@leviyuan/lodestar 0.16.0 → 0.16.1

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 +163 -161
  2. package/package.json +1 -1
package/dist/lodestar.js CHANGED
@@ -1,40 +1,40 @@
1
1
  #!/usr/bin/env node
2
- var bV=Object.defineProperty;var SV=($)=>$;function wV($,Z){this[$]=SV.bind(null,Z)}var F1=($,Z)=>{for(var J in Z)bV($,J,{get:Z[J],enumerable:!0,configurable:!0,set:wV.bind(Z,J)})};var E=($,Z)=>()=>($&&(Z=$($=0)),Z);import{homedir as fV}from"node:os";import{join as I}from"node:path";function I5($,Z,J){if($)return $;if(Z)return I(Z,"lodestar");return J}function vV(){if(g5)return I(process.env.APPDATA??I(a2,"AppData","Roaming"),"Lodestar");return I(a2,".config","lodestar")}function hV(){if(g5)return I(process.env.LOCALAPPDATA??I(a2,"AppData","Local"),"Lodestar");return I(a2,".local","share","lodestar")}var a2,g5,H6,i,L$,k$,A1,V6,X6,W6,z6,G6,r2,t2,s2,e2,c5,m5,$4,K6,v0,Z4;var D$=E(()=>{a2=fV(),g5=process.platform==="win32";H6=I5(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,vV()),i=I5(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,hV()),L$=process.env.LODESTAR_CONFIG??I(H6,"config.toml"),k$=I(i,"daemon.pid"),A1=I(i,"daemon.log"),V6=I(i,"session-chat-map.json"),X6=I(i,"session-resume-map.json"),W6=I(i,"session-turns-map.json"),z6=I(i,"session-model-map.json"),G6=I(i,"temp-session-leases.json"),r2=I(i,"tasklist-map.json"),t2=I(i,"consult-identities.json"),s2=I(i,"consult-runs"),e2=I(i,"managed-claude-plugin"),c5=I(i,"context-window-cache.json"),m5=I(i,"notify-callbacks.json"),$4=I(i,"alive-on-shutdown.json"),K6=I(i,"inbox"),v0=I(i,"debug.sock"),Z4=I(i,"debug-context.json")});import{execSync as u5}from"node:child_process";import{readFileSync as p5,writeFileSync as gV}from"node:fs";function IV(){return process.argv[1]??`pid:${process.pid}`}function cV($){try{if(process.platform==="linux")return p5(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return u5(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return u5(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function mV($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=cV($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function J4($){let Z="";try{Z=p5($,"utf8")}catch{return{state:"continue"}}let J=Z.split(`
3
- `),Q=parseInt((J[0]??"").trim(),10),Y=(J[1]??"").trim();if(!Number.isFinite(Q)||Q<=0)return{state:"continue"};if(!Y)try{return process.kill(Q,0),{state:"exit",pid:Q}}catch{return{state:"continue"}}if(mV(Q,Y))return{state:"exit",pid:Q};return{state:"continue"}}function l5($){gV($,`${process.pid}
4
- ${IV()}`)}var _6=()=>{};import{chmodSync as uV,closeSync as q6,fsyncSync as i5,mkdirSync as pV,openSync as d5,renameSync as lV,unlinkSync as iV,writeFileSync as dV}from"node:fs";import{randomUUID as nV}from"node:crypto";import{dirname as n5}from"node:path";function tV($){let Z=n5($);pV(Z,{recursive:!0,mode:rV})}function o5($,Z,J){tV($);let Q=`${$}.${process.pid}.${nV()}.tmp`,Y=null;try{Y=d5(Q,"wx",J),dV(Y,Z),i5(Y),q6(Y),Y=null,lV(Q,$);try{uV($,J)}catch{}if(process.platform!=="win32"){let H=null;try{H=d5(n5($),"r"),i5(H)}catch{}finally{if(H!==null)try{q6(H)}catch{}}}}catch(H){if(Y!==null)try{q6(Y)}catch{}try{iV(Q)}catch{}throw H}}function J0($,Z){o5($,Z,oV)}function a5($,Z){o5($,Z,aV)}function V$($,Z){J0($,JSON.stringify(Z,null,2)+`
5
- `)}var oV=384,aV=448,rV=448;var h$=()=>{};var e5={};F1(e5,{runSetup:()=>qX});import{execSync as sV,spawn as M1}from"node:child_process";import{existsSync as H4,mkdirSync as s5,readFileSync as eV}from"node:fs";import{createInterface as $X}from"node:readline/promises";import{delimiter as ZX,dirname as JX,join as V4}from"node:path";import{homedir as QX}from"node:os";import{fileURLToPath as YX}from"node:url";async function h0($,Z={}){while(!0){let J=Z.default?`${q.dim} [${Z.default}]${q.reset}`:"",Q=(await U1.question(`${q.cyan}? ${q.reset}${$}${J}
6
- ${q.green}>${q.reset} `)).trim();if(!Q&&Z.default!==void 0)return Z.default;if(!Q&&Z.required){console.log(`${q.red}必填,请重新输入${q.reset}`);continue}return Q}}function HX($){let Z="═".repeat(58);console.log(`
2
+ var fX=Object.defineProperty;var vX=($)=>$;function hX($,Z){this[$]=vX.bind(null,Z)}var F1=($,Z)=>{for(var J in Z)fX($,J,{get:Z[J],enumerable:!0,configurable:!0,set:hX.bind(Z,J)})};var k=($,Z)=>()=>($&&(Z=$($=0)),Z);import{homedir as IX}from"node:os";import{join as g}from"node:path";function c3($,Z,J){if($)return $;if(Z)return g(Z,"lodestar");return J}function gX(){if(g3)return g(process.env.APPDATA??g(a2,"AppData","Roaming"),"Lodestar");return g(a2,".config","lodestar")}function cX(){if(g3)return g(process.env.LOCALAPPDATA??g(a2,"AppData","Local"),"Lodestar");return g(a2,".local","share","lodestar")}var a2,g3,X8,d,L$,E$,P1,V8,W8,G8,z8,K8,r2,t2,s2,e2,m3,u3,$4,_8,f0,Z4;var D$=k(()=>{a2=IX(),g3=process.platform==="win32";X8=c3(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,gX()),d=c3(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,cX()),L$=process.env.LODESTAR_CONFIG??g(X8,"config.toml"),E$=g(d,"daemon.pid"),P1=g(d,"daemon.log"),V8=g(d,"session-chat-map.json"),W8=g(d,"session-resume-map.json"),G8=g(d,"session-turns-map.json"),z8=g(d,"session-model-map.json"),K8=g(d,"temp-session-leases.json"),r2=g(d,"tasklist-map.json"),t2=g(d,"consult-identities.json"),s2=g(d,"consult-runs"),e2=g(d,"managed-claude-plugin"),m3=g(d,"context-window-cache.json"),u3=g(d,"notify-callbacks.json"),$4=g(d,"alive-on-shutdown.json"),_8=g(d,"inbox"),f0=g(d,"debug.sock"),Z4=g(d,"debug-context.json")});import{execSync as p3}from"node:child_process";import{readFileSync as l3,writeFileSync as mX}from"node:fs";function uX(){return process.argv[1]??`pid:${process.pid}`}function pX($){try{if(process.platform==="linux")return l3(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return p3(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return p3(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function lX($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=pX($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function J4($){let Z="";try{Z=l3($,"utf8")}catch{return{state:"continue"}}let J=Z.split(`
3
+ `),Q=parseInt((J[0]??"").trim(),10),Y=(J[1]??"").trim();if(!Number.isFinite(Q)||Q<=0)return{state:"continue"};if(!Y)try{return process.kill(Q,0),{state:"exit",pid:Q}}catch{return{state:"continue"}}if(lX(Q,Y))return{state:"exit",pid:Q};return{state:"continue"}}function d3($){mX($,`${process.pid}
4
+ ${uX()}`)}var q8=()=>{};import{chmodSync as dX,closeSync as B8,fsyncSync as i3,mkdirSync as iX,openSync as n3,renameSync as nX,unlinkSync as oX,writeFileSync as aX}from"node:fs";import{randomUUID as rX}from"node:crypto";import{dirname as o3}from"node:path";function $V($){let Z=o3($);iX(Z,{recursive:!0,mode:eX})}function a3($,Z,J){$V($);let Q=`${$}.${process.pid}.${rX()}.tmp`,Y=null;try{Y=n3(Q,"wx",J),aX(Y,Z),i3(Y),B8(Y),Y=null,nX(Q,$);try{dX($,J)}catch{}if(process.platform!=="win32"){let H=null;try{H=n3(o3($),"r"),i3(H)}catch{}finally{if(H!==null)try{B8(H)}catch{}}}}catch(H){if(Y!==null)try{B8(Y)}catch{}try{oX(Q)}catch{}throw H}}function J0($,Z){a3($,Z,tX)}function r3($,Z){a3($,Z,sX)}function X$($,Z){J0($,JSON.stringify(Z,null,2)+`
5
+ `)}var tX=384,sX=448,eX=448;var h$=()=>{};var $5={};F1($5,{runSetup:()=>LV});import{execSync as ZV,spawn as M1}from"node:child_process";import{existsSync as H4,mkdirSync as e3,readFileSync as JV}from"node:fs";import{createInterface as QV}from"node:readline/promises";import{delimiter as YV,dirname as HV,join as X4}from"node:path";import{homedir as XV}from"node:os";import{fileURLToPath as VV}from"node:url";async function v0($,Z={}){while(!0){let J=Z.default?`${q.dim} [${Z.default}]${q.reset}`:"",Q=(await U1.question(`${q.cyan}? ${q.reset}${$}${J}
6
+ ${q.green}>${q.reset} `)).trim();if(!Q&&Z.default!==void 0)return Z.default;if(!Q&&Z.required){console.log(`${q.red}必填,请重新输入${q.reset}`);continue}return Q}}function WV($){let Z="═".repeat(58);console.log(`
7
7
  ${q.bold}${q.cyan}╔${Z}╗${q.reset}`),console.log(`${q.bold}${q.cyan}║ ${$.padEnd(54)} ║${q.reset}`),console.log(`${q.bold}${q.cyan}╚${Z}╝${q.reset}
8
8
  `)}function Q4($,Z,J){console.log(`
9
9
  ${q.bold}${q.yellow}[${$}/${Z}] ${J}${q.reset}
10
- `)}function j6($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function Y4($){let Z=process.env.PATH??"";if(!Z)return null;let J=process.platform==="win32"?[`${$}.cmd`,`${$}.bat`,`${$}.exe`,$]:[$];for(let Q of Z.split(ZX)){if(!Q)continue;for(let Y of J){let H=V4(Q,Y);if(H4(H))return H}}return null}function r5($){let Z=process.platform==="win32"?"npm.cmd":"npm";return new Promise((J)=>{let Q=M1(Z,["install","-g",`${$}@latest`],{stdio:"inherit",shell:process.platform==="win32"});Q.on("exit",(Y)=>J(Y===0)),Q.on("error",()=>J(!1))})}function t5($){try{let Z=sV(`"${$}" login status 2>&1`,{timeout:1e4}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function VX($){return new Promise((Z)=>{let J=M1($,["login"],{stdio:"inherit",shell:process.platform==="win32"});J.on("exit",(Q)=>Z(Q===0)),J.on("error",()=>Z(!1))})}function XX(){return process.env.CLAUDE_CONFIG_DIR||V4(QX(),".claude")}async function WX($){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(),Q=(Array.isArray(J?.data)?J.data:[]).map((_)=>typeof _?.display_name==="string"&&_.display_name?_.display_name:String(_?.id??"")).filter(Boolean);if(!Q.length)return null;let Y=(_)=>{let j=_.match(/(\d+(?:\.\d+)?)/);return j?Number(j[1]):-1},H=(_)=>_.replace(/-Turbo|-Air$/i,""),X=[...Q.filter((_)=>!/-Turbo|-Air/i.test(_))].sort((_,j)=>Y(j)-Y(_)),W=X[0],z=X[X.length-1],K={};if(W)K.ANTHROPIC_DEFAULT_OPUS_MODEL=`${W}[1m]`,K.ANTHROPIC_DEFAULT_SONNET_MODEL=`${W}[1m]`;if(z&&H(z)!==H(W))K.ANTHROPIC_DEFAULT_HAIKU_MODEL=z;return Object.keys(K).length?K:null}catch{return null}}async function zX($){try{let Z=XX();s5(Z,{recursive:!0});let J=V4(Z,"settings.json"),Q={};if(H4(J)){let X=eV(J,"utf8");try{let W=JSON.parse(X);if(!W||typeof W!=="object"||Array.isArray(W))return{error:`${J} 内容不是 JSON 对象, 拒绝覆盖, 请手动检查`};Q=W}catch{return{error:`${J} 解析失败 (JSON 语法错), 拒绝覆盖, 请手动修复后重跑`}}}let Y=Q.env&&typeof Q.env==="object"&&!Array.isArray(Q.env)?Q.env:{},H={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"},V=await WX($);if(V)Object.assign(H,V);return Q.env={...Y,...H},J0(J,JSON.stringify(Q,null,2)+`
11
- `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function GX($){try{if(process.platform==="win32")M1(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")M1("open",[$],{detached:!0,stdio:"ignore"}).unref();else M1("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function KX($,Z){try{let Q=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(Q.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书拒绝: code=${Q.code} msg=${Q.msg??"(no msg)"}`}}catch(J){return{ok:!1,error:`网络错误: ${J?.message??String(J)}`}}}function _X(){try{let $=JX(YX(import.meta.url)),Z=V4($,"lodestar.js");if(!H4(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=M1(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function qX(){if(!process.stdin.isTTY)console.error(`${q.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${q.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(H4(L$)){if(console.log(`${q.yellow}发现已有配置: ${L$}${q.reset}`),(await h0("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),U1.close();return}}HX("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log(`${q.yellow}⚠ Claude 官方限制:${q.reset}`),console.log(` ${q.bold}Claude 订阅 (Pro/Max OAuth 登录) 不支持本项目${q.reset},`),console.log(" 必须走 API 方式 —— 推荐 GLM Coding Plan, 或自备 Anthropic API key。"),console.log(),console.log("本向导依次做 4 件事:"),console.log(` ${q.dim}1) 确保 Claude Code CLI 已装好${q.reset}`),console.log(` ${q.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${q.reset}`),console.log(` ${q.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${q.reset}`),console.log(` ${q.dim}4) 工作目录, 自动启动 daemon${q.reset}`),console.log(),await U1.question(`${q.dim}按 Enter 开始 (Ctrl+C 退出)...${q.reset}`),Q4(1,4,"准备 Claude Code CLI");let $=Y4("claude");if($)console.log(`${q.green}✓ claude CLI 已就位${q.reset}: ${q.dim}${$}${q.reset}`);else{if(console.log(`${q.yellow}未在 PATH 找到 claude CLI, 自动安装...${q.reset}`),console.log(`${q.dim}运行: npm install -g @anthropic-ai/claude-code@latest${q.reset}`),console.log(),!await r5("@anthropic-ai/claude-code"))console.error(`
12
- ${q.red}安装失败。${q.reset}`),console.error("请手动运行后再开向导:"),console.error(` ${q.cyan}npm install -g @anthropic-ai/claude-code@latest${q.reset}`),console.error(` ${q.cyan}lodestar-setup${q.reset}`),U1.close(),process.exit(1);$=Y4("claude"),console.log(`${q.green}✓ 安装完成${q.reset}: ${q.dim}${$??"(应该装好了, 但 PATH 找不到 — 重开终端再试)"}${q.reset}`)}console.log(),console.log(`${q.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${q.reset}`),console.log(`${q.dim}记住: 别用 \`claude\` 走订阅 OAuth 登录 —— 订阅不支持本项目, 要用 API key。${q.reset}`),Q4(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${q.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${q.reset}`),console.log(` ${q.dim}不给也行: 以本机 Claude Code 现有配置启动 (确保是 API key 方式, 非订阅)。${q.reset}`),console.log();let Z=await h0("GLM API key (直接回车跳过)",{});if(Z){let j=await zX(Z);if("path"in j)console.log(`${q.green}✓ GLM 路由已写入${q.reset}: ${q.dim}${j.path}${q.reset}`),console.log(`${q.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${q.reset}`);else console.log(`${q.red}✗ 写入失败:${q.reset} ${j.error}`),console.log(`${q.dim}跳过 GLM 配置, 以本机 Claude Code 现有配置启动。${q.reset}`)}else console.log(`${q.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${q.reset}`);if(console.log(),console.log(`${q.bold}Codex (可选第二后端)${q.reset}`),console.log(` ${q.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${q.reset}`),(await h0("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){let j=Y4("codex");if(!j){if(console.log(`${q.dim}未找到 codex CLI, 安装 @openai/codex...${q.reset}`),await r5("@openai/codex"))j=Y4("codex")}if(j&&t5(j))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else if(j)if(console.log(`${q.dim}启动 \`codex login\`...${q.reset}`),await VX(j)&&t5(j))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else console.log(`${q.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${q.reset}`);else console.log(`${q.yellow}Codex 安装失败 — 不影响默认 Claude 后端; 需要时手动 npm i -g @openai/codex。${q.reset}`)}else console.log(`${q.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${q.reset}`);Q4(3,4,"Feishu 自建应用");let Q="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${q.cyan}${Q}${q.reset}`),GX(Q),console.log(`${q.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${q.reset}`),console.log(),console.log(`${q.bold}详细操作步骤:${q.reset}`),console.log(),console.log(` ${q.bold}① 创建应用${q.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${q.dim}Lodestar${q.reset}), logo 随意。`),console.log(),console.log(` ${q.bold}② 添加机器人能力${q.reset}`),console.log(` 左侧菜单 "${q.cyan}添加应用能力${q.reset}" → 找到 "机器人" → 点 "${q.bold}添加${q.reset}" 按钮。`),console.log(),console.log(` ${q.bold}③ 申请权限 (左侧 "${q.cyan}权限管理${q.reset}" → "${q.bold}开通权限${q.reset}")${q.reset}`),console.log(` ${q.yellow}缺一个都会让 daemon 启动后默默丢消息, 一定要全开。${q.reset}`),console.log(` ${q.dim}消息类:${q.reset}`),console.log(` • ${q.bold}im:message:send_as_bot${q.reset} ${q.dim}# 以机器人身份发消息${q.reset}`),console.log(` • ${q.bold}im:message${q.reset} ${q.dim}# 接收/操作消息 (核心)${q.reset}`),console.log(` • ${q.bold}im:chat${q.reset} ${q.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${q.reset}`),console.log(` • ${q.bold}im:chat:create${q.reset} ${q.dim}# wt: 自动创建 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat:delete${q.reset} ${q.dim}# wt: 解散 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat.members:read${q.reset} ${q.dim}# wt: 判断发起人是否已在群内${q.reset}`),console.log(` • ${q.bold}im:chat.members:write_only${q.reset} ${q.dim}# wt: 把发起人拉进已有 worktree 群${q.reset}`),console.log(` • ${q.bold}im:resource${q.reset} ${q.dim}# 上传/下载附件 (图文双向)${q.reset}`),console.log(` • ${q.bold}im:message.urgent${q.reset} ${q.dim}# 加急推送 (锁屏通知 / Ask)${q.reset}`),console.log(` • ${q.bold}im:message.group_msg${q.reset} ${q.dim}# 敏感: 接收群里所有消息${q.reset}`),console.log(` ${q.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${q.reset}`),console.log(` ${q.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${q.reset}`),console.log(` • ${q.bold}im:message.group_at_msg:readonly${q.reset} ${q.dim}# 读 @ 机器人消息 (兜底)${q.reset}`),console.log(` ${q.dim}卡片类 (Card Kit):${q.reset}`),console.log(` • ${q.bold}cardkit:card:read${q.reset} ${q.dim}# 读卡片状态${q.reset}`),console.log(` • ${q.bold}cardkit:card:write${q.reset} ${q.dim}# 创建/更新卡片 (流式渲染核心)${q.reset}`),console.log(),console.log(` ${q.bold}④ 订阅事件 (左侧 "${q.cyan}事件与回调${q.reset}", 拆两个子页:)${q.reset}`),console.log(` ${q.dim}a)${q.reset} ${q.bold}事件配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}im.message.receive_v1${q.reset} ${q.dim}# 收群消息${q.reset}`),console.log(` ${q.dim}b)${q.reset} ${q.bold}回调配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}card.action.trigger${q.reset} ${q.dim}# 卡片按钮点击回调${q.reset}`),console.log(),console.log(` ${q.bold}⑤ 发布版本${q.reset}`),console.log(` 页面顶部 "${q.bold}创建版本${q.reset}" → 滚到底点 "${q.bold}保存${q.reset}" → 弹框点 "${q.bold}发布${q.reset}"。`),console.log(` ${q.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${q.reset}`),console.log(),console.log(` ${q.bold}⑥ 拿凭据${q.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${q.bold}App ID${q.reset} (${q.dim}cli_...${q.reset}) 和 ${q.bold}App Secret${q.reset}, 待会粘到下面。`),console.log(),console.log(` ${q.bold}⑦ 把机器人拉进群${q.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${q.yellow}群名要等于 projects_root 下的项目目录名${q.reset} (下一步设, 默认是用户主目录)。`),console.log();let Y="",H="";while(!0){Y=await h0("App ID (以 cli_ 开头)",{required:!0}),H=await h0("App Secret",{required:!0}),console.log(`${q.dim}测试中... (调 tenant_access_token endpoint)${q.reset}`);let j=await KX(Y,H);if(j.ok){console.log(`${q.green}✓ Feishu 凭据测试通过${q.reset}`);break}if(console.log(`${q.red}✗ 测试失败:${q.reset} ${j.error}`),console.log(`${q.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${q.reset}`),console.log(),(await h0("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${q.yellow}已取消, 配置未写盘。${q.reset}`),U1.close(),process.exit(1)}Q4(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let V=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",X=await h0("projects_root",{default:V});s5(H6,{recursive:!0});let W=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${j6(Y)}"`,`app_secret = "${j6(H)}"`,"","[runtime]",`projects_root = "${j6(X)}"`,""];J0(L$,W.join(`
10
+ `)}function j8($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function Y4($){let Z=process.env.PATH??"";if(!Z)return null;let J=process.platform==="win32"?[`${$}.cmd`,`${$}.bat`,`${$}.exe`,$]:[$];for(let Q of Z.split(YV)){if(!Q)continue;for(let Y of J){let H=X4(Q,Y);if(H4(H))return H}}return null}function t3($){let Z=process.platform==="win32"?"npm.cmd":"npm";return new Promise((J)=>{let Q=M1(Z,["install","-g",`${$}@latest`],{stdio:"inherit",shell:process.platform==="win32"});Q.on("exit",(Y)=>J(Y===0)),Q.on("error",()=>J(!1))})}function s3($){try{let Z=ZV(`"${$}" login status 2>&1`,{timeout:1e4}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function GV($){return new Promise((Z)=>{let J=M1($,["login"],{stdio:"inherit",shell:process.platform==="win32"});J.on("exit",(Q)=>Z(Q===0)),J.on("error",()=>Z(!1))})}function zV(){return process.env.CLAUDE_CONFIG_DIR||X4(XV(),".claude")}async function KV($){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(),Q=(Array.isArray(J?.data)?J.data:[]).map((_)=>typeof _?.display_name==="string"&&_.display_name?_.display_name:String(_?.id??"")).filter(Boolean);if(!Q.length)return null;let Y=(_)=>{let B=_.match(/(\d+(?:\.\d+)?)/);return B?Number(B[1]):-1},H=(_)=>_.replace(/-Turbo|-Air$/i,""),V=[...Q.filter((_)=>!/-Turbo|-Air/i.test(_))].sort((_,B)=>Y(B)-Y(_)),W=V[0],G=V[V.length-1],K={};if(W)K.ANTHROPIC_DEFAULT_OPUS_MODEL=`${W}[1m]`,K.ANTHROPIC_DEFAULT_SONNET_MODEL=`${W}[1m]`;if(G&&H(G)!==H(W))K.ANTHROPIC_DEFAULT_HAIKU_MODEL=G;return Object.keys(K).length?K:null}catch{return null}}async function _V($){try{let Z=zV();e3(Z,{recursive:!0});let J=X4(Z,"settings.json"),Q={};if(H4(J)){let V=JV(J,"utf8");try{let W=JSON.parse(V);if(!W||typeof W!=="object"||Array.isArray(W))return{error:`${J} 内容不是 JSON 对象, 拒绝覆盖, 请手动检查`};Q=W}catch{return{error:`${J} 解析失败 (JSON 语法错), 拒绝覆盖, 请手动修复后重跑`}}}let Y=Q.env&&typeof Q.env==="object"&&!Array.isArray(Q.env)?Q.env:{},H={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"},X=await KV($);if(X)Object.assign(H,X);return Q.env={...Y,...H},J0(J,JSON.stringify(Q,null,2)+`
11
+ `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function qV($){try{if(process.platform==="win32")M1(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")M1("open",[$],{detached:!0,stdio:"ignore"}).unref();else M1("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function BV($,Z){try{let Q=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(Q.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书拒绝: code=${Q.code} msg=${Q.msg??"(no msg)"}`}}catch(J){return{ok:!1,error:`网络错误: ${J?.message??String(J)}`}}}function jV(){try{let $=HV(VV(import.meta.url)),Z=X4($,"lodestar.js");if(!H4(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=M1(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function LV(){if(!process.stdin.isTTY)console.error(`${q.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${q.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(H4(L$)){if(console.log(`${q.yellow}发现已有配置: ${L$}${q.reset}`),(await v0("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),U1.close();return}}WV("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log(`${q.yellow}⚠ Claude 官方限制:${q.reset}`),console.log(` ${q.bold}Claude 订阅 (Pro/Max OAuth 登录) 不支持本项目${q.reset},`),console.log(" 必须走 API 方式 —— 推荐 GLM Coding Plan, 或自备 Anthropic API key。"),console.log(),console.log("本向导依次做 4 件事:"),console.log(` ${q.dim}1) 确保 Claude Code CLI 已装好${q.reset}`),console.log(` ${q.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${q.reset}`),console.log(` ${q.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${q.reset}`),console.log(` ${q.dim}4) 工作目录, 自动启动 daemon${q.reset}`),console.log(),await U1.question(`${q.dim}按 Enter 开始 (Ctrl+C 退出)...${q.reset}`),Q4(1,4,"准备 Claude Code CLI");let $=Y4("claude");if($)console.log(`${q.green}✓ claude CLI 已就位${q.reset}: ${q.dim}${$}${q.reset}`);else{if(console.log(`${q.yellow}未在 PATH 找到 claude CLI, 自动安装...${q.reset}`),console.log(`${q.dim}运行: npm install -g @anthropic-ai/claude-code@latest${q.reset}`),console.log(),!await t3("@anthropic-ai/claude-code"))console.error(`
12
+ ${q.red}安装失败。${q.reset}`),console.error("请手动运行后再开向导:"),console.error(` ${q.cyan}npm install -g @anthropic-ai/claude-code@latest${q.reset}`),console.error(` ${q.cyan}lodestar-setup${q.reset}`),U1.close(),process.exit(1);$=Y4("claude"),console.log(`${q.green}✓ 安装完成${q.reset}: ${q.dim}${$??"(应该装好了, 但 PATH 找不到 — 重开终端再试)"}${q.reset}`)}console.log(),console.log(`${q.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${q.reset}`),console.log(`${q.dim}记住: 别用 \`claude\` 走订阅 OAuth 登录 —— 订阅不支持本项目, 要用 API key。${q.reset}`),Q4(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${q.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${q.reset}`),console.log(` ${q.dim}不给也行: 以本机 Claude Code 现有配置启动 (确保是 API key 方式, 非订阅)。${q.reset}`),console.log();let Z=await v0("GLM API key (直接回车跳过)",{});if(Z){let B=await _V(Z);if("path"in B)console.log(`${q.green}✓ GLM 路由已写入${q.reset}: ${q.dim}${B.path}${q.reset}`),console.log(`${q.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${q.reset}`);else console.log(`${q.red}✗ 写入失败:${q.reset} ${B.error}`),console.log(`${q.dim}跳过 GLM 配置, 以本机 Claude Code 现有配置启动。${q.reset}`)}else console.log(`${q.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${q.reset}`);if(console.log(),console.log(`${q.bold}Codex (可选第二后端)${q.reset}`),console.log(` ${q.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${q.reset}`),(await v0("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){let B=Y4("codex");if(!B){if(console.log(`${q.dim}未找到 codex CLI, 安装 @openai/codex...${q.reset}`),await t3("@openai/codex"))B=Y4("codex")}if(B&&s3(B))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else if(B)if(console.log(`${q.dim}启动 \`codex login\`...${q.reset}`),await GV(B)&&s3(B))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else console.log(`${q.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${q.reset}`);else console.log(`${q.yellow}Codex 安装失败 — 不影响默认 Claude 后端; 需要时手动 npm i -g @openai/codex。${q.reset}`)}else console.log(`${q.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${q.reset}`);Q4(3,4,"Feishu 自建应用");let Q="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${q.cyan}${Q}${q.reset}`),qV(Q),console.log(`${q.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${q.reset}`),console.log(),console.log(`${q.bold}详细操作步骤:${q.reset}`),console.log(),console.log(` ${q.bold}① 创建应用${q.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${q.dim}Lodestar${q.reset}), logo 随意。`),console.log(),console.log(` ${q.bold}② 添加机器人能力${q.reset}`),console.log(` 左侧菜单 "${q.cyan}添加应用能力${q.reset}" → 找到 "机器人" → 点 "${q.bold}添加${q.reset}" 按钮。`),console.log(),console.log(` ${q.bold}③ 申请权限 (左侧 "${q.cyan}权限管理${q.reset}" → "${q.bold}开通权限${q.reset}")${q.reset}`),console.log(` ${q.yellow}缺一个都会让 daemon 启动后默默丢消息, 一定要全开。${q.reset}`),console.log(` ${q.dim}消息类:${q.reset}`),console.log(` • ${q.bold}im:message:send_as_bot${q.reset} ${q.dim}# 以机器人身份发消息${q.reset}`),console.log(` • ${q.bold}im:message${q.reset} ${q.dim}# 接收/操作消息 (核心)${q.reset}`),console.log(` • ${q.bold}im:chat${q.reset} ${q.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${q.reset}`),console.log(` • ${q.bold}im:chat:create${q.reset} ${q.dim}# wt: 自动创建 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat:delete${q.reset} ${q.dim}# wt: 解散 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat.members:read${q.reset} ${q.dim}# wt: 判断发起人是否已在群内${q.reset}`),console.log(` • ${q.bold}im:chat.members:write_only${q.reset} ${q.dim}# wt: 把发起人拉进已有 worktree 群${q.reset}`),console.log(` • ${q.bold}im:resource${q.reset} ${q.dim}# 上传/下载附件 (图文双向)${q.reset}`),console.log(` • ${q.bold}im:message.urgent${q.reset} ${q.dim}# 加急推送 (锁屏通知 / Ask)${q.reset}`),console.log(` • ${q.bold}im:message.group_msg${q.reset} ${q.dim}# 敏感: 接收群里所有消息${q.reset}`),console.log(` ${q.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${q.reset}`),console.log(` ${q.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${q.reset}`),console.log(` • ${q.bold}im:message.group_at_msg:readonly${q.reset} ${q.dim}# 读 @ 机器人消息 (兜底)${q.reset}`),console.log(` ${q.dim}卡片类 (Card Kit):${q.reset}`),console.log(` • ${q.bold}cardkit:card:read${q.reset} ${q.dim}# 读卡片状态${q.reset}`),console.log(` • ${q.bold}cardkit:card:write${q.reset} ${q.dim}# 创建/更新卡片 (流式渲染核心)${q.reset}`),console.log(),console.log(` ${q.bold}④ 订阅事件 (左侧 "${q.cyan}事件与回调${q.reset}", 拆两个子页:)${q.reset}`),console.log(` ${q.dim}a)${q.reset} ${q.bold}事件配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}im.message.receive_v1${q.reset} ${q.dim}# 收群消息${q.reset}`),console.log(` ${q.dim}b)${q.reset} ${q.bold}回调配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}card.action.trigger${q.reset} ${q.dim}# 卡片按钮点击回调${q.reset}`),console.log(),console.log(` ${q.bold}⑤ 发布版本${q.reset}`),console.log(` 页面顶部 "${q.bold}创建版本${q.reset}" → 滚到底点 "${q.bold}保存${q.reset}" → 弹框点 "${q.bold}发布${q.reset}"。`),console.log(` ${q.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${q.reset}`),console.log(),console.log(` ${q.bold}⑥ 拿凭据${q.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${q.bold}App ID${q.reset} (${q.dim}cli_...${q.reset}) 和 ${q.bold}App Secret${q.reset}, 待会粘到下面。`),console.log(),console.log(` ${q.bold}⑦ 把机器人拉进群${q.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${q.yellow}群名要等于 projects_root 下的项目目录名${q.reset} (下一步设, 默认是用户主目录)。`),console.log();let Y="",H="";while(!0){Y=await v0("App ID (以 cli_ 开头)",{required:!0}),H=await v0("App Secret",{required:!0}),console.log(`${q.dim}测试中... (调 tenant_access_token endpoint)${q.reset}`);let B=await BV(Y,H);if(B.ok){console.log(`${q.green}✓ Feishu 凭据测试通过${q.reset}`);break}if(console.log(`${q.red}✗ 测试失败:${q.reset} ${B.error}`),console.log(`${q.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${q.reset}`),console.log(),(await v0("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${q.yellow}已取消, 配置未写盘。${q.reset}`),U1.close(),process.exit(1)}Q4(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let X=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",V=await v0("projects_root",{default:X});e3(X8,{recursive:!0});let W=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${j8(Y)}"`,`app_secret = "${j8(H)}"`,"","[runtime]",`projects_root = "${j8(V)}"`,""];J0(L$,W.join(`
13
13
  `)),console.log(`
14
14
  ${q.green}${q.bold}✓ 配置已写入${q.reset}`),console.log(` ${q.cyan}${L$}${q.reset}`),console.log(`
15
- ${q.bold}启动 daemon...${q.reset}`);let z=_X(),K=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(`${q.green}✓ daemon 已在后台启动${q.reset} (pid ${z.pid})`),console.log(),console.log(`${q.bold}最后一步: 在 Feishu 验证${q.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${q.cyan}${X}${K}<群名>${q.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${q.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${q.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${q.cyan}${_}${q.reset}`),console.log(),console.log(`${q.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${q.reset}`);else console.log(`${q.yellow}启动失败: ${z.error}${q.reset}`),console.log(`手动运行: ${q.cyan}lodestar-daemon${q.reset}`);console.log(),U1.close()}var q,U1;var $3=E(()=>{D$();h$();q={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},U1=$X({input:process.stdin,output:process.stdout})});import{readFileSync as jX}from"node:fs";import{homedir as J3}from"node:os";function Z3($){return $.replace(/^~(?=\/|$)/,J3())}function BX($){let Z={_:{}},J="_";for(let Q of $.split(`
16
- `)){let Y=LX(Q).trim();if(!Y)continue;let H=Y.match(/^\[([^\]]+)\]$/);if(H){J=H[1].trim(),Z[J]??={};continue}let V=Y.match(/^([\w.-]+)\s*=\s*(.+)$/);if(V){let X=V[2].trim(),W=X.startsWith('"')&&X.endsWith('"'),z=X.startsWith("'")&&X.endsWith("'");if(W||z){if(X=X.slice(1,-1),W)X=X.replace(/\\([\\"])/g,"$1")}Z[J][V[1]]=X}}return Z}function LX($){let Z=null,J=!1;for(let Q=0;Q<$.length;Q++){let Y=$[Q];if(Z==="double"){if(J){J=!1;continue}if(Y==="\\"){J=!0;continue}if(Y==='"')Z=null;continue}if(Z==="single"){if(Y==="'")Z=null;continue}if(Y==='"')Z="double";else if(Y==="'")Z="single";else if(Y==="#")return $.slice(0,Q)}return $}function Q3(){let $;try{$=jX(L$,"utf8")}catch(R){throw process.stderr.write(`lodestar: cannot read config at ${L$}
15
+ ${q.bold}启动 daemon...${q.reset}`);let G=jV(),K=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(G.pid)console.log(`${q.green}✓ daemon 已在后台启动${q.reset} (pid ${G.pid})`),console.log(),console.log(`${q.bold}最后一步: 在 Feishu 验证${q.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${q.cyan}${V}${K}<群名>${q.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${q.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${q.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${q.cyan}${_}${q.reset}`),console.log(),console.log(`${q.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${q.reset}`);else console.log(`${q.yellow}启动失败: ${G.error}${q.reset}`),console.log(`手动运行: ${q.cyan}lodestar-daemon${q.reset}`);console.log(),U1.close()}var q,U1;var Z5=k(()=>{D$();h$();q={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},U1=QV({input:process.stdin,output:process.stdout})});import{readFileSync as DV}from"node:fs";import{homedir as Q5}from"node:os";function J5($){return $.replace(/^~(?=\/|$)/,Q5())}function AV($){let Z={_:{}},J="_";for(let Q of $.split(`
16
+ `)){let Y=FV(Q).trim();if(!Y)continue;let H=Y.match(/^\[([^\]]+)\]$/);if(H){J=H[1].trim(),Z[J]??={};continue}let X=Y.match(/^([\w.-]+)\s*=\s*(.+)$/);if(X){let V=X[2].trim(),W=V.startsWith('"')&&V.endsWith('"'),G=V.startsWith("'")&&V.endsWith("'");if(W||G){if(V=V.slice(1,-1),W)V=V.replace(/\\([\\"])/g,"$1")}Z[J][X[1]]=V}}return Z}function FV($){let Z=null,J=!1;for(let Q=0;Q<$.length;Q++){let Y=$[Q];if(Z==="double"){if(J){J=!1;continue}if(Y==="\\"){J=!0;continue}if(Y==='"')Z=null;continue}if(Z==="single"){if(Y==="'")Z=null;continue}if(Y==='"')Z="double";else if(Y==="'")Z="single";else if(Y==="#")return $.slice(0,Q)}return $}function Y5(){let $;try{$=DV(L$,"utf8")}catch(R){throw process.stderr.write(`lodestar: cannot read config at ${L$}
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
- `),R}let Z=BX($),J=Z.feishu?.app_id,Q=Z.feishu?.app_secret;if(!J||!Q)throw Error(`lodestar: ${L$} is missing [feishu].app_id / [feishu].app_secret`);let Y=Z3(Z.runtime?.projects_root??J3()),H=(Z.runtime?.live_elapsed??"bucket").trim().toLowerCase();if(H!=="bucket"&&H!=="second")throw Error(`lodestar: [runtime].live_elapsed must be "bucket" or "second", got "${Z.runtime?.live_elapsed}"`);let V=H,X=Z.notify?.bind??"127.0.0.1",W=Z.notify?.port??"9876";if(!/^\d+$/.test(W.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${W}"`);let z=Number.parseInt(W,10);if(!Number.isFinite(z)||z<=0||z>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${W}"`);let K=(R)=>{let D=Z[R]??{},F={};for(let[y,C]of Object.entries(D))if(typeof C==="string"&&C.length>0)F[y]=C;return F},_=()=>{let R={};for(let[D,F]of Object.entries(Z)){if(!D.startsWith("claude.models."))continue;let C=D.slice(14).trim();if(!C)continue;let x={};for(let[m,g]of Object.entries(F)){if(typeof g!=="string"||g.length===0)continue;let f=m.trim();if(f==="display_name"||f==="description"||f==="model")x[f]=g}R[C]=x}return R},j=()=>{let R={},D="projects.";for(let[F,y]of Object.entries(Z)){if(!F.startsWith("projects."))continue;let C=F.slice(9).trim();if(!C)continue;let x={};for(let[m,g]of Object.entries(y)){if(typeof g!=="string"||g.length===0)continue;switch(m.trim()){case"cwd":x.cwd=g;break;case"setting_sources":x.settingSources=g;break;case"strict_mcp":x.strictMcp=g==="true";break;case"tools":x.tools=g;break;case"load_project_mcp":x.loadProjectMcp=g==="true";break}}R[C]=x}return R},B=()=>{let R={},D="token_source.";for(let[F,y]of Object.entries(Z)){if(!F.startsWith("token_source."))continue;let C=F.slice(13).trim();if(!C)continue;let x={};for(let[m,g]of Object.entries(y)){if(typeof g!=="string"||g.length===0)continue;let f=m.trim();if(f==="default")x.default=g==="true";else if(f==="agent"||f==="display"||f==="auth"||f==="base_url"||f==="auth_token"||f==="api_key"||f==="bin"||f==="model"||f==="effort"||f==="models"||f==="slots"||f==="usage")x[f]=g}R[C]=x}return R},L=K("codex.env"),P=K("claude.env"),A=Z.claude?.bin?Z3(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Q},runtime:{projects_root:Y,live_elapsed:V},notify:{bind:X,port:z},codex:{env:L},claude:{bin:A,env:P,models:_()},projects:j(),token_sources:B()}}function Y3(){S.token_sources=Q3().token_sources}var S;var y$=E(()=>{D$();S=Q3()});import{appendFileSync as X3,mkdirSync as DX,readdirSync as PX,unlinkSync as W3,existsSync as H3,statSync as FX,renameSync as AX,readFileSync as UX}from"node:fs";import{join as z3}from"node:path";function D6($="development"){return $!=="test"}function G3($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Q=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Q}`}function K3($,Z=i){return z3(Z,`${B6}${G3($)}${L6}`)}function RX($){if(!$.startsWith(B6)||!$.endsWith(L6))return null;let Z=$.slice(B6.length,$.length-L6.length),J=/^(\d{4})-(\d{2})-(\d{2})$/.exec(Z);if(!J)return null;let Q=new Date(Number(J[1]),Number(J[2])-1,Number(J[3]));return Number.isNaN(Q.getTime())?null:Q}function _3($,Z=new Date,J=MX){let Q;try{Q=PX($)}catch{return 0}let Y=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),H=0;for(let V of Q){let X=RX(V);if(!X)continue;if(Math.round((Y.getTime()-X.getTime())/86400000)<J)continue;try{W3(z3($,V)),H++}catch{}}return H}function OX($=new Date){try{if(!H3(A1))return;let Z=FX(A1);if(!Z.isFile()||Z.size===0)return;let J=K3(Z.mtime);if(H3(J)){X3(J,UX(A1)),W3(A1);return}AX(A1,J)}catch{}}function G($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
23
- `;if(process.stderr.write(J),!D6())return;try{let Q=G3(Z);if(V3!==Q)V3=Q,_3(i,Z);X3(K3(Z),J)}catch{}}var MX=7,B6="daemon-",L6=".log",V3=null;var w=E(()=>{D$();if(D6())try{DX(i,{recursive:!0})}catch{}if(D6()){try{OX()}catch{}try{_3(i)}catch{}}});function t($){return typeof $==="string"&&$?$:void 0}function v($){return $!=null&&typeof $==="object"?$:null}function Q0($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function X4($){if(!$)return"[]";let Z=Object.keys($),J=Z.slice(0,80),Q=Z.length>J.length?`,...+${Z.length-J.length}`:"";return`[${J.join(",")}${Q}]`}function kX($){let Z=$.slice(0,A6),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function yX($){let Z=v($);if(!Z)return null;let J=v(Z.event),Q=v(Z.payload);return v(Z.item)??v(Z.responseItem)??v(Z.rawItem)??v(J?.item)??v(J?.responseItem)??v(J?.rawItem)??v(Q?.item)??v(Q?.responseItem)??v(Q?.rawItem)??(H2(Z.type)?Z:null)??(J&&H2(J.type)?J:null)??(Q&&H2(Q.type)?Q:null)}function EX($){let Z=[],J=new WeakSet,Q=(Y,H,V)=>{if(Z.length>=A6||V>6)return;if(Array.isArray(Y)){if(H)Z.push(`${H}[]`);if(Y.length>0)Q(Y[0],H?`${H}[]`:"[]",V+1);return}if(Y==null||typeof Y!=="object")return;if(J.has(Y))return;J.add(Y);for(let X of Object.keys(Y)){if(Z.length>=A6)return;let W=H?`${H}.${X}`:X;Z.push(W),Q(Y[X],W,V+1)}};return Q($,"",0),Z}function U6($){let Z=new WeakSet,J;try{J=JSON.stringify($,(Q,Y)=>{if(typeof Y==="bigint")return`${Y.toString()}n`;if(typeof Y==="string"&&Y.length>F6)return`${Y.slice(0,F6)}...<truncated ${Y.length-F6} chars>`;if(Y!=null&&typeof Y==="object"){if(Z.has(Y))return"[Circular]";Z.add(Y)}return Y})??String($)}catch(Q){J=`<unserializable: ${Q}>`}if(J.length>P6)return`${J.slice(0,P6)}...<truncated ${J.length-P6} chars>`;return J}function M$($,Z){let J=v(Z),Q=J?v(J.params):null,Y=J?v(J.item)??v(Q?.item):null,H=J?t(J.method)??"-":"-";G([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${Q0(H)}`,`rootKeys=${X4(J)}`,`itemKeys=${X4(Y)}`,`payload=${U6(Z)}`].join(" "))}function M6($,Z,J){let Q=v(Z),Y=yX(Z),H=[`phase=${Q0(J.phase??"event")}`,`method=${Q0($)}`,`sourceMethod=${Q0(J.sourceMethod)}`,`sourceType=${Q0(J.sourceType)}`,`sessionId=${Q0(J.sessionId)}`,`threadId=${Q0(J.threadId)}`,`turnId=${Q0(J.turnId)}`,`itemId=${Q0(J.itemId)}`].join(" ");if(G(`codex-process: CONTEXT_COMPACTION_EVENT ${H} rootKeys=${X4(Q)} itemKeys=${X4(Y)}`),G(`codex-process: CONTEXT_COMPACTION_PATHS ${H} paths=${kX(EX(Z))}`),Y)G(`codex-process: CONTEXT_COMPACTION_ITEM ${H} item=${U6(Y)}`);G(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${H} payload=${U6(Z)}`)}function H2($){if(typeof $!=="string")return null;return TX.has($)?$:null}function xX($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||q3.has(Z))return"end";return"event"}function R6($,Z){return j3($,v(Z)??{})}function O6($){let Z=v($);if(!Z)return null;let J=t(Z.method)??t(Z.type)??"raw_message";return j3(J,Z)}function j3($,Z){let J=v(Z.payload),Q=[Z,v(Z.event),J,v(Z.item),v(Z.responseItem),v(Z.rawItem)].filter((W)=>W!=null),Y=null;for(let W of Q)if(Y=H2(W.type),Y)break;if(!q3.has($)&&!Y)return null;let H=v(Z.item)??v(Z.responseItem)??v(Z.rawItem),V=Y==="compacted"&&J?J:H&&H2(H.type)?H:Z,X=v(V.item)??v(V.responseItem)??v(V.rawItem)??H??{};return{...V,threadId:t(V.threadId)??t(V.thread_id)??t(Z.threadId)??t(Z.thread_id),turnId:t(V.turnId)??t(V.turn_id)??t(Z.turnId)??t(Z.turn_id),itemId:t(V.itemId)??t(V.item_id)??t(X.id)??t(X.itemId)??t(X.item_id),timestamp:t(Z.timestamp)??t(V.timestamp),recordType:t(Z.type),phase:xX(Y,$),sourceMethod:$,sourceType:Y??$}}var q3,TX,P6=200000,F6=50000,A6=400;var T6=E(()=>{w();q3=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),TX=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function V2($){return $!=null&&typeof $==="object"?$:null}function Y0($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function B3($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function W4($,Z){return $?Y0($[Z]):void 0}function R1($){let Z=V2($);if(!Z)return null;let J=V2(Z.inputTokensDetails)??V2(Z.input_tokens_details),Q=V2(Z.outputTokensDetails)??V2(Z.output_tokens_details),Y={total_tokens:Y0(Z.totalTokens??Z.total_tokens),input_tokens:Y0(Z.inputTokens??Z.input_tokens),output_tokens:Y0(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:Y0(Z.reasoningOutputTokens??Z.reasoning_output_tokens??W4(Q,"reasoningTokens")??W4(Q,"reasoning_tokens")),cache_creation_input_tokens:Y0(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:Y0(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??W4(J,"cachedTokens")??W4(J,"cached_tokens"))};return B3(Y)?Y:null}function k6($,Z){let J=(Y)=>{let H=Y0($?.[Y]),V=Y0(Z?.[Y]);if(H===void 0&&V===void 0)return;return Math.max(0,(H??0)-(V??0))},Q={total_tokens:J("total_tokens"),input_tokens:J("input_tokens"),output_tokens:J("output_tokens"),reasoning_output_tokens:J("reasoning_output_tokens"),cache_creation_input_tokens:J("cache_creation_input_tokens"),cache_read_input_tokens:J("cache_read_input_tokens")};return B3(Q)?Q:null}function y6($){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 L3($){let Z=$.trim();if(Z.length<2)return Z;let J=z4[Z[0]];if(!J||!Z.endsWith(J))return Z;let Q=Z.slice(1,-1);if(Z[0]==="'")return Q.replace(/''/g,"'");if(Z[0]==='"')return Q.replace(/\\"/g,'"');return Q}function x6($){let Z=CX(String($??"")),J=Z.split(`
22
+ `),R}let Z=AV($),J=Z.feishu?.app_id,Q=Z.feishu?.app_secret;if(!J||!Q)throw Error(`lodestar: ${L$} is missing [feishu].app_id / [feishu].app_secret`);let Y=J5(Z.runtime?.projects_root??Q5()),H=(Z.runtime?.live_elapsed??"bucket").trim().toLowerCase();if(H!=="bucket"&&H!=="second")throw Error(`lodestar: [runtime].live_elapsed must be "bucket" or "second", got "${Z.runtime?.live_elapsed}"`);let X=H,V=Z.notify?.bind??"127.0.0.1",W=Z.notify?.port??"9876";if(!/^\d+$/.test(W.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${W}"`);let G=Number.parseInt(W,10);if(!Number.isFinite(G)||G<=0||G>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${W}"`);let K=(R)=>{let D=Z[R]??{},F={};for(let[N,C]of Object.entries(D))if(typeof C==="string"&&C.length>0)F[N]=C;return F},_=()=>{let R={};for(let[D,F]of Object.entries(Z)){if(!D.startsWith("claude.models."))continue;let C=D.slice(14).trim();if(!C)continue;let x={};for(let[m,I]of Object.entries(F)){if(typeof I!=="string"||I.length===0)continue;let f=m.trim();if(f==="display_name"||f==="description"||f==="model")x[f]=I}R[C]=x}return R},B=()=>{let R={},D="projects.";for(let[F,N]of Object.entries(Z)){if(!F.startsWith("projects."))continue;let C=F.slice(9).trim();if(!C)continue;let x={};for(let[m,I]of Object.entries(N)){if(typeof I!=="string"||I.length===0)continue;switch(m.trim()){case"cwd":x.cwd=I;break;case"setting_sources":x.settingSources=I;break;case"strict_mcp":x.strictMcp=I==="true";break;case"tools":x.tools=I;break;case"load_project_mcp":x.loadProjectMcp=I==="true";break}}R[C]=x}return R},j=()=>{let R={},D="token_source.";for(let[F,N]of Object.entries(Z)){if(!F.startsWith("token_source."))continue;let C=F.slice(13).trim();if(!C)continue;let x={};for(let[m,I]of Object.entries(N)){if(typeof I!=="string"||I.length===0)continue;let f=m.trim();if(f==="default")x.default=I==="true";else if(f==="agent"||f==="display"||f==="auth"||f==="base_url"||f==="auth_token"||f==="api_key"||f==="bin"||f==="model"||f==="effort"||f==="models"||f==="slots"||f==="usage")x[f]=I}R[C]=x}return R},L=K("codex.env"),A=K("claude.env"),P=Z.claude?.bin?J5(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Q},runtime:{projects_root:Y,live_elapsed:X},notify:{bind:V,port:G},codex:{env:L},claude:{bin:P,env:A,models:_()},projects:B(),token_sources:j()}}function H5(){b.token_sources=Y5().token_sources}var b;var N$=k(()=>{D$();b=Y5()});import{appendFileSync as W5,mkdirSync as PV,readdirSync as UV,unlinkSync as G5,existsSync as X5,statSync as MV,renameSync as RV,readFileSync as OV}from"node:fs";import{join as z5}from"node:path";function A8($="development"){return $!=="test"}function K5($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Q=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Q}`}function _5($,Z=d){return z5(Z,`${L8}${K5($)}${D8}`)}function EV($){if(!$.startsWith(L8)||!$.endsWith(D8))return null;let Z=$.slice(L8.length,$.length-D8.length),J=/^(\d{4})-(\d{2})-(\d{2})$/.exec(Z);if(!J)return null;let Q=new Date(Number(J[1]),Number(J[2])-1,Number(J[3]));return Number.isNaN(Q.getTime())?null:Q}function q5($,Z=new Date,J=TV){let Q;try{Q=UV($)}catch{return 0}let Y=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),H=0;for(let X of Q){let V=EV(X);if(!V)continue;if(Math.round((Y.getTime()-V.getTime())/86400000)<J)continue;try{G5(z5($,X)),H++}catch{}}return H}function NV($=new Date){try{if(!X5(P1))return;let Z=MV(P1);if(!Z.isFile()||Z.size===0)return;let J=_5(Z.mtime);if(X5(J)){W5(J,OV(P1)),G5(P1);return}RV(P1,J)}catch{}}function z($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
23
+ `;if(process.stderr.write(J),!A8())return;try{let Q=K5(Z);if(V5!==Q)V5=Q,q5(d,Z);W5(_5(Z),J)}catch{}}var TV=7,L8="daemon-",D8=".log",V5=null;var w=k(()=>{D$();if(A8())try{PV(d,{recursive:!0})}catch{}if(A8()){try{NV()}catch{}try{q5(d)}catch{}}});function r($){return typeof $==="string"&&$?$:void 0}function v($){return $!=null&&typeof $==="object"?$:null}function Q0($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function V4($){if(!$)return"[]";let Z=Object.keys($),J=Z.slice(0,80),Q=Z.length>J.length?`,...+${Z.length-J.length}`:"";return`[${J.join(",")}${Q}]`}function xV($){let Z=$.slice(0,U8),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function yV($){let Z=v($);if(!Z)return null;let J=v(Z.event),Q=v(Z.payload);return v(Z.item)??v(Z.responseItem)??v(Z.rawItem)??v(J?.item)??v(J?.responseItem)??v(J?.rawItem)??v(Q?.item)??v(Q?.responseItem)??v(Q?.rawItem)??(H2(Z.type)?Z:null)??(J&&H2(J.type)?J:null)??(Q&&H2(Q.type)?Q:null)}function CV($){let Z=[],J=new WeakSet,Q=(Y,H,X)=>{if(Z.length>=U8||X>6)return;if(Array.isArray(Y)){if(H)Z.push(`${H}[]`);if(Y.length>0)Q(Y[0],H?`${H}[]`:"[]",X+1);return}if(Y==null||typeof Y!=="object")return;if(J.has(Y))return;J.add(Y);for(let V of Object.keys(Y)){if(Z.length>=U8)return;let W=H?`${H}.${V}`:V;Z.push(W),Q(Y[V],W,X+1)}};return Q($,"",0),Z}function M8($){let Z=new WeakSet,J;try{J=JSON.stringify($,(Q,Y)=>{if(typeof Y==="bigint")return`${Y.toString()}n`;if(typeof Y==="string"&&Y.length>P8)return`${Y.slice(0,P8)}...<truncated ${Y.length-P8} chars>`;if(Y!=null&&typeof Y==="object"){if(Z.has(Y))return"[Circular]";Z.add(Y)}return Y})??String($)}catch(Q){J=`<unserializable: ${Q}>`}if(J.length>F8)return`${J.slice(0,F8)}...<truncated ${J.length-F8} chars>`;return J}function M$($,Z){let J=v(Z),Q=J?v(J.params):null,Y=J?v(J.item)??v(Q?.item):null,H=J?r(J.method)??"-":"-";z([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${Q0(H)}`,`rootKeys=${V4(J)}`,`itemKeys=${V4(Y)}`,`payload=${M8(Z)}`].join(" "))}function R8($,Z,J){let Q=v(Z),Y=yV(Z),H=[`phase=${Q0(J.phase??"event")}`,`method=${Q0($)}`,`sourceMethod=${Q0(J.sourceMethod)}`,`sourceType=${Q0(J.sourceType)}`,`sessionId=${Q0(J.sessionId)}`,`threadId=${Q0(J.threadId)}`,`turnId=${Q0(J.turnId)}`,`itemId=${Q0(J.itemId)}`].join(" ");if(z(`codex-process: CONTEXT_COMPACTION_EVENT ${H} rootKeys=${V4(Q)} itemKeys=${V4(Y)}`),z(`codex-process: CONTEXT_COMPACTION_PATHS ${H} paths=${xV(CV(Z))}`),Y)z(`codex-process: CONTEXT_COMPACTION_ITEM ${H} item=${M8(Y)}`);z(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${H} payload=${M8(Z)}`)}function H2($){if(typeof $!=="string")return null;return kV.has($)?$:null}function SV($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||B5.has(Z))return"end";return"event"}function O8($,Z){return j5($,v(Z)??{})}function T8($){let Z=v($);if(!Z)return null;let J=r(Z.method)??r(Z.type)??"raw_message";return j5(J,Z)}function j5($,Z){let J=v(Z.payload),Q=[Z,v(Z.event),J,v(Z.item),v(Z.responseItem),v(Z.rawItem)].filter((W)=>W!=null),Y=null;for(let W of Q)if(Y=H2(W.type),Y)break;if(!B5.has($)&&!Y)return null;let H=v(Z.item)??v(Z.responseItem)??v(Z.rawItem),X=Y==="compacted"&&J?J:H&&H2(H.type)?H:Z,V=v(X.item)??v(X.responseItem)??v(X.rawItem)??H??{};return{...X,threadId:r(X.threadId)??r(X.thread_id)??r(Z.threadId)??r(Z.thread_id),turnId:r(X.turnId)??r(X.turn_id)??r(Z.turnId)??r(Z.turn_id),itemId:r(X.itemId)??r(X.item_id)??r(V.id)??r(V.itemId)??r(V.item_id),timestamp:r(Z.timestamp)??r(X.timestamp),recordType:r(Z.type),phase:SV(Y,$),sourceMethod:$,sourceType:Y??$}}var B5,kV,F8=200000,P8=50000,U8=400;var E8=k(()=>{w();B5=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),kV=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function X2($){return $!=null&&typeof $==="object"?$:null}function Y0($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function L5($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function W4($,Z){return $?Y0($[Z]):void 0}function R1($){let Z=X2($);if(!Z)return null;let J=X2(Z.inputTokensDetails)??X2(Z.input_tokens_details),Q=X2(Z.outputTokensDetails)??X2(Z.output_tokens_details),Y={total_tokens:Y0(Z.totalTokens??Z.total_tokens),input_tokens:Y0(Z.inputTokens??Z.input_tokens),output_tokens:Y0(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:Y0(Z.reasoningOutputTokens??Z.reasoning_output_tokens??W4(Q,"reasoningTokens")??W4(Q,"reasoning_tokens")),cache_creation_input_tokens:Y0(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:Y0(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??W4(J,"cachedTokens")??W4(J,"cached_tokens"))};return L5(Y)?Y:null}function N8($,Z){let J=(Y)=>{let H=Y0($?.[Y]),X=Y0(Z?.[Y]);if(H===void 0&&X===void 0)return;return Math.max(0,(H??0)-(X??0))},Q={total_tokens:J("total_tokens"),input_tokens:J("input_tokens"),output_tokens:J("output_tokens"),reasoning_output_tokens:J("reasoning_output_tokens"),cache_creation_input_tokens:J("cache_creation_input_tokens"),cache_read_input_tokens:J("cache_read_input_tokens")};return L5(Q)?Q:null}function k8($){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 D5($){let Z=$.trim();if(Z.length<2)return Z;let J=G4[Z[0]];if(!J||!Z.endsWith(J))return Z;let Q=Z.slice(1,-1);if(Z[0]==="'")return Q.replace(/''/g,"'");if(Z[0]==='"')return Q.replace(/\\"/g,'"');return Q}function y8($){let Z=wV(String($??"")),J=Z.split(`
24
24
  `,1)[0]?.trim()??"",Y=(J.startsWith("#")&&!J.startsWith("#!")?J.replace(/^#\s*/,"").trim():"").replace(/^(?:desc|dec|description|说明|目的|用途)\s*[::]\s*/i,"").trim(),H=Y?Z.split(`
25
25
  `).slice(1).join(`
26
- `).trimStart():Z;return{description:Y,command:H||Z}}function O1($,Z=60){let{description:J,command:Q}=x6($);if(J)return J;return NX(Q).replace(/\s+/g," ").trim().slice(0,Z)}function NX($){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 CX($){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 Y=SX(J[1]);return E6(Y||Z)}let Q=bX(Z);if(Q)return Q;return E6(Z)}function bX($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=L3(Z[1]).replace(/\.exe$/i,"");if(!/(?:^|[\\/])(?:powershell|pwsh)$/i.test(J))return null;let Q=Z[2];for(;;){let Y=Q.match(/^(-[A-Za-z][\w-]*)\s+([\s\S]*)$/);if(!Y)break;let H=Y[1].toLowerCase();if(H==="-command"||H==="-c")return E6(L3(Y[2]));if(Q=Y[2],H==="-executionpolicy"||H==="-inputformat"||H==="-outputformat")Q=Q.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function SX($){let Z=$.trim();if(Z.length<2)return Z;let J=z4[Z[0]];if(!J||!Z.endsWith(J))return Z;let Q=Z.slice(1,-1);if(Z[0]==="'")return Q.replace(/'\\''/g,"'");return Q.replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
28
- `)}function E6($){let Z=$.trim(),J=Z[0];if(!z4[J])return Z;let Q=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Q)&&!wX(Q,J))return Z;if(J!=='"')return Q.replace(/'\s*$/,"");return Q.replace(/\s*[”"]\s*$/,"").replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
29
- `).replace(/\s*"\s*'\$\(([^)]*)\)'/g,(V,X)=>` $(${X})`)}function wX($,Z){let J=z4[Z];for(let Q=0;Q<$.length;Q++){let Y=$[Q];if(Z==='"'&&Y==="\\"&&Q+1<$.length){Q++;continue}if(Y===J)return/^[\s]*$/.test($.slice(Q+1))}return!1}var z4;var G4=E(()=>{z4={'"':'"',"'":"'","“":"”"}});function U($){return $ instanceof Error?$.message:String($)}function z$($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}async function N6($,Z,J){let Q=null;try{return await Promise.race([$,new Promise((Y,H)=>{Q=setTimeout(()=>H(Error(`${J} timed out after ${Z/1000}s`)),Z)})])}finally{if(Q)clearTimeout(Q)}}import{isAbsolute as D3}from"node:path";function fX($){return $.kind==="fresh"?null:$.source.provider}function G$($,Z,J){let Q=fX($);if(Q&&Q!==Z)throw Error(`conversation launch provider mismatch: source=${Q} target=${Z}`);if($.kind!=="fresh"&&!$.source.sessionId.trim())throw Error("conversation launch source session id is empty");if($.kind!=="fresh"&&$.source.cwd!==null&&(typeof $.source.cwd!=="string"||!D3($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!D3(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 T1=()=>{};import{closeSync as vX,existsSync as q4,mkdirSync as hX,openSync as gX,readdirSync as IX,readSync as cX,statSync as _4,writeFileSync as mX}from"node:fs";import{homedir as g0}from"node:os";import{delimiter as C6,isAbsolute as P3,join as g$}from"node:path";import{EventEmitter as uX}from"node:events";import{StringDecoder as F3}from"node:string_decoder";import{spawn as pX}from"cross-spawn";function X2(){if(process.platform!=="win32"){let $=g$(g0(),".local","npm-global","bin","codex");if(q4($))return $;let Z=g$(g0(),".local","bin","codex");if(q4(Z))return Z}return lX()??"codex"}function lX(){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(C6)){if(!J)continue;for(let Q of Z){let Y=g$(J,Q);if(q4(Y))return Y}}return null}function iX(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([g$(g0(),".local","npm-global","bin"),g$(g0(),".local","bin"),g$(g0(),".bun","bin"),...(process.env.PATH??"").split(C6),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(C6)}function aX($={}){return["app-server",...($.configOverrides??[]).flatMap((Z)=>["--config",Z]),...($.disabledFeatures??[]).flatMap((Z)=>["--disable",Z]),"--listen","stdio://"]}function rX($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function tX($,Z,J=!1){switch($){case"read-only":return{type:"readOnly",networkAccess:J};case"workspace-write":return{type:"workspaceWrite",writableRoots:[Z],networkAccess:J,excludeTmpdirEnvVar:!1,excludeSlashTmp:!1};default:return{type:"dangerFullAccess"}}}function E$($){return typeof $==="string"&&sX.includes($)}function eX($){if(!Array.isArray($))return[];let Z=new Set,J=[];for(let Q of $){let Y=typeof Q==="string"?Q:typeof Q==="object"&&Q?Q.reasoningEffort:null;if(!E$(Y)||Z.has(Y))continue;Z.add(Y);let H=typeof Q==="object"&&Q&&typeof Q.description==="string"?Q.description:"";J.push({reasoningEffort:Y,description:H})}return J}function b6($,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:T3($)}}}return null}function T3($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function U3($){if(!$||!q4(A3))return null;let Z=null,J=[A3];while(J.length){let Q=J.pop(),Y;try{Y=IX(Q,{withFileTypes:!0})}catch(H){G(`codex-process: cannot scan Codex session dir ${Q}: ${H instanceof Error?H.message:H}`);continue}for(let H of Y){let V=g$(Q,H.name);if(H.isDirectory()){J.push(V);continue}if(!H.isFile())continue;if(!H.name.startsWith("rollout-")||!H.name.endsWith(`${$}.jsonl`))continue;try{let X=_4(V).mtimeMs;if(!Z||X>Z.mtimeMs)Z={path:V,mtimeMs:X}}catch(X){G(`codex-process: cannot stat Codex rollout ${V}: ${X instanceof Error?X.message:X}`)}}}return Z?.path??null}function k3($,Z,J=dX){let Q=$?.savedPath??$?.saved_path;if(typeof Q==="string"&&Q)return Q;let Y=$?.result;if(typeof Y==="string"){let H=$W($,Z,J);if(H)return H;if(Y.length>2048){let V=y3($);return G(`codex-process: image generation inline result could not be decoded id=${V} length=${Y.length}`),`Image generation returned ${Y.length} chars of inline data, but Lodestar could not materialize it as an image file.`}return Y}if(Y&&typeof Y==="object"){let H=Y.savedPath??Y.saved_path??Y.path;if(typeof H==="string"&&H)return H;return JSON.stringify(Y,null,2)}return""}function $W($,Z,J){let Q=$?.result;if(typeof Q!=="string")return null;let Y=ZW(Q);if(!Y)return null;let H=M3(Z??"unknown-thread"),V=M3(y3($)),X=g$(J,H),W=g$(X,`${V}.${Y.ext}`);try{return hX(X,{recursive:!0}),mX(W,Y.buffer),W}catch(z){return G(`codex-process: failed to write image generation result ${W}: ${z instanceof Error?z.message:z}`),null}}function y3($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function M3($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function ZW($){let Z=$.trim(),J=Z,Q=null,Y=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Y)Q=QW(Y[1]),J=Y[2];else{if(Z.length<64)return null;if(!/^[a-zA-Z0-9+/=_\-\s]+$/.test(Z))return null}if(J=J.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/"),!J||J.length%4===1)return null;let H=J.padEnd(Math.ceil(J.length/4)*4,"="),V;try{V=Buffer.from(H,"base64")}catch{return null}if(V.length<12)return null;let X=JW(V)??Q;if(!X)return null;return{buffer:V,ext:X}}function JW($){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 QW($){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 R3($,Z,J){let Q=b6($,Z);if(!Q)return null;switch($.type){case"commandExecution":return{...Q,output:$.aggregatedOutput??"",isError:$.exitCode!=null&&$.exitCode!==0};case"fileChange":return{...Q,output:JSON.stringify($.changes??[],null,2),isError:$.status==="failed"};case"mcpToolCall":return{...Q,output:$.error?JSON.stringify($.error,null,2):JSON.stringify($.result??null,null,2),isError:!!$.error};case"dynamicToolCall":return{...Q,output:JSON.stringify($.contentItems??[],null,2),isError:$.success===!1};case"webSearch":return{...Q,output:JSON.stringify($.action??{},null,2),isError:!1};case"imageGeneration":return{...Q,output:k3($,J),isError:$.status==="failed"}}return null}function K4($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return z$(Z)}function O3($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function YW($,Z,J){let Q=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":{if(J!=null){let Y=J.replace(/\s+/g," ").trim();return Y?`→ ${Y.slice(0,60)}`:""}return O1(Q(Z?.command))||"(空命令)"}case"FileChange":{let Y=Array.isArray(Z?.changes)?Z.changes.length:0;if(J!=null)return"";return Y>0?`改 ${Y} 个文件`:"文件变更"}case"MCP":return`${Q(Z?.server)}/${Q(Z?.tool)}`.slice(0,60);case"WebSearch":return`"${Q(Z?.query).slice(0,50)}"`;default:{if(J!=null){let Y=J.replace(/\s+/g," ").trim();return Y?`→ ${Y.slice(0,60)}`:""}return JSON.stringify(Z??{}).replace(/\s+/g," ").slice(0,60)}}}function E3($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function HW($){let Z=E3($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function VW($){let Z=$.agentsStates;if(!Z||typeof Z!=="object")return"";let J=[];for(let[Q,Y]of Object.entries(Z)){let H=Y,V=typeof H?.status==="string"?H.status:"unknown";J.push(`${z$(Q)}: ${V}`)}return J.join(`
30
- `)}var A3,dX,nX=30000,oX=5000,sX,W2="xhigh",j4,I0;var k1=E(()=>{y$();w();T6();G4();T1();T6();A3=g$(g0(),".codex","sessions"),dX=g$(g0(),".codex","generated_images");sX=["none","minimal","low","medium","high","xhigh","max","ultra"];j4=class j4 extends Error{method;requestId;serverCode;serverMessage;constructor($,Z,J,Q){super(`codex app-server ${$} failed (id=${Z}, code=${J??"MISS"}): ${Q}`);this.method=$;this.requestId=Z;this.serverCode=J;this.serverMessage=Q;this.name="CodexRpcResponseError"}};I0=class I0 extends uX{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;rolloutFilePath=null;rolloutReadOffset=0;rolloutLineRemainder="";rolloutDecoder=new F3("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;constructor($){super();this.on("error",()=>{}),this.exitPromise=new Promise((H)=>{this.resolveExit=H}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.launchKind=($.launch??{kind:"fresh"}).kind;let Z=X2(),J=aX($);G(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Q={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:iX(),...S.codex.env,...$.hostEnv??{}},Y=$.transformEnv?$.transformEnv(Q):Q;this.proc=pX(Z,J,rX($.workDir,Y)),this.proc.stdout.on("data",(H)=>this.onStdout(H)),this.proc.stderr.on("data",(H)=>this.onStderr(H)),this.proc.stdin.on("error",(H)=>this.handleStdinError(H)),this.proc.on("exit",(H,V)=>this.handleChildExit(H,V)),this.proc.on("close",(H,V)=>this.handleChildClose(H,V)),this.proc.on("error",(H)=>this.handleChildProcessError(H))}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.childExitCode=$,this.childExitSignal=Z,G(`codex-process: OS exit code=${$} signal=${Z}; awaiting stdio close`)}handleChildClose($,Z){this.alive=!1,this.flushStdoutTail(),this.flushStderrTail(),this.rejectPendingRequests((H,V)=>Error(`codex app-server closed before ${V.method} response (id=${H})`)),this.serverRequests.clear();let J=$??this.childExitCode,Q=Z??this.childExitSignal,Y=this.conversationMaterializationBarrier();if(Y){Y.then(()=>this.emitProcessExit(J,Q),()=>this.emitProcessExit(J,Q));return}this.emitProcessExit(J,Q)}handleChildProcessError($){G(`codex-process: child process error: ${$}`),this.rejectPendingRequests((Q,Y)=>Error(`codex app-server process failed before ${Y.method} response (id=${Q}): ${$.message}`,{cause:$}));let Z=typeof this.proc.pid!=="number",J=!1;if(Z&&this.alive)this.alive=!1,this.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 Q;try{Q=JSON.parse(J)}catch(Y){G(`codex-process: bad json: ${J.slice(0,200)} (${Y})`);continue}try{this.handleMessage(Q)}catch(Y){G(`codex-process: dispatch error: ${JSON.stringify(Q).slice(0,200)} (${Y})`)}}}flushStdoutTail(){if(!this.stdoutBuf)return;this.onStdout(Buffer.from(`
26
+ `).trimStart():Z;return{description:Y,command:H||Z}}function O1($,Z=60){let{description:J,command:Q}=y8($);if(J)return J;return bV(Q).replace(/\s+/g," ").trim().slice(0,Z)}function bV($){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 wV($){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 Y=vV(J[1]);return x8(Y||Z)}let Q=fV(Z);if(Q)return Q;return x8(Z)}function fV($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=D5(Z[1]).replace(/\.exe$/i,"");if(!/(?:^|[\\/])(?:powershell|pwsh)$/i.test(J))return null;let Q=Z[2];for(;;){let Y=Q.match(/^(-[A-Za-z][\w-]*)\s+([\s\S]*)$/);if(!Y)break;let H=Y[1].toLowerCase();if(H==="-command"||H==="-c")return x8(D5(Y[2]));if(Q=Y[2],H==="-executionpolicy"||H==="-inputformat"||H==="-outputformat")Q=Q.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function vV($){let Z=$.trim();if(Z.length<2)return Z;let J=G4[Z[0]];if(!J||!Z.endsWith(J))return Z;let Q=Z.slice(1,-1);if(Z[0]==="'")return Q.replace(/'\\''/g,"'");return Q.replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
28
+ `)}function x8($){let Z=$.trim(),J=Z[0];if(!G4[J])return Z;let Q=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Q)&&!hV(Q,J))return Z;if(J!=='"')return Q.replace(/'\s*$/,"");return Q.replace(/\s*[”"]\s*$/,"").replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
29
+ `).replace(/\s*"\s*'\$\(([^)]*)\)'/g,(X,V)=>` $(${V})`)}function hV($,Z){let J=G4[Z];for(let Q=0;Q<$.length;Q++){let Y=$[Q];if(Z==='"'&&Y==="\\"&&Q+1<$.length){Q++;continue}if(Y===J)return/^[\s]*$/.test($.slice(Q+1))}return!1}var G4;var z4=k(()=>{G4={'"':'"',"'":"'","“":"”"}});function U($){return $ instanceof Error?$.message:String($)}function G$($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}async function C8($,Z,J){let Q=null;try{return await Promise.race([$,new Promise((Y,H)=>{Q=setTimeout(()=>H(Error(`${J} timed out after ${Z/1000}s`)),Z)})])}finally{if(Q)clearTimeout(Q)}}import{isAbsolute as A5}from"node:path";function IV($){return $.kind==="fresh"?null:$.source.provider}function z$($,Z,J){let Q=IV($);if(Q&&Q!==Z)throw Error(`conversation launch provider mismatch: source=${Q} target=${Z}`);if($.kind!=="fresh"&&!$.source.sessionId.trim())throw Error("conversation launch source session id is empty");if($.kind!=="fresh"&&$.source.cwd!==null&&(typeof $.source.cwd!=="string"||!A5($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!A5(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 T1=()=>{};import{closeSync as gV,existsSync as q4,mkdirSync as cV,openSync as mV,readdirSync as uV,readSync as pV,statSync as _4,writeFileSync as lV}from"node:fs";import{homedir as h0}from"node:os";import{delimiter as S8,isAbsolute as F5,join as I$}from"node:path";import{EventEmitter as dV}from"node:events";import{StringDecoder as P5}from"node:string_decoder";import{spawn as iV}from"cross-spawn";function V2(){if(process.platform!=="win32"){let $=I$(h0(),".local","npm-global","bin","codex");if(q4($))return $;let Z=I$(h0(),".local","bin","codex");if(q4(Z))return Z}return nV()??"codex"}function nV(){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(S8)){if(!J)continue;for(let Q of Z){let Y=I$(J,Q);if(q4(Y))return Y}}return null}function oV(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([I$(h0(),".local","npm-global","bin"),I$(h0(),".local","bin"),I$(h0(),".bun","bin"),...(process.env.PATH??"").split(S8),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(S8)}function sV($={}){return["app-server",...($.configOverrides??[]).flatMap((Z)=>["--config",Z]),...($.disabledFeatures??[]).flatMap((Z)=>["--disable",Z]),"--listen","stdio://"]}function eV($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function $W($,Z,J=!1){switch($){case"read-only":return{type:"readOnly",networkAccess:J};case"workspace-write":return{type:"workspaceWrite",writableRoots:[Z],networkAccess:J,excludeTmpdirEnvVar:!1,excludeSlashTmp:!1};default:return{type:"dangerFullAccess"}}}function k$($){return typeof $==="string"&&ZW.includes($)}function JW($){if(!Array.isArray($))return[];let Z=new Set,J=[];for(let Q of $){let Y=typeof Q==="string"?Q:typeof Q==="object"&&Q?Q.reasoningEffort:null;if(!k$(Y)||Z.has(Y))continue;Z.add(Y);let H=typeof Q==="object"&&Q&&typeof Q.description==="string"?Q.description:"";J.push({reasoningEffort:Y,description:H})}return J}function b8($,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:E5($)}}}return null}function E5($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function M5($){if(!$||!q4(U5))return null;let Z=null,J=[U5];while(J.length){let Q=J.pop(),Y;try{Y=uV(Q,{withFileTypes:!0})}catch(H){z(`codex-process: cannot scan Codex session dir ${Q}: ${H instanceof Error?H.message:H}`);continue}for(let H of Y){let X=I$(Q,H.name);if(H.isDirectory()){J.push(X);continue}if(!H.isFile())continue;if(!H.name.startsWith("rollout-")||!H.name.endsWith(`${$}.jsonl`))continue;try{let V=_4(X).mtimeMs;if(!Z||V>Z.mtimeMs)Z={path:X,mtimeMs:V}}catch(V){z(`codex-process: cannot stat Codex rollout ${X}: ${V instanceof Error?V.message:V}`)}}}return Z?.path??null}function N5($,Z,J=aV){let Q=$?.savedPath??$?.saved_path;if(typeof Q==="string"&&Q)return Q;let Y=$?.result;if(typeof Y==="string"){let H=QW($,Z,J);if(H)return H;if(Y.length>2048){let X=k5($);return z(`codex-process: image generation inline result could not be decoded id=${X} length=${Y.length}`),`Image generation returned ${Y.length} chars of inline data, but Lodestar could not materialize it as an image file.`}return Y}if(Y&&typeof Y==="object"){let H=Y.savedPath??Y.saved_path??Y.path;if(typeof H==="string"&&H)return H;return JSON.stringify(Y,null,2)}return""}function QW($,Z,J){let Q=$?.result;if(typeof Q!=="string")return null;let Y=YW(Q);if(!Y)return null;let H=R5(Z??"unknown-thread"),X=R5(k5($)),V=I$(J,H),W=I$(V,`${X}.${Y.ext}`);try{return cV(V,{recursive:!0}),lV(W,Y.buffer),W}catch(G){return z(`codex-process: failed to write image generation result ${W}: ${G instanceof Error?G.message:G}`),null}}function k5($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function R5($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function YW($){let Z=$.trim(),J=Z,Q=null,Y=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Y)Q=XW(Y[1]),J=Y[2];else{if(Z.length<64)return null;if(!/^[a-zA-Z0-9+/=_\-\s]+$/.test(Z))return null}if(J=J.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/"),!J||J.length%4===1)return null;let H=J.padEnd(Math.ceil(J.length/4)*4,"="),X;try{X=Buffer.from(H,"base64")}catch{return null}if(X.length<12)return null;let V=HW(X)??Q;if(!V)return null;return{buffer:X,ext:V}}function HW($){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 XW($){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 O5($,Z,J){let Q=b8($,Z);if(!Q)return null;switch($.type){case"commandExecution":return{...Q,output:$.aggregatedOutput??"",isError:$.exitCode!=null&&$.exitCode!==0};case"fileChange":return{...Q,output:JSON.stringify($.changes??[],null,2),isError:$.status==="failed"};case"mcpToolCall":return{...Q,output:$.error?JSON.stringify($.error,null,2):JSON.stringify($.result??null,null,2),isError:!!$.error};case"dynamicToolCall":return{...Q,output:JSON.stringify($.contentItems??[],null,2),isError:$.success===!1};case"webSearch":return{...Q,output:JSON.stringify($.action??{},null,2),isError:!1};case"imageGeneration":return{...Q,output:N5($,J),isError:$.status==="failed"}}return null}function K4($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return G$(Z)}function T5($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function VW($,Z,J){let Q=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":{if(J!=null){let Y=J.replace(/\s+/g," ").trim();return Y?`→ ${Y.slice(0,60)}`:""}return O1(Q(Z?.command))||"(空命令)"}case"FileChange":{let Y=Array.isArray(Z?.changes)?Z.changes.length:0;if(J!=null)return"";return Y>0?`改 ${Y} 个文件`:"文件变更"}case"MCP":return`${Q(Z?.server)}/${Q(Z?.tool)}`.slice(0,60);case"WebSearch":return`"${Q(Z?.query).slice(0,50)}"`;default:{if(J!=null){let Y=J.replace(/\s+/g," ").trim();return Y?`→ ${Y.slice(0,60)}`:""}return JSON.stringify(Z??{}).replace(/\s+/g," ").slice(0,60)}}}function x5($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function WW($){let Z=x5($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function GW($){let Z=$.agentsStates;if(!Z||typeof Z!=="object")return"";let J=[];for(let[Q,Y]of Object.entries(Z)){let H=Y,X=typeof H?.status==="string"?H.status:"unknown";J.push(`${G$(Q)}: ${X}`)}return J.join(`
30
+ `)}var U5,aV,rV=30000,tV=5000,ZW,W2="xhigh",B4,I0;var E1=k(()=>{N$();w();E8();z4();T1();E8();U5=I$(h0(),".codex","sessions"),aV=I$(h0(),".codex","generated_images");ZW=["none","minimal","low","medium","high","xhigh","max","ultra"];B4=class B4 extends Error{method;requestId;serverCode;serverMessage;constructor($,Z,J,Q){super(`codex app-server ${$} failed (id=${Z}, code=${J??"MISS"}): ${Q}`);this.method=$;this.requestId=Z;this.serverCode=J;this.serverMessage=Q;this.name="CodexRpcResponseError"}};I0=class I0 extends dV{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;rolloutFilePath=null;rolloutReadOffset=0;rolloutLineRemainder="";rolloutDecoder=new P5("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;constructor($){super();this.on("error",()=>{}),this.exitPromise=new Promise((H)=>{this.resolveExit=H}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.launchKind=($.launch??{kind:"fresh"}).kind;let Z=V2(),J=sV($);z(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Q={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:oV(),...b.codex.env,...$.hostEnv??{}},Y=$.transformEnv?$.transformEnv(Q):Q;this.proc=iV(Z,J,eV($.workDir,Y)),this.proc.stdout.on("data",(H)=>this.onStdout(H)),this.proc.stderr.on("data",(H)=>this.onStderr(H)),this.proc.stdin.on("error",(H)=>this.handleStdinError(H)),this.proc.on("exit",(H,X)=>this.handleChildExit(H,X)),this.proc.on("close",(H,X)=>this.handleChildClose(H,X)),this.proc.on("error",(H)=>this.handleChildProcessError(H))}handleStdinError($){let Z=$ instanceof Error?$:Error(String($));if(z(`codex-process: stdin failed: ${Z.message}`),!this.expectedExit)this.emit("error",Z)}handleChildExit($,Z){if(!this.alive){z(`codex-process: duplicate exit ignored code=${$} signal=${Z}`);return}this.alive=!1,this.childExitCode=$,this.childExitSignal=Z,z(`codex-process: OS exit code=${$} signal=${Z}; awaiting stdio close`)}handleChildClose($,Z){this.alive=!1,this.flushStdoutTail(),this.flushStderrTail(),this.rejectPendingRequests((H,X)=>Error(`codex app-server closed before ${X.method} response (id=${H})`)),this.serverRequests.clear();let J=$??this.childExitCode,Q=Z??this.childExitSignal,Y=this.conversationMaterializationBarrier();if(Y){Y.then(()=>this.emitProcessExit(J,Q),()=>this.emitProcessExit(J,Q));return}this.emitProcessExit(J,Q)}handleChildProcessError($){z(`codex-process: child process error: ${$}`),this.rejectPendingRequests((Q,Y)=>Error(`codex app-server process failed before ${Y.method} response (id=${Q}): ${$.message}`,{cause:$}));let Z=typeof this.proc.pid!=="number",J=!1;if(Z&&this.alive)this.alive=!1,this.serverRequests.clear(),J=!0;if(this.emit("error",$),J)z(`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(),z(`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 Q;try{Q=JSON.parse(J)}catch(Y){z(`codex-process: bad json: ${J.slice(0,200)} (${Y})`);continue}try{this.handleMessage(Q)}catch(Y){z(`codex-process: dispatch error: ${JSON.stringify(Q).slice(0,200)} (${Y})`)}}}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 Q=typeof $.error?.code==="number"?$.error.code:null,Y=typeof $.error==="string"?$.error:typeof $.error?.message==="string"?$.error.message:JSON.stringify($.error);J.reject(new j4(J.method,$.id,Q,Y))}else J.resolve($.result);return}if(Object.prototype.hasOwnProperty.call($,"id")&&$.method){this.handleServerRequest($);return}if($.method){this.handleNotification($.method,$.params??{});return}let Z=O6($);if(Z){let J=this.withSessionId(Z);M6(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}M$("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=R6($,Z);if(J){let Q=this.withSessionId(J);M6($,Z,Q),this.emit("context_compacted",Q);return}switch($){case"thread/started":{let Q=Z.thread;if(Q?.id)this.sessionId=Q.id;return}case"thread/settings/updated":{let Q=Z.threadSettings;if(typeof Q?.model==="string")this.lastModel=Q.model;if(E$(Q?.effort))this.lastEffort=Q.effort;return}case"thread/tokenUsage/updated":{let Q=R1(Z.tokenUsage?.last);if(Q)this.lastUsage=Q,this.lastResult.usage=this.lastUsage;else G("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=R1(Z.tokenUsage?.total);let Y=Z.tokenUsage?.modelContextWindow;if(typeof Y==="number"&&Y>0)this.lastContextWindow=Y;this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:Z.threadId,turnId:Z.turnId});return}case"turn/started":{if(typeof Z.threadId!=="string"||Z.threadId!==this.sessionId){M$("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){M$("TURN_COMPLETED_THREAD_MISMATCH",{method:$,params:Z});return}let Q=Z.turn??{},Y=typeof Q.id==="string"&&Q.id?Q.id:null;if(Y){if(this.finishedTurnIds?.has(Y)){G(`codex-process: duplicate turn/completed ignored turn=${Y}`);return}if(this.currentTurnId&&this.currentTurnId!==Y){this.markTurnStartTerminal(Y),this.rememberFinishedTurn(Y),G(`codex-process: stale turn/completed ignored turn=${Y} current=${this.currentTurnId}`);return}if(!this.opts.ephemeral)this.flushRolloutImageGenerations();this.markConversationMaterialized("turn/completed notification"),this.markTurnStartTerminal(Y),this.rememberFinishedTurn(Y)}else M$("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let H=Q.status,V=H==="failed"||!!Q.error,X=!this.opts.ephemeral&&H==="completed"&&!V&&!!Y;this.lastCompletedTurnId=X?Y:null;let W=V?Q.error?.type??Q.error?.message??"failed":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof Q.durationMs==="number"?Q.durationMs:null,num_turns:1,usage:this.lastUsage,subtype:W,is_error:V},this.currentTurnId=null,this.emit("result",{subtype:W,is_error:V,duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Y,checkpoint:X&&this.sessionId?{provider:"codex",kind:"turn",id:Y,source:{provider:"codex",sessionId:this.sessionId,cwd:this.opts.workDir}}:null});return}case"turn/plan/updated":{this.emit("turn_plan_updated",Z);return}case"item/plan/delta":{this.emit("plan_delta",Z);return}case"thread/goal/updated":{if(Z.goal)this.emit("thread_goal_updated",Z.goal);else 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});else M$("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)}`),this.emit("error",Error(Z.message??Z.summary??"codex app-server error"));return}}M$("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){M$("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started",$))return;let J=b6(Z,this.opts.workDir);if(!J){M$("ITEM_STARTED_UNMAPPED",{method:"item/started",params:$});return}this.emit("tool_use",{id:Z.id,name:J.name,input:J.input})}handleSubagentItemStarted($){let Z=$?.item;if(!Z?.id)return;if(this.feedCollabItem(Z,"started",$))return;this.emitSubagentStep(Z,"started",$)}handleSubagentItemCompleted($){let Z=$?.item;if(!Z?.id)return;if(Z.type==="agentMessage"){let J=typeof Z.text==="string"?Z.text:"";if(J){let Q=typeof $?.threadId==="string"?$.threadId:"";this.collabAgentSummaries.set(Q,J)}return}if(this.feedCollabItem(Z,"completed",$))return;this.emitSubagentStep(Z,"completed",$)}handleItemCompleted($){let Z=$?.item;if(!Z?.id){M$("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});return}if(this.feedCollabItem(Z,"completed",$))return;let J=R3(Z,this.opts.workDir,this.sessionId??void 0);if(!J){M$("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)??z$(Z)}),this.emit("bg_task_updated",{task_id:Z,patch:{is_backgrounded:!0}});this.emit("bg_task_updated",{task_id:Z,patch:{status:"running"}});return}if(J==="idle"||J==="systemError"){if(!this.collabAgentWasActive.has(Z))return;if(this.collabAgentSettled.has(Z))return;this.collabAgentSettled.add(Z),this.emit("bg_task_settled",{task_id:Z,status:J==="systemError"?"failed":"completed",summary:this.collabAgentSummaries.get(Z)??void 0})}}emitSubagentStep($,Z,J){let Q=typeof J?.threadId==="string"?J.threadId:"",Y=Z==="started"?b6($,this.opts.workDir):R3($,this.opts.workDir,this.sessionId??void 0);if(!Y)return;let H="output"in Y&&typeof Y.output==="string"?Y.output:void 0;this.emit("subagent_step",{thread_id:Q,item_id:$.id,tool:Y.name,phase:Z,brief:YW(Y.name,Y.input,H)})}feedCollabItem($,Z,J){if($.type==="subAgentActivity"){let Q=typeof $.agentThreadId==="string"?$.agentThreadId:"";if(!Q)return!0;if($.kind==="started"&&!this.collabAgentNames.has(Q)){let Y=K4($.agentPath,Q);this.collabAgentNames.set(Q,Y),this.emit("bg_task_started",{task_id:Q,task_type:"local_agent",description:Y}),this.emit("bg_task_updated",{task_id:Q,patch:{is_backgrounded:!0}})}else if($.kind==="started"){let Y=this.collabAgentNames.get(Q),H=K4($.agentPath,Q);if(Y!==H&&!this.collabAgentSettled.has(Q))this.collabAgentNames.set(Q,H),this.emit("bg_task_started",{task_id:Q,task_type:"local_agent",description:H})}else if($.kind==="interrupted")this.emit("bg_task_updated",{task_id:Q,patch:{status:"paused"}});return!0}if($.type==="collabAgentToolCall"){let Q=$.agentsStates;if(Q&&typeof Q==="object")for(let[Y,H]of Object.entries(Q))this.translateAgentState(Y,H,$);if($.tool==="closeAgent"&&Z==="completed"&&$.status!=="failed"){let Y=E3($);for(let H of Y){if(this.collabAgentSettled.has(H))continue;if(this.collabAgentSettled.add(H),!this.collabAgentNames.has(H))this.collabAgentNames.set(H,K4(null,H));this.emit("bg_task_settled",{task_id:H,status:"stopped"})}}if($.tool==="spawnAgent"){if(Z==="started")this.emit("tool_use",{id:$.id,name:"Agent",input:{tool:"spawnAgent",prompt:O3($.prompt),description:HW($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:VW($),is_error:$.status==="failed"})}return!0}return!1}translateAgentState($,Z,J){let Q=Z?.status;if(typeof Q!=="string")return;if(this.collabAgentSettled.has($)){if(Q!=="running"&&Q!=="pendingInit"){if(Q==="errored"||Q==="shutdown"||Q==="notFound"||Q==="interrupted")this.emit("bg_task_updated",{task_id:$,patch:{status:Q==="errored"?"failed":"killed",error:typeof Z?.message==="string"&&Z.message?Z.message:void 0}});return}this.collabAgentSettled.delete($);let H=this.collabAgentNames.get($)??K4(null,$);this.emit("bg_task_started",{task_id:$,task_type:"local_agent",description:H}),this.emit("bg_task_updated",{task_id:$,patch:{is_backgrounded:!0}})}if(!this.collabAgentNames.has($)){this.collabAgentNames.set($,"子 agent");let V={task_id:$,task_type:"local_agent",description:"子 agent",prompt:O3(J.prompt)};this.emit("bg_task_started",V);let X={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",X)}if(Q==="running"||Q==="pendingInit"||Q==="interrupted"){let H={task_id:$,patch:{status:Q==="pendingInit"?"pending":Q==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",H);return}if(this.collabAgentSettled.size>=5000)this.collabAgentSettled.clear();this.collabAgentSettled.add($);let Y={task_id:$,status:Q==="completed"?"completed":Q==="errored"?"failed":"stopped",summary:typeof Z?.message==="string"&&Z.message?Z.message:void 0};this.emit("bg_task_settled",Y)}primeRolloutImageGenerationScan(){if(this.rolloutFilePath=null,this.rolloutReadOffset=0,this.rolloutLineRemainder="",this.rolloutDecoder=new F3("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=U3(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=_4($).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??U3(this.sessionId);if(!$){G(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Y=_4($).size;if(Y<=this.rolloutReadOffset)return;let H=Y-this.rolloutReadOffset;Z=Buffer.allocUnsafe(H);let V=gX($,"r"),X=0;try{while(X<H){let W=cX(V,Z,X,H-X,this.rolloutReadOffset+X);if(W===0)break;X+=W}}finally{vX(V)}Z=Z.subarray(0,X),this.rolloutReadOffset+=X}catch(Y){G(`codex-process: image generation rollout read failed ${$}: ${Y instanceof Error?Y.message:Y}`);return}let J=this.rolloutLineRemainder+this.rolloutDecoder.write(Z),Q=J.split(/\r?\n/);this.rolloutLineRemainder=J.endsWith(`
34
- `)?"":Q.pop()??"";for(let Y of Q){if(!Y.trim())continue;let H;try{H=JSON.parse(Y)}catch(W){G(`codex-process: image generation rollout JSON parse failed ${$}: ${W instanceof Error?W.message:W}`);continue}let V=H?.payload,X=V?.type;if(X!=="image_generation_end"&&X!=="image_generation_call")continue;this.emitRolloutImageGeneration(V)}}emitRolloutImageGeneration($){let Z=typeof $?.call_id==="string"?$.call_id:typeof $?.id==="string"?$.id:"";if(!Z||this.emittedImageGenerationIds.has(Z))return;let J=k3($,this.sessionId??void 0);if(!J)return;let Q=$?.status==="failed",Y=$?.status==="generating"&&P3(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:{status:Y,revisedPrompt:T3($)}}),this.emit("tool_result",{tool_use_id:Z,content:J,is_error:Q})}withSessionId($){let Z=$.sessionId??this.sessionId??void 0;return Z?{...$,sessionId:Z}:$}handleServerRequest($){let Z=String($.id);switch(this.serverRequests.set(Z,{id:$.id,method:$.method,params:$.params}),$.method){case"item/commandExecution/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"Bash",input:{command:J.command,cwd:J.cwd,reason:J.reason},tool_use_id:J.itemId});return}case"item/fileChange/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"FileChange",input:{reason:J.reason,grantRoot:J.grantRoot},tool_use_id:J.itemId});return}case"item/tool/requestUserInput":{let J=$.params??{},Q={questions:(J.questions??[]).map((Y)=>({id:Y.id,header:Y.header,question:Y.question,options:Array.isArray(Y.options)&&Y.options.length?Y.options.map((H)=>({label:H.label,description:H.description})):[{label:"自定义回答",description:Y.isSecret?"请直接在群里回复":"可直接在群里回复"}]}))};this.emit("tool_use",{id:J.itemId,name:"AskUserQuestion",input:Q}),this.emit("can_use_tool",{request_id:Z,tool_name:"AskUserQuestion",input:Q,tool_use_id:J.itemId});return}case"item/permissions/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"PermissionProfile",input:{cwd:J.cwd,reason:J.reason,permissions:J.permissions},tool_use_id:J.itemId});return}case"item/tool/call":{let J=$.params??{};this.emit("tool_use",{id:J.callId,name:J.namespace?`${J.namespace}.${J.tool}`:J.tool,input:J.arguments}),this.respond(Z,{contentItems:[{type:"inputText",text:"Lodestar does not implement this dynamic tool."}],success:!1});return}case"account/chatgptAuthTokens/refresh":case"attestation/generate":case"applyPatchApproval":case"execCommandApproval":default:M$("SERVER_REQUEST_UNSUPPORTED",$),this.respondError(Z,`unsupported server request: ${$.method}`)}}write($,Z){let J=(Q)=>{let Y=Q instanceof Error?Q:Error(String(Q));return G(`codex-process: stdin write failed: ${Y.message}`),Z?.(Y),!1};if(!this.alive)return J(Error(`write to dead process: ${JSON.stringify($).slice(0,200)}`));if(this.proc.stdin.destroyed||this.proc.stdin.writableEnded||!this.proc.stdin.writable)return J(Error("stdin is not writable"));try{return this.proc.stdin.write(JSON.stringify($)+`
35
- `,(Q)=>{if(Q)J(Q)}),!0}catch(Q){return J(Q)}}request($,Z,J=nX){let Q=++this.requestCounter;return new Promise((Y,H)=>{let V=setTimeout(()=>{let W=this.pending.get(Q);if(!W)return;this.pending.delete(Q),W.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Q})`))},Math.max(0,J)),X={resolve:Y,reject:H,method:$,timeout:V};this.pending.set(Q,X),this.write({id:Q,method:$,params:Z},(W)=>{if(this.pending.get(Q)!==X)return;this.pending.delete(Q),clearTimeout(V),H(Error(`codex app-server ${$} request write failed (id=${Q}): ${W.message}`,{cause:W}))})})}rejectPendingRequests($){for(let[Z,J]of this.pending)clearTimeout(J.timeout),J.reject($(Z,J));this.pending.clear()}respond($,Z){let J=String($),Q=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Q?.id??$,result:Z})}respondError($,Z){let J=String($),Q=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Q?.id??$,error:{code:-32601,message:Z}})}sendInitialize(){if(!this.readyPromise)this.readyPromise=this.initializeAndStartThread(),this.readyPromise.catch(($)=>{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,Q;if($.kind==="resume")J="thread/resume",Q=await this.request(J,{threadId:$.source.sessionId,...Z,excludeTurns:!0,persistExtendedHistory:!1});else if($.kind==="fork")J="thread/fork",Q=await this.request(J,{threadId:$.source.sessionId,...$.through?{lastTurnId:$.through.id}:{},...Z,excludeTurns:!0});else J="thread/start",Q=await this.request(J,{...Z,experimentalRawEvents:!1,persistExtendedHistory:!1});let Y=Q?.thread;if(typeof Y?.id!=="string"||!Y.id)throw Error(`codex app-server ${J} returned no thread.id`);let H=typeof Y.cwd==="string"?Y.cwd:typeof Q?.cwd==="string"?Q.cwd:null;if(H!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${H??"MISS"}, expected ${this.opts.workDir}`);if($.kind==="fork"&&Y.id===$.source.sessionId)throw Error(`codex app-server thread/fork returned source thread id ${Y.id}`);if($.kind==="resume"&&Y.id!==$.source.sessionId)throw Error(`codex app-server thread/resume returned thread id ${Y.id}, expected ${$.source.sessionId}`);let V=typeof Y.path==="string"&&Y.path?Y.path:null;if(!this.opts.ephemeral&&(!V||!P3(V)||!V.endsWith(`${Y.id}.jsonl`)))throw Error(`codex app-server ${J} returned invalid thread.path=${V??"MISS"}`);if(this.sessionId=Y.id,this.conversationRolloutPath=V,this.conversationResumable=!1,$.kind!=="fresh")await this.verifyConversationMaterialized(`${J} response`),this.conversationResumable=!0;if(Q?.model)this.lastModel=Q.model;if(E$(Q?.reasoningEffort))this.lastEffort=Q.reasoningEffort;else this.lastEffort=this.opts.effort??null;if(G(`codex-process: thread=${this.sessionId}`),!this.opts.ephemeral)this.primeRolloutImageGenerationScan();this.emit("init",{session_id:this.sessionId,thread:Y})}markConversationMaterialized($){if(this.opts.ephemeral)return;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:$})},(Q)=>{let Y=Q instanceof Error?Q:Error(String(Q));this.lastConversationMaterializationFailure=Y,G(`codex-process: conversation materialization check failed thread=${Z} source=${$}: ${Y.message}`),this.emit("conversation_materialization_failed",{session_id:Z,path:this.conversationRolloutPath,source:$,error:Y})}).finally(()=>{if(this.conversationMaterializationVerification===J)this.conversationMaterializationVerification=null;let Q=this.conversationMaterializationRetrySource;if(this.conversationMaterializationRetrySource=null,!this.conversationResumable&&Q)this.markConversationMaterialized(Q)})}async verifyConversationMaterialized($){let Z=this.sessionId,J=this.conversationRolloutPath;if(!Z||!J)throw Error(`codex ${$} has no initialized rollout identity`);let Y=(await this.request("thread/read",{threadId:Z,includeTurns:!0},oX))?.thread;if(Y?.id!==Z||Y.cwd!==this.opts.workDir||Y.path!==J||!Array.isArray(Y.turns))throw Error(`codex ${$} thread/read returned an invalid materialized thread`);this.assertConversationRolloutMaterialized($)}assertConversationRolloutMaterialized($){let Z=this.conversationRolloutPath;if(!Z)throw Error(`codex ${$} has no authoritative rollout path`);let J;try{J=_4(Z)}catch(Q){throw Error(`codex ${$} rollout is not readable at ${Z}: ${Q instanceof Error?Q.message:Q}`,{cause:Q})}if(!J.isFile())throw Error(`codex ${$} rollout path is not a file: ${Z}`)}conversationLaunch(){let $=this.opts.launch??{kind:"fresh"};if(G$($,"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:this.opts.sandbox??"danger-full-access",config:{"features.default_mode_request_user_input":!0,...this.opts.effort?{model_reasoning_effort:this.opts.effort}:{}},...this.opts.model?{model:this.opts.model}:{},...this.opts.appendSystemPrompt?{developerInstructions:this.opts.appendSystemPrompt}:{},serviceName:"lodestar",...this.opts.ephemeral?{ephemeral:!0}:{}}}sendUserText($,Z=[]){let J=Z.length?Z.map((Y)=>`[file: ${Y}]`).join(" ")+`
33
+ `))>=0){let J=this.stderrBuf.slice(0,Z);if(this.stderrBuf=this.stderrBuf.slice(Z+1),J.trim())z(`codex-process[stderr]: ${J}`)}}flushStderrTail(){let $=this.stderrBuf;if(this.stderrBuf="",$.trim())z(`codex-process[stderr]: ${$}`)}handleMessage($){if(Object.prototype.hasOwnProperty.call($,"id")&&!$.method){let J=this.pending.get($.id);if(!J){z(`codex-process: response for unknown id=${$.id}`);return}if(this.pending.delete($.id),clearTimeout(J.timeout),$.error){let Q=typeof $.error?.code==="number"?$.error.code:null,Y=typeof $.error==="string"?$.error:typeof $.error?.message==="string"?$.error.message:JSON.stringify($.error);J.reject(new B4(J.method,$.id,Q,Y))}else J.resolve($.result);return}if(Object.prototype.hasOwnProperty.call($,"id")&&$.method){this.handleServerRequest($);return}if($.method){this.handleNotification($.method,$.params??{});return}let Z=T8($);if(Z){let J=this.withSessionId(Z);R8(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}M$("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=O8($,Z);if(J){let Q=this.withSessionId(J);R8($,Z,Q),this.emit("context_compacted",Q);return}switch($){case"thread/started":{let Q=Z.thread;if(Q?.id)this.sessionId=Q.id;return}case"thread/settings/updated":{let Q=Z.threadSettings;if(typeof Q?.model==="string")this.lastModel=Q.model;if(k$(Q?.effort))this.lastEffort=Q.effort;return}case"thread/tokenUsage/updated":{let Q=R1(Z.tokenUsage?.last);if(Q)this.lastUsage=Q,this.lastResult.usage=this.lastUsage;else z("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=R1(Z.tokenUsage?.total);let Y=Z.tokenUsage?.modelContextWindow;if(typeof Y==="number"&&Y>0)this.lastContextWindow=Y;this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:Z.threadId,turnId:Z.turnId});return}case"turn/started":{if(typeof Z.threadId!=="string"||Z.threadId!==this.sessionId){M$("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){M$("TURN_COMPLETED_THREAD_MISMATCH",{method:$,params:Z});return}let Q=Z.turn??{},Y=typeof Q.id==="string"&&Q.id?Q.id:null;if(Y){if(this.finishedTurnIds?.has(Y)){z(`codex-process: duplicate turn/completed ignored turn=${Y}`);return}if(this.currentTurnId&&this.currentTurnId!==Y){this.markTurnStartTerminal(Y),this.rememberFinishedTurn(Y),z(`codex-process: stale turn/completed ignored turn=${Y} current=${this.currentTurnId}`);return}if(!this.opts.ephemeral)this.flushRolloutImageGenerations();this.markConversationMaterialized("turn/completed notification"),this.markTurnStartTerminal(Y),this.rememberFinishedTurn(Y)}else M$("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let H=Q.status,X=H==="failed"||!!Q.error,V=!this.opts.ephemeral&&H==="completed"&&!X&&!!Y;this.lastCompletedTurnId=V?Y:null;let W=X?Q.error?.type??Q.error?.message??"failed":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof Q.durationMs==="number"?Q.durationMs:null,num_turns:1,usage:this.lastUsage,subtype:W,is_error:X},this.currentTurnId=null,this.emit("result",{subtype:W,is_error:X,duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Y,checkpoint:V&&this.sessionId?{provider:"codex",kind:"turn",id:Y,source:{provider:"codex",sessionId:this.sessionId,cwd:this.opts.workDir}}:null});return}case"turn/plan/updated":{this.emit("turn_plan_updated",Z);return}case"item/plan/delta":{this.emit("plan_delta",Z);return}case"thread/goal/updated":{if(Z.goal)this.emit("thread_goal_updated",Z.goal);else z("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 M$("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":{z(`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":{z(`codex-process: ${$}: ${Z.summary??Z.message??JSON.stringify(Z).slice(0,200)}`);return}case"error":{z(`codex-process: server error: ${JSON.stringify(Z).slice(0,500)}`),this.emit("error",Error(Z.message??Z.summary??"codex app-server error"));return}}M$("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){M$("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started",$))return;let J=b8(Z,this.opts.workDir);if(!J){M$("ITEM_STARTED_UNMAPPED",{method:"item/started",params:$});return}this.emit("tool_use",{id:Z.id,name:J.name,input:J.input})}handleSubagentItemStarted($){let Z=$?.item;if(!Z?.id)return;if(this.feedCollabItem(Z,"started",$))return;this.emitSubagentStep(Z,"started",$)}handleSubagentItemCompleted($){let Z=$?.item;if(!Z?.id)return;if(Z.type==="agentMessage"){let J=typeof Z.text==="string"?Z.text:"";if(J){let Q=typeof $?.threadId==="string"?$.threadId:"";this.collabAgentSummaries.set(Q,J)}return}if(this.feedCollabItem(Z,"completed",$))return;this.emitSubagentStep(Z,"completed",$)}handleItemCompleted($){let Z=$?.item;if(!Z?.id){M$("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=O5(Z,this.opts.workDir,this.sessionId??void 0);if(!J){M$("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)??G$(Z)}),this.emit("bg_task_updated",{task_id:Z,patch:{is_backgrounded:!0}});this.emit("bg_task_updated",{task_id:Z,patch:{status:"running"}});return}if(J==="idle"||J==="systemError"){if(!this.collabAgentWasActive.has(Z))return;if(this.collabAgentSettled.has(Z))return;this.collabAgentSettled.add(Z),this.emit("bg_task_settled",{task_id:Z,status:J==="systemError"?"failed":"completed",summary:this.collabAgentSummaries.get(Z)??void 0})}}emitSubagentStep($,Z,J){let Q=typeof J?.threadId==="string"?J.threadId:"",Y=Z==="started"?b8($,this.opts.workDir):O5($,this.opts.workDir,this.sessionId??void 0);if(!Y)return;let H="output"in Y&&typeof Y.output==="string"?Y.output:void 0;this.emit("subagent_step",{thread_id:Q,item_id:$.id,tool:Y.name,phase:Z,brief:VW(Y.name,Y.input,H)})}feedCollabItem($,Z,J){if($.type==="subAgentActivity"){let Q=typeof $.agentThreadId==="string"?$.agentThreadId:"";if(!Q)return!0;if($.kind==="started"&&!this.collabAgentNames.has(Q)){let Y=K4($.agentPath,Q);this.collabAgentNames.set(Q,Y),this.emit("bg_task_started",{task_id:Q,task_type:"local_agent",description:Y}),this.emit("bg_task_updated",{task_id:Q,patch:{is_backgrounded:!0}})}else if($.kind==="started"){let Y=this.collabAgentNames.get(Q),H=K4($.agentPath,Q);if(Y!==H&&!this.collabAgentSettled.has(Q))this.collabAgentNames.set(Q,H),this.emit("bg_task_started",{task_id:Q,task_type:"local_agent",description:H})}else if($.kind==="interrupted")this.emit("bg_task_updated",{task_id:Q,patch:{status:"paused"}});return!0}if($.type==="collabAgentToolCall"){let Q=$.agentsStates;if(Q&&typeof Q==="object")for(let[Y,H]of Object.entries(Q))this.translateAgentState(Y,H,$);if($.tool==="closeAgent"&&Z==="completed"&&$.status!=="failed"){let Y=x5($);for(let H of Y){if(this.collabAgentSettled.has(H))continue;if(this.collabAgentSettled.add(H),!this.collabAgentNames.has(H))this.collabAgentNames.set(H,K4(null,H));this.emit("bg_task_settled",{task_id:H,status:"stopped"})}}if($.tool==="spawnAgent"){if(Z==="started")this.emit("tool_use",{id:$.id,name:"Agent",input:{tool:"spawnAgent",prompt:T5($.prompt),description:WW($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:GW($),is_error:$.status==="failed"})}return!0}return!1}translateAgentState($,Z,J){let Q=Z?.status;if(typeof Q!=="string")return;if(this.collabAgentSettled.has($)){if(Q!=="running"&&Q!=="pendingInit"){if(Q==="errored"||Q==="shutdown"||Q==="notFound"||Q==="interrupted")this.emit("bg_task_updated",{task_id:$,patch:{status:Q==="errored"?"failed":"killed",error:typeof Z?.message==="string"&&Z.message?Z.message:void 0}});return}this.collabAgentSettled.delete($);let H=this.collabAgentNames.get($)??K4(null,$);this.emit("bg_task_started",{task_id:$,task_type:"local_agent",description:H}),this.emit("bg_task_updated",{task_id:$,patch:{is_backgrounded:!0}})}if(!this.collabAgentNames.has($)){this.collabAgentNames.set($,"子 agent");let X={task_id:$,task_type:"local_agent",description:"子 agent",prompt:T5(J.prompt)};this.emit("bg_task_started",X);let V={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",V)}if(Q==="running"||Q==="pendingInit"||Q==="interrupted"){let H={task_id:$,patch:{status:Q==="pendingInit"?"pending":Q==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",H);return}if(this.collabAgentSettled.size>=5000)this.collabAgentSettled.clear();this.collabAgentSettled.add($);let Y={task_id:$,status:Q==="completed"?"completed":Q==="errored"?"failed":"stopped",summary:typeof Z?.message==="string"&&Z.message?Z.message:void 0};this.emit("bg_task_settled",Y)}primeRolloutImageGenerationScan(){if(this.rolloutFilePath=null,this.rolloutReadOffset=0,this.rolloutLineRemainder="",this.rolloutDecoder=new P5("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=M5(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=_4($).size,z(`codex-process: image generation rollout scan primed ${$} offset=${this.rolloutReadOffset}`)}catch(Z){z(`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??M5(this.sessionId);if(!$){z(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Y=_4($).size;if(Y<=this.rolloutReadOffset)return;let H=Y-this.rolloutReadOffset;Z=Buffer.allocUnsafe(H);let X=mV($,"r"),V=0;try{while(V<H){let W=pV(X,Z,V,H-V,this.rolloutReadOffset+V);if(W===0)break;V+=W}}finally{gV(X)}Z=Z.subarray(0,V),this.rolloutReadOffset+=V}catch(Y){z(`codex-process: image generation rollout read failed ${$}: ${Y instanceof Error?Y.message:Y}`);return}let J=this.rolloutLineRemainder+this.rolloutDecoder.write(Z),Q=J.split(/\r?\n/);this.rolloutLineRemainder=J.endsWith(`
34
+ `)?"":Q.pop()??"";for(let Y of Q){if(!Y.trim())continue;let H;try{H=JSON.parse(Y)}catch(W){z(`codex-process: image generation rollout JSON parse failed ${$}: ${W instanceof Error?W.message:W}`);continue}let X=H?.payload,V=X?.type;if(V!=="image_generation_end"&&V!=="image_generation_call")continue;this.emitRolloutImageGeneration(X)}}emitRolloutImageGeneration($){let Z=typeof $?.call_id==="string"?$.call_id:typeof $?.id==="string"?$.id:"";if(!Z||this.emittedImageGenerationIds.has(Z))return;let J=N5($,this.sessionId??void 0);if(!J)return;let Q=$?.status==="failed",Y=$?.status==="generating"&&F5(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:{status:Y,revisedPrompt:E5($)}}),this.emit("tool_result",{tool_use_id:Z,content:J,is_error:Q})}withSessionId($){let Z=$.sessionId??this.sessionId??void 0;return Z?{...$,sessionId:Z}:$}handleServerRequest($){let Z=String($.id);switch(this.serverRequests.set(Z,{id:$.id,method:$.method,params:$.params}),$.method){case"item/commandExecution/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"Bash",input:{command:J.command,cwd:J.cwd,reason:J.reason},tool_use_id:J.itemId});return}case"item/fileChange/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"FileChange",input:{reason:J.reason,grantRoot:J.grantRoot},tool_use_id:J.itemId});return}case"item/tool/requestUserInput":{let J=$.params??{},Q={questions:(J.questions??[]).map((Y)=>({id:Y.id,header:Y.header,question:Y.question,options:Array.isArray(Y.options)&&Y.options.length?Y.options.map((H)=>({label:H.label,description:H.description})):[{label:"自定义回答",description:Y.isSecret?"请直接在群里回复":"可直接在群里回复"}]}))};this.emit("tool_use",{id:J.itemId,name:"AskUserQuestion",input:Q}),this.emit("can_use_tool",{request_id:Z,tool_name:"AskUserQuestion",input:Q,tool_use_id:J.itemId});return}case"item/permissions/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"PermissionProfile",input:{cwd:J.cwd,reason:J.reason,permissions:J.permissions},tool_use_id:J.itemId});return}case"item/tool/call":{let J=$.params??{};this.emit("tool_use",{id:J.callId,name:J.namespace?`${J.namespace}.${J.tool}`:J.tool,input:J.arguments}),this.respond(Z,{contentItems:[{type:"inputText",text:"Lodestar does not implement this dynamic tool."}],success:!1});return}case"account/chatgptAuthTokens/refresh":case"attestation/generate":case"applyPatchApproval":case"execCommandApproval":default:M$("SERVER_REQUEST_UNSUPPORTED",$),this.respondError(Z,`unsupported server request: ${$.method}`)}}write($,Z){let J=(Q)=>{let Y=Q instanceof Error?Q:Error(String(Q));return z(`codex-process: stdin write failed: ${Y.message}`),Z?.(Y),!1};if(!this.alive)return J(Error(`write to dead process: ${JSON.stringify($).slice(0,200)}`));if(this.proc.stdin.destroyed||this.proc.stdin.writableEnded||!this.proc.stdin.writable)return J(Error("stdin is not writable"));try{return this.proc.stdin.write(JSON.stringify($)+`
35
+ `,(Q)=>{if(Q)J(Q)}),!0}catch(Q){return J(Q)}}request($,Z,J=rV){let Q=++this.requestCounter;return new Promise((Y,H)=>{let X=setTimeout(()=>{let W=this.pending.get(Q);if(!W)return;this.pending.delete(Q),W.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Q})`))},Math.max(0,J)),V={resolve:Y,reject:H,method:$,timeout:X};this.pending.set(Q,V),this.write({id:Q,method:$,params:Z},(W)=>{if(this.pending.get(Q)!==V)return;this.pending.delete(Q),clearTimeout(X),H(Error(`codex app-server ${$} request write failed (id=${Q}): ${W.message}`,{cause:W}))})})}rejectPendingRequests($){for(let[Z,J]of this.pending)clearTimeout(J.timeout),J.reject($(Z,J));this.pending.clear()}respond($,Z){let J=String($),Q=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Q?.id??$,result:Z})}respondError($,Z){let J=String($),Q=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Q?.id??$,error:{code:-32601,message:Z}})}sendInitialize(){if(!this.readyPromise)this.readyPromise=this.initializeAndStartThread(),this.readyPromise.catch(($)=>{z(`codex-process: initialize failed: ${$}`),this.emit("error",$)})}initializationPromise(){if(!this.readyPromise)this.sendInitialize();return this.readyPromise}isConversationResumable(){return this.conversationResumable}conversationMaterializationBarrier(){return this.conversationMaterializationVerification?this.drainConversationMaterialization():null}conversationMaterializationFailure(){return this.lastConversationMaterializationFailure}async drainConversationMaterialization(){while(this.conversationMaterializationVerification){let $=this.conversationMaterializationVerification;try{await $}catch{}await Promise.resolve()}if(!this.conversationResumable&&this.lastConversationMaterializationFailure)throw this.lastConversationMaterializationFailure}async readRateLimits(){return await this.ensureInitialized(),this.request("account/rateLimits/read",{})}initializeParams(){return{clientInfo:{name:"lodestar",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}}async ensureInitialized(){if(!this.initializePromise)this.initializePromise=this.request("initialize",this.initializeParams()).then(()=>{if(!this.write({method:"initialized"}))throw Error("codex app-server initialized notification write failed")});await this.initializePromise}async initializeAndStartThread(){let $=this.conversationLaunch();await this.ensureInitialized();let Z=this.threadParams(),J,Q;if($.kind==="resume")J="thread/resume",Q=await this.request(J,{threadId:$.source.sessionId,...Z,excludeTurns:!0,persistExtendedHistory:!1});else if($.kind==="fork")J="thread/fork",Q=await this.request(J,{threadId:$.source.sessionId,...$.through?{lastTurnId:$.through.id}:{},...Z,excludeTurns:!0});else J="thread/start",Q=await this.request(J,{...Z,experimentalRawEvents:!1,persistExtendedHistory:!1});let Y=Q?.thread;if(typeof Y?.id!=="string"||!Y.id)throw Error(`codex app-server ${J} returned no thread.id`);let H=typeof Y.cwd==="string"?Y.cwd:typeof Q?.cwd==="string"?Q.cwd:null;if(H!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${H??"MISS"}, expected ${this.opts.workDir}`);if($.kind==="fork"&&Y.id===$.source.sessionId)throw Error(`codex app-server thread/fork returned source thread id ${Y.id}`);if($.kind==="resume"&&Y.id!==$.source.sessionId)throw Error(`codex app-server thread/resume returned thread id ${Y.id}, expected ${$.source.sessionId}`);let X=typeof Y.path==="string"&&Y.path?Y.path:null;if(!this.opts.ephemeral&&(!X||!F5(X)||!X.endsWith(`${Y.id}.jsonl`)))throw Error(`codex app-server ${J} returned invalid thread.path=${X??"MISS"}`);if(this.sessionId=Y.id,this.conversationRolloutPath=X,this.conversationResumable=!1,$.kind!=="fresh")await this.verifyConversationMaterialized(`${J} response`),this.conversationResumable=!0;if(Q?.model)this.lastModel=Q.model;if(k$(Q?.reasoningEffort))this.lastEffort=Q.reasoningEffort;else this.lastEffort=this.opts.effort??null;if(z(`codex-process: thread=${this.sessionId}`),!this.opts.ephemeral)this.primeRolloutImageGenerationScan();this.emit("init",{session_id:this.sessionId,thread:Y})}markConversationMaterialized($){if(this.opts.ephemeral)return;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,z(`codex-process: conversation materialized thread=${Z} source=${$}`),this.emit("conversation_materialized",{session_id:Z,source:$})},(Q)=>{let Y=Q instanceof Error?Q:Error(String(Q));this.lastConversationMaterializationFailure=Y,z(`codex-process: conversation materialization check failed thread=${Z} source=${$}: ${Y.message}`),this.emit("conversation_materialization_failed",{session_id:Z,path:this.conversationRolloutPath,source:$,error:Y})}).finally(()=>{if(this.conversationMaterializationVerification===J)this.conversationMaterializationVerification=null;let Q=this.conversationMaterializationRetrySource;if(this.conversationMaterializationRetrySource=null,!this.conversationResumable&&Q)this.markConversationMaterialized(Q)})}async verifyConversationMaterialized($){let Z=this.sessionId,J=this.conversationRolloutPath;if(!Z||!J)throw Error(`codex ${$} has no initialized rollout identity`);let Y=(await this.request("thread/read",{threadId:Z,includeTurns:!0},tV))?.thread;if(Y?.id!==Z||Y.cwd!==this.opts.workDir||Y.path!==J||!Array.isArray(Y.turns))throw Error(`codex ${$} thread/read returned an invalid materialized thread`);this.assertConversationRolloutMaterialized($)}assertConversationRolloutMaterialized($){let Z=this.conversationRolloutPath;if(!Z)throw Error(`codex ${$} has no authoritative rollout path`);let J;try{J=_4(Z)}catch(Q){throw Error(`codex ${$} rollout is not readable at ${Z}: ${Q instanceof Error?Q.message:Q}`,{cause:Q})}if(!J.isFile())throw Error(`codex ${$} rollout path is not a file: ${Z}`)}conversationLaunch(){let $=this.opts.launch??{kind:"fresh"};if(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:this.opts.sandbox??"danger-full-access",config:{"features.default_mode_request_user_input":!0,...this.opts.effort?{model_reasoning_effort:this.opts.effort}:{}},...this.opts.model?{model:this.opts.model}:{},...this.opts.appendSystemPrompt?{developerInstructions:this.opts.appendSystemPrompt}:{},serviceName:"lodestar",...this.opts.ephemeral?{ephemeral:!0}:{}}}sendUserText($,Z=[]){let J=Z.length?Z.map((Y)=>`[file: ${Y}]`).join(" ")+`
36
36
 
37
- `:"",Q=this.beginTurnStart();this.startTurn(J+$,Q).catch((Y)=>this.failTurnStart(Y,Q))}async listModels(){await this.ensureInitialized();let $=[],Z=null;do{let J=await this.request("model/list",{cursor:Z,limit:100,includeHidden:!1});if(!Array.isArray(J?.data))throw Error("model/list returned no data array");for(let Q of J.data){if(typeof Q?.model!=="string"||!Q.model)continue;$.push({id:typeof Q.id==="string"&&Q.id?Q.id:Q.model,model:Q.model,displayName:typeof Q.displayName==="string"&&Q.displayName?Q.displayName:Q.model,description:typeof Q.description==="string"?Q.description:"",hidden:Q.hidden===!0,isDefault:Q.isDefault===!0,supportedReasoningEfforts:eX(Q.supportedReasoningEfforts),defaultReasoningEffort:E$(Q.defaultReasoningEffort)?Q.defaultReasoningEffort:null})}Z=typeof J?.nextCursor==="string"&&J.nextCursor?J.nextCursor:null}while(Z);return $}async listConversations(){await this.ensureInitialized();let $=[],Z=new Set,J=null;do{let Q=await this.request("thread/list",{cursor:J,limit:100,sortKey:"updated_at",sortDirection:"desc",cwd:this.opts.workDir});if(!Array.isArray(Q?.data))throw Error("thread/list returned no data array");for(let H of Q.data){if(typeof H?.id!=="string"||!H.id||typeof H.preview!=="string"||typeof H.updatedAt!=="number"||!Number.isFinite(H.updatedAt)||typeof H.cwd!=="string"||H.cwd!==this.opts.workDir)throw Error("thread/list returned an invalid thread summary");let V=typeof H.status==="string"?H.status:typeof H.status?.type==="string"?H.status.type:void 0;$.push({provider:"codex",sessionId:H.id,cwd:H.cwd,preview:H.preview,ts:H.updatedAt*1000,...V?{status:V}:{}})}let Y=Q?.nextCursor;if(Y!==null&&typeof Y!=="string")throw Error("thread/list returned an invalid nextCursor");if(Y&&Z.has(Y))throw Error(`thread/list repeated pagination cursor ${Y}`);if(Y)Z.add(Y);J=Y}while(J);return $}async readConversationRef($){if(!$.trim())throw Error("thread/read requires a session id");await this.ensureInitialized();let J=(await this.request("thread/read",{threadId:$,includeTurns:!1}))?.thread;if(J?.id!==$||typeof J.cwd!=="string")throw Error("thread/read returned an invalid conversation reference");return{provider:"codex",sessionId:$,cwd:J.cwd}}async injectThreadItems($){if(!Array.isArray($)||$.length===0)return;if(!this.readyPromise)this.sendInitialize();if(await this.readyPromise,!this.sessionId)throw Error("codex thread not initialized");await this.request("thread/inject_items",{threadId:this.sessionId,items:$})}async setModelSettings($,Z){G("codex-process: setModelSettings no-op (codex model/effort governed by ~/.codex/config.toml)")}async setModel($){G("codex-process: setModel no-op (codex model governed by ~/.codex/config.toml)")}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;let J=$ instanceof Error?$.message:String($);G(`codex-process: turn/start failed: ${J}`),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,Q){let Y=typeof $?.id==="string"&&$.id?$.id:null;if(!Y)throw Error(`codex app-server ${J} returned no turn.id`);if(this.finishedTurnIds?.has(Y))return;this.confirmTurnStart(Y,Q);let H=this.currentTurnId!==Y;if(this.currentTurnId=Y,!H)return;this.lastCompletedTurnId=null,this.emit("turn_started",{turn_id:Y,thread_id:typeof Z==="string"&&Z?Z:this.sessionId})}beginTurnStart(){let $={generation:(this.turnStartGeneration??0)+1,turnId:null,confirmed:!1,terminal:!1};return this.turnStartGeneration=$.generation,this.turnStartOwner=$,$}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,!this.sessionId)throw Error("codex thread not initialized");let Q=await this.request("turn/start",{threadId:this.sessionId,input:[{type:"text",text:$,text_elements:[]}],cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandboxPolicy:tX(this.opts.sandbox??"danger-full-access",this.opts.workDir,this.opts.networkAccess===!0)});this.recordTurnStarted(Q?.turn,this.sessionId,"turn/start response",J)}catch(Q){if(!this.ownsTurnStartFailure(J)){G(`codex-process: ignored stale turn/start rejection generation=${J.generation}`);return}throw Q}}sendInterrupt(){if(!this.sessionId||!this.currentTurnId)return;this.request("turn/interrupt",{threadId:this.sessionId,turnId:this.currentTurnId}).catch(($)=>G(`codex-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Q=this.serverRequests.get(String($));if(!Q){G(`codex-process: permission response for unknown request ${$}`);return}let Y=Z==="allow";switch(Q.method){case"item/commandExecution/requestApproval":this.respond($,{decision:Y?"accept":"decline"});return;case"item/fileChange/requestApproval":this.respond($,{decision:Y?"accept":"decline"});return;case"item/permissions/requestApproval":if(Y)this.respond($,{permissions:Q.params?.permissions??{},scope:"session"});else this.respondError($,J?.denyMessage??"denied by user");return;case"item/tool/requestUserInput":{if(!Y){this.respondError($,J?.denyMessage??"denied by user");return}let H=J?.updatedInput?.answers??{},V={};for(let X of Q.params?.questions??[]){let W=H[X.question]??H[X.id];if(W!==void 0)V[X.id]={answers:[String(W)]}}this.respond($,{answers:V});return}default:M$("APPROVAL_RESPONSE_UNSUPPORTED",{requestId:$,method:Q.method,params:Q.params,decision:Z,payload:J}),this.respondError($,J?.denyMessage??"unsupported approval request")}}sendToolResult($,Z,J=!1){G("codex-process: sendToolResult ignored; Codex app-server server requests are answered via sendPermissionResponse")}sendHookResponse($,Z={}){this.respond($,Z)}isAlive(){return!this.exitEventEmitted}async kill($=5000){if(!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("; ")}`:"",Q=Error(`codex app-server did not exit after SIGTERM and SIGKILL (${$}ms each)${J}`);throw G(`codex-process: kill failed: ${Q.message}`),Q}sendSignal($,Z){try{if(!this.proc.kill($)&&this.alive)Z.push(`${$} was not delivered`)}catch(J){Z.push(`${$} failed: ${J instanceof Error?J.message:String(J)}`)}}async waitForExit($){if(this.exitEventEmitted)return!0;return new Promise((Z)=>{let J=!1,Q=(H)=>{if(J)return;J=!0,clearTimeout(Y),Z(H)},Y=setTimeout(()=>Q(!1),Math.max(0,$));this.exitPromise.then(()=>Q(!0))})}}});function XW($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function S6($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Q=0;while(Q<$.length){J.lastIndex=Q;let X=J.exec($);if(!X)break;let W=X[1],z=new RegExp(`^(?: {0,3})${XW(W[0])}{${W.length},}[ \\t]*(?:\\n|$)`,"gm");z.lastIndex=X.index+X[0].length;let K=z.exec($),_=K?K.index+K[0].length:$.length;Z.push({start:X.index,end:_}),Q=_}let Y=[...Z],H=[],V=0;for(let X of Z){if(V<X.start)H.push({start:V,end:X.start});V=X.end}if(V<$.length)H.push({start:V,end:$.length});for(let X of H){let W=$.slice(X.start,X.end),z=/(`+)[^\n]*?\1/g,K;while((K=z.exec(W))!==null)Y.push({start:X.start+K.index,end:X.start+K.index+K[0].length})}return Y.sort((X,W)=>X.start-W.start)}function w6($,Z){if(!$)return $;let J=S6($);if(!J.length)return Z($);let Q="",Y=0;for(let H of J){if(H.start>Y)Q+=Z($.slice(Y,H.start));Q+=$.slice(H.start,H.end),Y=Math.max(Y,H.end)}if(Y<$.length)Q+=Z($.slice(Y));return Q}function WW($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function x3($){return $.replace(/!\[([^\]]*)\]\(([^)]*)\)/g,(J,Q,Y)=>{let H=Y.trim();return Q.trim()?`\uD83D\uDDBC️ ${Q.trim()} (${H})`:`\uD83D\uDDBC️ ${H}`}).replace(/!\[/g,"\uD83D\uDDBC️ [")}function U0($){if(Array.isArray($))return $.map((Q)=>U0(Q));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Q,Y]of Object.entries(Z))J[Q]=U0(Y);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=f6(Z.content);return J}function a($){return w6($,(Z)=>zW(x3(WW(Z))))}function zW($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
37
+ `:"",Q=this.beginTurnStart();this.startTurn(J+$,Q).catch((Y)=>this.failTurnStart(Y,Q))}async listModels(){await this.ensureInitialized();let $=[],Z=null;do{let J=await this.request("model/list",{cursor:Z,limit:100,includeHidden:!1});if(!Array.isArray(J?.data))throw Error("model/list returned no data array");for(let Q of J.data){if(typeof Q?.model!=="string"||!Q.model)continue;$.push({id:typeof Q.id==="string"&&Q.id?Q.id:Q.model,model:Q.model,displayName:typeof Q.displayName==="string"&&Q.displayName?Q.displayName:Q.model,description:typeof Q.description==="string"?Q.description:"",hidden:Q.hidden===!0,isDefault:Q.isDefault===!0,supportedReasoningEfforts:JW(Q.supportedReasoningEfforts),defaultReasoningEffort:k$(Q.defaultReasoningEffort)?Q.defaultReasoningEffort:null})}Z=typeof J?.nextCursor==="string"&&J.nextCursor?J.nextCursor:null}while(Z);return $}async listConversations(){await this.ensureInitialized();let $=[],Z=new Set,J=null;do{let Q=await this.request("thread/list",{cursor:J,limit:100,sortKey:"updated_at",sortDirection:"desc",cwd:this.opts.workDir});if(!Array.isArray(Q?.data))throw Error("thread/list returned no data array");for(let H of Q.data){if(typeof H?.id!=="string"||!H.id||typeof H.preview!=="string"||typeof H.updatedAt!=="number"||!Number.isFinite(H.updatedAt)||typeof H.cwd!=="string"||H.cwd!==this.opts.workDir)throw Error("thread/list returned an invalid thread summary");let X=typeof H.status==="string"?H.status:typeof H.status?.type==="string"?H.status.type:void 0;$.push({provider:"codex",sessionId:H.id,cwd:H.cwd,preview:H.preview,ts:H.updatedAt*1000,...X?{status:X}:{}})}let Y=Q?.nextCursor;if(Y!==null&&typeof Y!=="string")throw Error("thread/list returned an invalid nextCursor");if(Y&&Z.has(Y))throw Error(`thread/list repeated pagination cursor ${Y}`);if(Y)Z.add(Y);J=Y}while(J);return $}async readConversationRef($){if(!$.trim())throw Error("thread/read requires a session id");await this.ensureInitialized();let J=(await this.request("thread/read",{threadId:$,includeTurns:!1}))?.thread;if(J?.id!==$||typeof J.cwd!=="string")throw Error("thread/read returned an invalid conversation reference");return{provider:"codex",sessionId:$,cwd:J.cwd}}async injectThreadItems($){if(!Array.isArray($)||$.length===0)return;if(!this.readyPromise)this.sendInitialize();if(await this.readyPromise,!this.sessionId)throw Error("codex thread not initialized");await this.request("thread/inject_items",{threadId:this.sessionId,items:$})}async setModelSettings($,Z){z("codex-process: setModelSettings no-op (codex model/effort governed by ~/.codex/config.toml)")}async setModel($){z("codex-process: setModel no-op (codex model governed by ~/.codex/config.toml)")}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)){z(`codex-process: ignored stale turn/start failure generation=${Z.generation}`);return}this.turnStartOwner=null;let J=$ instanceof Error?$.message:String($);z(`codex-process: turn/start failed: ${J}`),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,Q){let Y=typeof $?.id==="string"&&$.id?$.id:null;if(!Y)throw Error(`codex app-server ${J} returned no turn.id`);if(this.finishedTurnIds?.has(Y))return;this.confirmTurnStart(Y,Q);let H=this.currentTurnId!==Y;if(this.currentTurnId=Y,!H)return;this.lastCompletedTurnId=null,this.emit("turn_started",{turn_id:Y,thread_id:typeof Z==="string"&&Z?Z:this.sessionId})}beginTurnStart(){let $={generation:(this.turnStartGeneration??0)+1,turnId:null,confirmed:!1,terminal:!1};return this.turnStartGeneration=$.generation,this.turnStartOwner=$,$}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,!this.sessionId)throw Error("codex thread not initialized");let Q=await this.request("turn/start",{threadId:this.sessionId,input:[{type:"text",text:$,text_elements:[]}],cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandboxPolicy:$W(this.opts.sandbox??"danger-full-access",this.opts.workDir,this.opts.networkAccess===!0)});this.recordTurnStarted(Q?.turn,this.sessionId,"turn/start response",J)}catch(Q){if(!this.ownsTurnStartFailure(J)){z(`codex-process: ignored stale turn/start rejection generation=${J.generation}`);return}throw Q}}sendInterrupt(){if(!this.sessionId||!this.currentTurnId)return;this.request("turn/interrupt",{threadId:this.sessionId,turnId:this.currentTurnId}).catch(($)=>z(`codex-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Q=this.serverRequests.get(String($));if(!Q){z(`codex-process: permission response for unknown request ${$}`);return}let Y=Z==="allow";switch(Q.method){case"item/commandExecution/requestApproval":this.respond($,{decision:Y?"accept":"decline"});return;case"item/fileChange/requestApproval":this.respond($,{decision:Y?"accept":"decline"});return;case"item/permissions/requestApproval":if(Y)this.respond($,{permissions:Q.params?.permissions??{},scope:"session"});else this.respondError($,J?.denyMessage??"denied by user");return;case"item/tool/requestUserInput":{if(!Y){this.respondError($,J?.denyMessage??"denied by user");return}let H=J?.updatedInput?.answers??{},X={};for(let V of Q.params?.questions??[]){let W=H[V.question]??H[V.id];if(W!==void 0)X[V.id]={answers:[String(W)]}}this.respond($,{answers:X});return}default:M$("APPROVAL_RESPONSE_UNSUPPORTED",{requestId:$,method:Q.method,params:Q.params,decision:Z,payload:J}),this.respondError($,J?.denyMessage??"unsupported approval request")}}sendToolResult($,Z,J=!1){z("codex-process: sendToolResult ignored; Codex app-server server requests are answered via sendPermissionResponse")}sendHookResponse($,Z={}){this.respond($,Z)}isAlive(){return!this.exitEventEmitted}async kill($=5000){if(!this.alive){if(await this.waitForExit($))return;throw Error(`codex app-server exited but stdio did not close within ${$}ms`)}this.expectedExit=!0,z(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(z(`codex-process: SIGKILL (lifecycle not closed after ${$}ms)`),this.alive)this.sendSignal("SIGKILL",Z);if(await this.waitForExit($))return;let J=Z.length?`; ${Z.join("; ")}`:"",Q=Error(`codex app-server did not exit after SIGTERM and SIGKILL (${$}ms each)${J}`);throw z(`codex-process: kill failed: ${Q.message}`),Q}sendSignal($,Z){try{if(!this.proc.kill($)&&this.alive)Z.push(`${$} was not delivered`)}catch(J){Z.push(`${$} failed: ${J instanceof Error?J.message:String(J)}`)}}async waitForExit($){if(this.exitEventEmitted)return!0;return new Promise((Z)=>{let J=!1,Q=(H)=>{if(J)return;J=!0,clearTimeout(Y),Z(H)},Y=setTimeout(()=>Q(!1),Math.max(0,$));this.exitPromise.then(()=>Q(!0))})}}});function zW($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function w8($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Q=0;while(Q<$.length){J.lastIndex=Q;let V=J.exec($);if(!V)break;let W=V[1],G=new RegExp(`^(?: {0,3})${zW(W[0])}{${W.length},}[ \\t]*(?:\\n|$)`,"gm");G.lastIndex=V.index+V[0].length;let K=G.exec($),_=K?K.index+K[0].length:$.length;Z.push({start:V.index,end:_}),Q=_}let Y=[...Z],H=[],X=0;for(let V of Z){if(X<V.start)H.push({start:X,end:V.start});X=V.end}if(X<$.length)H.push({start:X,end:$.length});for(let V of H){let W=$.slice(V.start,V.end),G=/(`+)[^\n]*?\1/g,K;while((K=G.exec(W))!==null)Y.push({start:V.start+K.index,end:V.start+K.index+K[0].length})}return Y.sort((V,W)=>V.start-W.start)}function f8($,Z){if(!$)return $;let J=w8($);if(!J.length)return Z($);let Q="",Y=0;for(let H of J){if(H.start>Y)Q+=Z($.slice(Y,H.start));Q+=$.slice(H.start,H.end),Y=Math.max(Y,H.end)}if(Y<$.length)Q+=Z($.slice(Y));return Q}function KW($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function y5($){return $.replace(/!\[([^\]]*)\]\(([^)]*)\)/g,(J,Q,Y)=>{let H=Y.trim();return Q.trim()?`\uD83D\uDDBC️ ${Q.trim()} (${H})`:`\uD83D\uDDBC️ ${H}`}).replace(/!\[/g,"\uD83D\uDDBC️ [")}function U0($){if(Array.isArray($))return $.map((Q)=>U0(Q));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Q,Y]of Object.entries(Z))J[Q]=U0(Y);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=v8(Z.content);return J}function s($){return f8($,(Z)=>_W(y5(KW(Z))))}function _W($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
38
38
  \`\`\`
39
39
  ${J.trim()}
40
40
  \`\`\`
@@ -42,176 +42,178 @@ ${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 f6($){return w6($,x3)}var M;var x$=E(()=>{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",consultIdentityPanel:"consult_id_panel",consultRunFooter:"consult_run_footer"}});function N3($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function GW($,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 C3($){return $==="workflow"||$==="monitor"}function N$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function M0($){return $.some((Z)=>!N$(Z))}function I6($,Z,J=Date.now()){let Q=GW(Z.task_type,Z.subagent_type),Y=$.active.some((X)=>X.id===Z.task_id),H=$.pending.some((X)=>X.id===Z.task_id);if(Y||H){let X=(W)=>({...W,type:Q,toolUseId:Z.tool_use_id??W.toolUseId,description:Z.description||W.description,subagentType:Z.subagent_type??W.subagentType,workflowName:Z.workflow_name??W.workflowName,prompt:Z.prompt??W.prompt});return{active:Y?$.active.map((W)=>W.id===Z.task_id?X(W):W):$.active,pending:H?$.pending.map((W)=>W.id===Z.task_id?X(W):W):$.pending}}let V={id:Z.task_id,toolUseId:Z.tool_use_id,type:Q,description:Z.description,subagentType:Z.subagent_type,workflowName:Z.workflow_name,prompt:Z.prompt,status:"running",startedAt:J,steps:[],...C3(Q)?{isBackgrounded:!0}:{}};return C3(Q)?{active:[...$.active,V],pending:$.pending}:{active:$.active,pending:[...$.pending,V]}}function c6($,Z){let J=$.active.some((H)=>H.id===Z.task_id),Q=$.pending.some((H)=>H.id===Z.task_id);if(!J&&!Q)return $;let Y=(H)=>({...H,description:Z.description??H.description,subagentType:Z.subagent_type??H.subagentType,usage:Z.usage??H.usage,lastToolName:Z.last_tool_name??H.lastToolName,summary:Z.summary??H.summary,status:H.status==="pending"?"running":H.status});return{active:J?$.active.map((H)=>H.id===Z.task_id?Y(H):H):$.active,pending:Q?$.pending.map((H)=>H.id===Z.task_id?Y(H):H):$.pending}}function m6($,Z){let J=$.pending.findIndex((V)=>V.id===Z.task_id),Q=Z.patch;if(Q.is_backgrounded===!0&&J>=0){let V=$.pending[J],X={...V,isBackgrounded:!0,status:Q.status??V.status,description:Q.description??V.description,error:Q.error??V.error,endTime:Q.end_time??V.endTime};return{active:[...$.active,X],pending:$.pending.filter((W)=>W.id!==Z.task_id)}}let Y=$.active.some((V)=>V.id===Z.task_id),H=J>=0;if(Y||H){let V=(X)=>({...X,status:Q.status??X.status,description:Q.description??X.description,error:Q.error??X.error,isBackgrounded:Q.is_backgrounded??X.isBackgrounded,endTime:Q.end_time??X.endTime});return{active:Y?$.active.map((X)=>X.id===Z.task_id?V(X):X):$.active,pending:H?$.pending.map((X)=>X.id===Z.task_id?V(X):X):$.pending}}return $}function u6($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function p6($,Z,J=Date.now()){let Q=Z.status==="completed"?"completed":Z.status==="failed"?"failed":"killed";if($.pending.some((Y)=>Y.id===Z.task_id))return{active:$.active,pending:$.pending.filter((Y)=>Y.id!==Z.task_id)};if($.active.some((Y)=>Y.id===Z.task_id))return{active:$.active.map((Y)=>Y.id===Z.task_id?{...Y,status:Q,usage:Z.usage??Y.usage,summary:Z.summary??Y.summary,endTime:Y.endTime??J}:Y),pending:$.pending};return $}function B4($){let Z=0,J=0;for(let Q=$.length-1;Q>=0;Q--)if(Z+=$[Q].brief.length+5,Z>KW){J=Q+1;break}return J===0?$:$.slice(J)}function _W($,Z){let J=(Q)=>typeof Q==="string"?Q:"";switch($){case"Bash":return O1(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 qW($,Z){let J=($??"").replace(/\s+/g," ").trim();return Z?`❌ ${J.slice(0,80)}`:J.slice(0,80)}function l6($,Z,J,Q,Y){if(!Z)return $;let H=$.active.some((W)=>W.toolUseId===Z),V=$.pending.some((W)=>W.toolUseId===Z);if(!H&&!V)return $;let X=(W)=>W.map((z)=>z.toolUseId===Z?{...z,steps:B4([...z.steps,{toolUseId:J,tool:Q,brief:`${Q} ${_W(Q,Y)}`.trim()}])}:z);return{active:H?X($.active):$.active,pending:V?X($.pending):$.pending}}function i6($,Z,J,Q,Y,H){let V=$.active.some((z)=>z.id===Z),X=$.pending.some((z)=>z.id===Z);if(!V&&!X)return $;let W=(z)=>z.map((K)=>{if(K.id!==Z)return K;if(Y==="started")return{...K,steps:B4([...K.steps,{toolUseId:J,tool:Q,brief:`${Q} ${H}`.trim()}])};let _=!1,j=K.steps.map((B)=>{if(_||B.toolUseId!==J)return B;return _=!0,{...B,brief:H?`${B.brief} ${H}`:B.brief}});if(!_&&H)j.push({toolUseId:J,tool:Q,brief:`${Q} ${H}`.trim()});return{...K,steps:B4(j)}});return{active:V?W($.active):$.active,pending:X?W($.pending):$.pending}}function d6($,Z,J,Q,Y){if(!Z)return $;let H=$.active.some((W)=>W.toolUseId===Z),V=$.pending.some((W)=>W.toolUseId===Z);if(!H&&!V)return $;let X=(W)=>W.map((z)=>{if(z.toolUseId!==Z)return z;let K=!1,_=z.steps.map((j)=>{if(K||j.toolUseId!==J)return j;return K=!0,{...j,brief:`${j.brief} → ${qW(Q,Y)}`}});return{...z,steps:B4(_)}});return{active:H?X($.active):$.active,pending:V?X($.pending):$.pending}}function v6($){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 w3($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let H of LW)if(Z<H.limit)return{label:H.label,nextDelayMs:H.limit-Z};let J=600000,Q=Math.floor((Z-600000)/J),Y=600000+(Q+1)*J;return{label:`${(Q+1)*10}m+`,nextDelayMs:Y-Z}}function R0($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=h6){let Q=Math.floor((J-h6)/b3),Y=h6+(Q+1)*b3;return{label:`${10+Q*5}m+`,nextDelayMs:Y-J}}return{label:`${Math.floor(J/1000)}s`,nextDelayMs:S3}}return w3($)}function DW($){return $.subagentType??$.workflowName??BW[$.type]}function g6($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function PW($,Z,J="bucket"){let Q=(Y)=>R0(Y,J).label;switch($.status){case"running":return`\uD83D\uDFE1 运行中 (${Q(Z-$.startedAt)})`;case"paused":return`⏸️ 已暂停 (${Q(Z-$.startedAt)})`;case"pending":return"⚪ 等待中";case"completed":return`✅ 用时 ${v6(g6($))}`;case"failed":return`❌ 失败 ${v6(g6($))}`;case"killed":return`\uD83D\uDC80 已终止 ${v6(g6($))}`}}function f3($){let Z=$.filter((Q)=>!N$(Q)).length,J=$.length-Z;if(Z>0)return`${Z} 进行中${J?` · ${J} 已结束`:""}`;return J?`${J} 已结束`:"空"}function L4($){return`\uD83E\uDDED 后台任务 · ${f3($)}`}function FW($){let Z=[];if($.error)Z.push(`⚠ ${$.error}`);if(N$($)&&$.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 a(Z.length>0?Z.join(`
46
- `):"_(暂无执行记录)_")}function y1($,Z=Date.now(),J="bucket"){return{tag:"collapsible_panel",element_id:z2.panel($.id),header:{title:{tag:"plain_text",content:`${jW[$.type]} ${DW($)} · ${$.description||"(无描述)"} — ${PW($,Z,J)}`}},expanded:!1,elements:[{tag:"markdown",element_id:z2.body($.id),content:FW($)}]}}function n6($,Z=Date.now(),J="bucket"){return{schema:"2.0",config:{streaming_mode:!0,summary:{content:L4($)}},body:{elements:$.map((Q)=>y1(Q,Z,J))}}}function D4($,Z=Date.now(),J="bucket"){let Q=$.filter(N$);return{schema:"2.0",config:{streaming_mode:!1,summary:{content:`\uD83E\uDDED 后台任务(历史) · ${Q.length} 已结束`}},body:{elements:Q.map((Y)=>y1(Y,Z,J))}}}function o6(){return{schema:"2.0",config:{streaming_mode:!1,summary:{content:"↪ 后台任务进行中"}},body:{elements:[{tag:"markdown",element_id:"bg_marker",content:"↪ 本轮后台任务仍在进行,进度已迁至最新卡片"}]}}}var z2,KW=1000,jW,BW,LW,S3=1000,h6=600000,b3=300000;var a6=E(()=>{x$();G4();z2={panel:($)=>`bg_${N3($)}`,body:($)=>`bgb_${N3($)}`};jW={subagent:"\uD83D\uDFE2",shell:"⚙️",monitor:"\uD83D\uDCE1",workflow:"\uD83D\uDD01",unknown:"\uD83D\uDD39"},BW={subagent:"子agent",shell:"shell",monitor:"监控",workflow:"工作流",unknown:"任务"};LW=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});function o$($){return typeof $==="string"&&AW.includes($)}function E1($){return $?.startsWith("claude:")?"claude":"codex"}function H0($){return $==="claude"?"Claude":"Codex"}var AW,O0="max",G2;var c0=E(()=>{AW=["low","medium","high","xhigh","max"];G2=class G2 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}}});var I3={};F1(I3,{tokenSourceFactories:()=>N1,setDefaultTokenSource:()=>t6,scrubAnthropicEnv:()=>m0,resetTokenSourceRegistry:()=>s6,registerTokenSourceFactory:()=>V0,registerTokenSource:()=>r6,refreshAllTokenSourceModels:()=>p0,pendingTokenSourceModelRefresh:()=>e6,listTokenSourcesByAgent:()=>g3,listTokenSources:()=>u0,listEnabledTokenSourcesByAgent:()=>P4,getTokenSource:()=>Z$,defaultTokenSourceId:()=>MW});function m0($){let Z={...$};for(let J of UW)delete Z[J];return Z}function V0($){v3.set($.kind,$)}function N1(){return[...v3.values()]}function r6($,Z){if(_2.set($.id,$),Z?.default||K2===null)K2=$.id}function Z$($){return $?_2.get($):void 0}function u0(){return[..._2.values()]}function g3($){return u0().filter((Z)=>Z.agent===$)}function P4($){return g3($).filter((Z)=>Z.enabled)}function MW(){return K2}function t6($){if(_2.has($))K2=$}function s6(){_2.clear(),K2=null,h3++}function p0(){let $=h3;if(x1?.generation===$)return x1.promise;let Z=Promise.allSettled(u0().map(async(J)=>{await J.refreshModels(),G(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(x1?.promise===Z)x1=null});return x1={generation:$,promise:Z},Z}function e6(){return x1?.promise??null}var UW,v3,_2,K2=null,h3=0,x1=null;var A$=E(()=>{w();UW=["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","ANTHROPIC_DEFAULT_OPUS_MODEL","ANTHROPIC_DEFAULT_SONNET_MODEL","ANTHROPIC_DEFAULT_HAIKU_MODEL"];v3=new Map;_2=new Map});import{exec as RW}from"node:child_process";function m3(){RW(`systemctl --user stop ${c3}.timer ${c3}.service 2>/dev/null`,()=>{})}var c3="cc-feishu-rollback-watchdog";var u3=()=>{};function OW($){return{...p3[$]??{},...S.claude.models[$]??{}}}function TW($){let Z=OW($);return{key:`claude:${$}`,name:$,displayName:Z.display_name?.trim()||`Claude Code · ${$}`,description:Z.description?.trim()||`使用 ${$} 路由运行 Claude Code 后端。`,sdkModel:Z.model?.trim()||"opus"}}function kW(){return[...new Set([...Object.keys(p3),...Object.keys(S.claude.models)])].map(TW).filter((Z)=>Z!==null)}function yW($){if(!$?.startsWith("claude:"))return null;let Z=$.slice(7);if(!Z||Z==="default")return null;return kW().find((J)=>J.name===Z||J.key===$)??null}function T0($){return $.startsWith("claude:")?$:`claude:${$}`}function $8($){if(!$)return"opus";let Z=yW($);if(Z)return Z.sdkModel;let J=$.startsWith("claude:")?$.slice(7):$;return J==="default"?"opus":J}var p3;var l3=E(()=>{y$();p3={glm:{display_name:"Claude Code · GLM",description:"使用 GLM 路由,适合中文交流和通用编码任务。"}}});import{existsSync as EW,readFileSync as xW}from"node:fs";function Z8(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:c5}function j2(){if(q2!==null)return q2;try{q2=EW(Z8())?JSON.parse(xW(Z8(),"utf8")):{}}catch($){G(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),q2={}}return q2??{}}function bW(){try{V$(Z8(),j2())}catch($){G(`context-window-observe: cache write MISS (${$?.message??$})`)}}function J8($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function Q8($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Q=J8($,Z),Y=j2()[Q];if(Y===J)return;j2()[Q]=J,bW(),G(`context-window-observe: ${Q} → ${J} (prev ${Y??"-"})`)}function i3($,Z){Q8($,Z,CW)}function F4($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=j2()[J8($,Z)];return J!=null&&J<NW?Z:`${Z}[1m]`}function A4($,Z){return j2()[J8($,Z)]}var NW=1e6,CW=200000,q2=null;var U4=E(()=>{D$();w();h$()});import{existsSync as R4,readFileSync as ZZ,realpathSync as d3}from"node:fs";import{homedir as L2}from"node:os";import{spawn as SW}from"cross-spawn";import{delimiter as n3,isAbsolute as JZ,join as l0,posix as wW,relative as fW,resolve as vW,sep as hW,win32 as gW}from"node:path";import{EventEmitter as IW}from"node:events";import{query as cW}from"@anthropic-ai/claude-agent-sdk";function o3($){return $?{"safe-mode":null}:void 0}function mW($,Z,J=!1){if(!Z||J||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function uW($,Z,J,Q,Y=[]){if(Y.includes($))return{allowed:!0};if(!["Read","Grep","Glob"].includes($))return{allowed:!1,message:`consult reviewer tool is not allowed: ${$}`};if(Q.length===0)return{allowed:!1,message:"consult reviewer has no readable project root"};if($==="Glob"){let W=Z.pattern;if(typeof W!=="string"||!W||pW(W))return{allowed:!1,message:"consult reviewer Glob pattern escapes the project root"}}let H=$==="Read"?Z.file_path:Z.path??J;if(typeof H!=="string"||!H)return{allowed:!1,message:`consult reviewer ${$} path is missing`};let V,X;try{V=d3(vW(J,H)),X=Q.map((W)=>d3(W))}catch(W){return{allowed:!1,message:`consult reviewer path cannot be resolved: ${W instanceof Error?W.message:String(W)}`}}if(X.some((W)=>lW(V,W)))return{allowed:!0};return{allowed:!1,message:`consult reviewer read is outside the project root: ${H}`}}function pW($){if(JZ($)||$.startsWith("~"))return!0;return $.replaceAll("\\","/").split("/").includes("..")}function lW($,Z){let J=fW(Z,$);return J===""||!JZ(J)&&J!==".."&&!J.startsWith(`..${hW}`)}function iW($){return $==="win32"?";":":"}function H8($,...Z){return $==="win32"?gW.join(...Z):wW.join(...Z)}function a3($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function r3($){let Z=SW($.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 YZ($={}){let Z=$.platform??process.platform,J=$.exists??R4,Q=$.homeDir??L2();if(Z!=="win32"){let H=[H8(Z,Q,".local","npm-global","bin","claude"),H8(Z,Q,".local","bin","claude")];for(let V of H)if(J(V))return V}let Y=nW($);if(Y)return Y;return null}function HZ(){YZ()}function dW($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?S.claude.bin:$.configuredBin;if(J){if(!($.exists??R4)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&a3(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:r3,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}let Q=YZ($);if(!Q)return{description:"sdk-default"};if(Z==="win32"&&a3(Q))return{pathToClaudeCodeExecutable:Q,spawnClaudeCodeProcess:r3,description:`windows-shell-shim:${Q}`};return{description:"sdk-default"}}function nW($={}){let Z=$.platform??process.platform,J=$.pathEnv??process.env.PATH??"";if(!J)return null;let Q=$.exists??R4,Y=Z==="win32"?["claude.exe","claude.cmd","claude.bat","claude"]:["claude"];for(let H of J.split(iW(Z))){if(!H)continue;for(let V of Y){let X=H8(Z,H,V);if(Q(X))return X}}return null}function t3(){if(process.platform==="win32")return process.env.PATH??"";let $=[l0(L2(),".local","npm-global","bin"),l0(L2(),".local","bin"),l0(L2(),".bun","bin"),...(process.env.PATH??"").split(n3),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(n3)}function oW($){let Z=R1($);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 s3($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function X8($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||l0(L2(),".claude");return l0(J,"projects",Z)}function W8($,Z){return l0(X8($),`${Z}.jsonl`)}function aW($){let Z;try{Z=ZZ($,"utf8")}catch{return null}let J=Z.split(`
47
- `);for(let Q=J.length-1;Q>=0;Q--){let Y=J[Q].trim();if(!Y)continue;try{let H=JSON.parse(Y);if(H?.type==="assistant"&&H?.message?.usage){let V=H.message.usage;if((V.input_tokens??0)+(V.cache_read_input_tokens??0)+(V.cache_creation_input_tokens??0)+(V.output_tokens??0)>0)return V}}catch{}}return null}function e3($,Z){let J=Z?.trim()||"no-source",Q=$&&$.trim()?$:"claude:default";return`${J}:${Q}`}function rW($){if(!$||typeof $!=="object")return{usage:null,contextWindow:null};let Z={},J=null;for(let Y of Object.values($)){if(!Y||typeof Y!=="object")continue;let H=Y;Z.input_tokens=(Z.input_tokens??0)+C1(H.inputTokens??H.input_tokens),Z.output_tokens=(Z.output_tokens??0)+C1(H.outputTokens??H.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+C1(H.reasoningOutputTokens??H.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+C1(H.cacheReadInputTokens??H.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+C1(H.cacheCreationInputTokens??H.cache_creation_input_tokens);let V=C1(H.contextWindow??H.context_window);if(V>0)J=Math.max(J??0,V)}let Q=(Z.input_tokens??0)+(Z.output_tokens??0)+(Z.cache_creation_input_tokens??0)+(Z.cache_read_input_tokens??0);if(Q<=0)return{usage:null,contextWindow:J};return Z.total_tokens=Q,{usage:Z,contextWindow:J}}function M4($){return{...$}}function Y8($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function tW($,Z){let J=$?{...$}:{},Q=(Y)=>{let H=Z[Y];if(typeof H!=="number"||!Number.isFinite(H))return;J[Y]=(J[Y]??0)+H};return Q("total_tokens"),Q("input_tokens"),Q("output_tokens"),Q("reasoning_output_tokens"),Q("cache_creation_input_tokens"),Q("cache_read_input_tokens"),J}function C1($){return typeof $==="number"&&Number.isFinite($)?$:0}function VZ($){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 sW($){let Z=VZ($);try{let J=JSON.parse(Z);if(Array.isArray(J)){let Q=J.map((Y)=>{if(typeof Y==="string")return Y;if(Y&&typeof Y==="object"&&typeof Y.text==="string")return Y.text;return JSON.stringify(Y)}).filter(Boolean);if(Q.length>0)return Q.join(`
49
- `)}}catch{}return Z}function eW($){return`server_tool:${$}`}function $z($){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 Zz($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function Jz($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[O0];return{id:T0($.value),model:T0($.value),displayName:$.displayName||T0($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(O0)?O0:Z[0]}}function Yz($){if(!$?.settingSources)return[...$Z];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...$Z]}function Hz($){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 Vz($){let Z=l0($,".mcp.json"),J;try{J=ZZ(Z,"utf8")}catch(Q){if(Q.code!=="ENOENT")G(`claude-agent-process: project .mcp.json not readable at ${Z}: ${Q}`);return}try{let Q=JSON.parse(J);if(Q&&typeof Q==="object"&&Q.mcpServers&&typeof Q.mcpServers==="object")return Q.mcpServers;G(`claude-agent-process: project .mcp.json has no mcpServers object at ${Z}`);return}catch(Q){G(`claude-agent-process: project .mcp.json parse failed at ${Z}: ${Q}`);return}}function Xz($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Q)=>Wz(Q)).filter((Q)=>Q!==null)}function Wz($){let Z=$&&typeof $==="object"?$:{question:$},J=V8(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Q=zz(Z.options??Z.choices??Z.suggestions);return{...Z,question:J,options:Q,...typeof Z.header==="string"?{header:Z.header}:{},...typeof Z.multiSelect==="boolean"?{multiSelect:Z.multiSelect}:{}}}function zz($){if(!Array.isArray($))return[];let Z=[];for(let J of $){if(typeof J==="string"){Z.push({label:J});continue}if(!J||typeof J!=="object")continue;let Q=J,Y=V8(Q.label,Q.value,Q.text,Q.title);if(!Y?.trim())continue;let H=V8(Q.description,Q.detail,Q.preview);Z.push(H?{label:Y,description:H}:{label:Y})}return Z}function V8(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var QZ,B2,Qz="default",$Z,D2;var O4=E(()=>{y$();w();c0();l3();U4();QZ=class QZ{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($))}};B2=new Map;$Z=["project","local"];D2=class D2 extends IW{provider="claude";tokenSourceId;opts;input=new QZ;query=null;abortController=new AbortController;alive=!0;expectedExit=!1;exitPromise;resolveExit;started=!1;pendingPermissions=new Map;pendingInjectedContext=[];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?T0($.model):null}sendInitialize(){if(this.started)return;this.started=!0;let $=$8(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??Yz(Z),Q=mW(J,this.opts.managedSkillPluginPath,this.opts.safeMode===!0),Y=Hz(Z),H=Z?.strictMcp===!0,V=Z?.loadProjectMcp!==!1?Vz(this.opts.workDir):void 0;try{let X=dW();G(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${X.description}`),this.query=cW({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}:{},...o3(this.opts.safeMode)?{extraArgs:o3(this.opts.safeMode)}:{},...X.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:X.pathToClaudeCodeExecutable}:{},...X.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:X.spawnClaudeCodeProcess}:{},permissionMode:Qz,env:this.opts.transformEnv?this.opts.transformEnv({...process.env,PATH:t3(),...S.claude.env,...this.opts.hostEnv??{}}):{...process.env,PATH:t3(),...S.claude.env,...this.opts.hostEnv??{}},settingSources:[...J],...Q,tools:Y,...H?{strictMcpConfig:!0}:{},...V?{mcpServers:V}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(W,z,K)=>this.canUseTool(W,z,K),includePartialMessages:!1,systemPrompt:this.opts.systemPrompt??{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(W)=>{let z=W.trim();if(z)G(`claude-agent-process[stderr]: ${z}`)}}})}catch(X){let W=X instanceof Error?X:Error(String(X));this.emit("error",W),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 v8($){return f8($,y5)}var M;var x$=k(()=>{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",consultIdentityPanel:"consult_id_panel",consultRunFooter:"consult_run_footer"}});function C5($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function qW($,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 S5($){return $==="workflow"||$==="monitor"}function y$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function g0($){return $.some((Z)=>!y$(Z))}function c8($,Z,J=Date.now()){let Q=qW(Z.task_type,Z.subagent_type),Y=$.active.some((V)=>V.id===Z.task_id),H=$.pending.some((V)=>V.id===Z.task_id);if(Y||H){let V=(W)=>({...W,type:Q,toolUseId:Z.tool_use_id??W.toolUseId,description:Z.description||W.description,subagentType:Z.subagent_type??W.subagentType,workflowName:Z.workflow_name??W.workflowName,prompt:Z.prompt??W.prompt});return{active:Y?$.active.map((W)=>W.id===Z.task_id?V(W):W):$.active,pending:H?$.pending.map((W)=>W.id===Z.task_id?V(W):W):$.pending}}let X={id:Z.task_id,toolUseId:Z.tool_use_id,type:Q,description:Z.description,subagentType:Z.subagent_type,workflowName:Z.workflow_name,prompt:Z.prompt,status:"running",startedAt:J,steps:[],...S5(Q)?{isBackgrounded:!0}:{}};return S5(Q)?{active:[...$.active,X],pending:$.pending}:{active:$.active,pending:[...$.pending,X]}}function m8($,Z){let J=$.active.some((H)=>H.id===Z.task_id),Q=$.pending.some((H)=>H.id===Z.task_id);if(!J&&!Q)return $;let Y=(H)=>({...H,description:Z.description??H.description,subagentType:Z.subagent_type??H.subagentType,usage:Z.usage??H.usage,lastToolName:Z.last_tool_name??H.lastToolName,summary:Z.summary??H.summary,status:H.status==="pending"?"running":H.status});return{active:J?$.active.map((H)=>H.id===Z.task_id?Y(H):H):$.active,pending:Q?$.pending.map((H)=>H.id===Z.task_id?Y(H):H):$.pending}}function u8($,Z){let J=$.pending.findIndex((X)=>X.id===Z.task_id),Q=Z.patch;if(Q.is_backgrounded===!0&&J>=0){let X=$.pending[J],V={...X,isBackgrounded:!0,status:Q.status??X.status,description:Q.description??X.description,error:Q.error??X.error,endTime:Q.end_time??X.endTime};return{active:[...$.active,V],pending:$.pending.filter((W)=>W.id!==Z.task_id)}}let Y=$.active.some((X)=>X.id===Z.task_id),H=J>=0;if(Y||H){let X=(V)=>({...V,status:Q.status??V.status,description:Q.description??V.description,error:Q.error??V.error,isBackgrounded:Q.is_backgrounded??V.isBackgrounded,endTime:Q.end_time??V.endTime});return{active:Y?$.active.map((V)=>V.id===Z.task_id?X(V):V):$.active,pending:H?$.pending.map((V)=>V.id===Z.task_id?X(V):V):$.pending}}return $}function p8($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function l8($,Z,J=Date.now()){let Q=Z.status==="completed"?"completed":Z.status==="failed"?"failed":"killed";if($.pending.some((Y)=>Y.id===Z.task_id))return{active:$.active,pending:$.pending.filter((Y)=>Y.id!==Z.task_id)};if($.active.some((Y)=>Y.id===Z.task_id))return{active:$.active.map((Y)=>Y.id===Z.task_id?{...Y,status:Q,usage:Z.usage??Y.usage,summary:Z.summary??Y.summary,endTime:Y.endTime??J}:Y),pending:$.pending};return $}function j4($){let Z=0,J=0;for(let Q=$.length-1;Q>=0;Q--)if(Z+=$[Q].brief.length+5,Z>BW){J=Q+1;break}return J===0?$:$.slice(J)}function jW($,Z){let J=(Q)=>typeof Q==="string"?Q:"";switch($){case"Bash":return O1(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 LW($,Z){let J=($??"").replace(/\s+/g," ").trim();return Z?`❌ ${J.slice(0,80)}`:J.slice(0,80)}function d8($,Z,J,Q,Y){if(!Z)return $;let H=$.active.some((W)=>W.toolUseId===Z),X=$.pending.some((W)=>W.toolUseId===Z);if(!H&&!X)return $;let V=(W)=>W.map((G)=>G.toolUseId===Z?{...G,steps:j4([...G.steps,{toolUseId:J,tool:Q,brief:`${Q} ${jW(Q,Y)}`.trim()}])}:G);return{active:H?V($.active):$.active,pending:X?V($.pending):$.pending}}function i8($,Z,J,Q,Y,H){let X=$.active.some((G)=>G.id===Z),V=$.pending.some((G)=>G.id===Z);if(!X&&!V)return $;let W=(G)=>G.map((K)=>{if(K.id!==Z)return K;if(Y==="started")return{...K,steps:j4([...K.steps,{toolUseId:J,tool:Q,brief:`${Q} ${H}`.trim()}])};let _=!1,B=K.steps.map((j)=>{if(_||j.toolUseId!==J)return j;return _=!0,{...j,brief:H?`${j.brief} ${H}`:j.brief}});if(!_&&H)B.push({toolUseId:J,tool:Q,brief:`${Q} ${H}`.trim()});return{...K,steps:j4(B)}});return{active:X?W($.active):$.active,pending:V?W($.pending):$.pending}}function n8($,Z,J,Q,Y){if(!Z)return $;let H=$.active.some((W)=>W.toolUseId===Z),X=$.pending.some((W)=>W.toolUseId===Z);if(!H&&!X)return $;let V=(W)=>W.map((G)=>{if(G.toolUseId!==Z)return G;let K=!1,_=G.steps.map((B)=>{if(K||B.toolUseId!==J)return B;return K=!0,{...B,brief:`${B.brief} → ${LW(Q,Y)}`}});return{...G,steps:j4(_)}});return{active:H?V($.active):$.active,pending:X?V($.pending):$.pending}}function h8($){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 f5($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let H of FW)if(Z<H.limit)return{label:H.label,nextDelayMs:H.limit-Z};let J=600000,Q=Math.floor((Z-600000)/J),Y=600000+(Q+1)*J;return{label:`${(Q+1)*10}m+`,nextDelayMs:Y-Z}}function M0($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=I8){let Q=Math.floor((J-I8)/b5),Y=I8+(Q+1)*b5;return{label:`${10+Q*5}m+`,nextDelayMs:Y-J}}return{label:`${Math.floor(J/1000)}s`,nextDelayMs:w5}}return f5($)}function PW($){return $.subagentType??$.workflowName??AW[$.type]}function g8($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function UW($,Z,J="bucket"){let Q=(Y)=>M0(Y,J).label;switch($.status){case"running":return`\uD83D\uDFE1 运行中 (${Q(Z-$.startedAt)})`;case"paused":return`⏸️ 已暂停 (${Q(Z-$.startedAt)})`;case"pending":return"⚪ 等待中";case"completed":return`✅ 用时 ${h8(g8($))}`;case"failed":return`❌ 失败 ${h8(g8($))}`;case"killed":return`\uD83D\uDC80 已终止 ${h8(g8($))}`}}function v5($){let Z=$.filter((Q)=>!y$(Q)).length,J=$.length-Z;if(Z>0)return`${Z} 进行中${J?` · ${J} 已结束`:""}`;return J?`${J} 已结束`:"空"}function L4($){return`\uD83E\uDDED 后台任务 · ${v5($)}`}function MW($){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 N1($,Z=Date.now(),J="bucket"){return{tag:"collapsible_panel",element_id:G2.panel($.id),header:{title:{tag:"plain_text",content:`${DW[$.type]} ${PW($)} · ${$.description||"(无描述)"} — ${UW($,Z,J)}`}},expanded:!1,elements:[{tag:"markdown",element_id:G2.body($.id),content:MW($)}]}}function o8($,Z=Date.now(),J="bucket"){return{schema:"2.0",config:{streaming_mode:!0,summary:{content:L4($)}},body:{elements:$.map((Q)=>N1(Q,Z,J))}}}function D4($,Z=Date.now(),J="bucket"){let Q=$.filter(y$);return{schema:"2.0",config:{streaming_mode:!1,summary:{content:`\uD83E\uDDED 后台任务(历史) · ${Q.length} 已结束`}},body:{elements:Q.map((Y)=>N1(Y,Z,J))}}}function a8(){return{schema:"2.0",config:{streaming_mode:!1,summary:{content:"↪ 后台任务进行中"}},body:{elements:[{tag:"markdown",element_id:"bg_marker",content:"↪ 本轮后台任务仍在进行,进度已迁至最新卡片"}]}}}var G2,BW=1000,DW,AW,FW,w5=1000,I8=600000,b5=300000;var r8=k(()=>{x$();z4();G2={panel:($)=>`bg_${C5($)}`,body:($)=>`bgb_${C5($)}`};DW={subagent:"\uD83D\uDFE2",shell:"⚙️",monitor:"\uD83D\uDCE1",workflow:"\uD83D\uDD01",unknown:"\uD83D\uDD39"},AW={subagent:"子agent",shell:"shell",monitor:"监控",workflow:"工作流",unknown:"任务"};FW=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});function o$($){return typeof $==="string"&&RW.includes($)}function k1($){return $?.startsWith("claude:")?"claude":"codex"}function H0($){return $==="claude"?"Claude":"Codex"}var RW,R0="max",z2;var c0=k(()=>{RW=["low","medium","high","xhigh","max"];z2=class z2 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}}});var c5={};F1(c5,{tokenSourceFactories:()=>y1,setDefaultTokenSource:()=>s8,scrubAnthropicEnv:()=>m0,resetTokenSourceRegistry:()=>e8,registerTokenSourceFactory:()=>X0,registerTokenSource:()=>t8,refreshAllTokenSourceModels:()=>p0,pendingTokenSourceModelRefresh:()=>$6,listTokenSourcesByAgent:()=>g5,listTokenSources:()=>u0,listEnabledTokenSourcesByAgent:()=>A4,getTokenSource:()=>Z$,defaultTokenSourceId:()=>TW});function m0($){let Z={...$};for(let J of OW)delete Z[J];return Z}function X0($){h5.set($.kind,$)}function y1(){return[...h5.values()]}function t8($,Z){if(_2.set($.id,$),Z?.default||K2===null)K2=$.id}function Z$($){return $?_2.get($):void 0}function u0(){return[..._2.values()]}function g5($){return u0().filter((Z)=>Z.agent===$)}function A4($){return g5($).filter((Z)=>Z.enabled)}function TW(){return K2}function s8($){if(_2.has($))K2=$}function e8(){_2.clear(),K2=null,I5++}function p0(){let $=I5;if(x1?.generation===$)return x1.promise;let Z=Promise.allSettled(u0().map(async(J)=>{await J.refreshModels(),z(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(x1?.promise===Z)x1=null});return x1={generation:$,promise:Z},Z}function $6(){return x1?.promise??null}var OW,h5,_2,K2=null,I5=0,x1=null;var P$=k(()=>{w();OW=["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","ANTHROPIC_DEFAULT_OPUS_MODEL","ANTHROPIC_DEFAULT_SONNET_MODEL","ANTHROPIC_DEFAULT_HAIKU_MODEL"];h5=new Map;_2=new Map});import{exec as EW}from"node:child_process";function u5(){EW(`systemctl --user stop ${m5}.timer ${m5}.service 2>/dev/null`,()=>{})}var m5="cc-feishu-rollback-watchdog";var p5=()=>{};function NW($){return{...l5[$]??{},...b.claude.models[$]??{}}}function kW($){let Z=NW($);return{key:`claude:${$}`,name:$,displayName:Z.display_name?.trim()||`Claude Code · ${$}`,description:Z.description?.trim()||`使用 ${$} 路由运行 Claude Code 后端。`,sdkModel:Z.model?.trim()||"opus"}}function xW(){return[...new Set([...Object.keys(l5),...Object.keys(b.claude.models)])].map(kW).filter((Z)=>Z!==null)}function yW($){if(!$?.startsWith("claude:"))return null;let Z=$.slice(7);if(!Z||Z==="default")return null;return xW().find((J)=>J.name===Z||J.key===$)??null}function O0($){return $.startsWith("claude:")?$:`claude:${$}`}function Z6($){if(!$)return"opus";let Z=yW($);if(Z)return Z.sdkModel;let J=$.startsWith("claude:")?$.slice(7):$;return J==="default"?"opus":J}var l5;var d5=k(()=>{N$();l5={glm:{display_name:"Claude Code · GLM",description:"使用 GLM 路由,适合中文交流和通用编码任务。"}}});import{existsSync as CW,readFileSync as SW}from"node:fs";function J6(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:m3}function B2(){if(q2!==null)return q2;try{q2=CW(J6())?JSON.parse(SW(J6(),"utf8")):{}}catch($){z(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),q2={}}return q2??{}}function fW(){try{X$(J6(),B2())}catch($){z(`context-window-observe: cache write MISS (${$?.message??$})`)}}function Q6($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function Y6($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Q=Q6($,Z),Y=B2()[Q];if(Y===J)return;B2()[Q]=J,fW(),z(`context-window-observe: ${Q} → ${J} (prev ${Y??"-"})`)}function i5($,Z){Y6($,Z,wW)}function F4($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=B2()[Q6($,Z)];return J!=null&&J<bW?Z:`${Z}[1m]`}function P4($,Z){return B2()[Q6($,Z)]}var bW=1e6,wW=200000,q2=null;var U4=k(()=>{D$();w();h$()});import{existsSync as R4,readFileSync as JZ,realpathSync as n5}from"node:fs";import{homedir as L2}from"node:os";import{spawn as vW}from"cross-spawn";import{delimiter as o5,isAbsolute as QZ,join as l0,posix as hW,relative as IW,resolve as gW,sep as cW,win32 as mW}from"node:path";import{EventEmitter as uW}from"node:events";import{query as pW}from"@anthropic-ai/claude-agent-sdk";function a5($){return $?{"safe-mode":null}:void 0}function lW($,Z,J=!1){if(!Z||J||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function dW($,Z,J,Q,Y=[]){if(Y.includes($))return{allowed:!0};if(!["Read","Grep","Glob"].includes($))return{allowed:!1,message:`consult reviewer tool is not allowed: ${$}`};if(Q.length===0)return{allowed:!1,message:"consult reviewer has no readable project root"};if($==="Glob"){let W=Z.pattern;if(typeof W!=="string"||!W||iW(W))return{allowed:!1,message:"consult reviewer Glob pattern escapes the project root"}}let H=$==="Read"?Z.file_path:Z.path??J;if(typeof H!=="string"||!H)return{allowed:!1,message:`consult reviewer ${$} path is missing`};let X,V;try{X=n5(gW(J,H)),V=Q.map((W)=>n5(W))}catch(W){return{allowed:!1,message:`consult reviewer path cannot be resolved: ${W instanceof Error?W.message:String(W)}`}}if(V.some((W)=>nW(X,W)))return{allowed:!0};return{allowed:!1,message:`consult reviewer read is outside the project root: ${H}`}}function iW($){if(QZ($)||$.startsWith("~"))return!0;return $.replaceAll("\\","/").split("/").includes("..")}function nW($,Z){let J=IW(Z,$);return J===""||!QZ(J)&&J!==".."&&!J.startsWith(`..${cW}`)}function oW($){return $==="win32"?";":":"}function X6($,...Z){return $==="win32"?mW.join(...Z):hW.join(...Z)}function r5($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function t5($){let Z=vW($.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 HZ($={}){let Z=$.platform??process.platform,J=$.exists??R4,Q=$.homeDir??L2();if(Z!=="win32"){let H=[X6(Z,Q,".local","npm-global","bin","claude"),X6(Z,Q,".local","bin","claude")];for(let X of H)if(J(X))return X}let Y=rW($);if(Y)return Y;return null}function XZ(){HZ()}function aW($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?b.claude.bin:$.configuredBin;if(J){if(!($.exists??R4)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&r5(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:t5,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}let Q=HZ($);if(!Q)return{description:"sdk-default"};if(Z==="win32"&&r5(Q))return{pathToClaudeCodeExecutable:Q,spawnClaudeCodeProcess:t5,description:`windows-shell-shim:${Q}`};return{description:"sdk-default"}}function rW($={}){let Z=$.platform??process.platform,J=$.pathEnv??process.env.PATH??"";if(!J)return null;let Q=$.exists??R4,Y=Z==="win32"?["claude.exe","claude.cmd","claude.bat","claude"]:["claude"];for(let H of J.split(oW(Z))){if(!H)continue;for(let X of Y){let V=X6(Z,H,X);if(Q(V))return V}}return null}function s5(){if(process.platform==="win32")return process.env.PATH??"";let $=[l0(L2(),".local","npm-global","bin"),l0(L2(),".local","bin"),l0(L2(),".bun","bin"),...(process.env.PATH??"").split(o5),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(o5)}function tW($){let Z=R1($);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 e5($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function W6($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||l0(L2(),".claude");return l0(J,"projects",Z)}function G6($,Z){return l0(W6($),`${Z}.jsonl`)}function sW($){let Z;try{Z=JZ($,"utf8")}catch{return null}let J=Z.split(`
47
+ `);for(let Q=J.length-1;Q>=0;Q--){let Y=J[Q].trim();if(!Y)continue;try{let H=JSON.parse(Y);if(H?.type==="assistant"&&H?.message?.usage){let X=H.message.usage;if((X.input_tokens??0)+(X.cache_read_input_tokens??0)+(X.cache_creation_input_tokens??0)+(X.output_tokens??0)>0)return X}}catch{}}return null}function $Z($,Z){let J=Z?.trim()||"no-source",Q=$&&$.trim()?$:"claude:default";return`${J}:${Q}`}function eW($){if(!$||typeof $!=="object")return{usage:null,contextWindow:null};let Z={},J=null;for(let Y of Object.values($)){if(!Y||typeof Y!=="object")continue;let H=Y;Z.input_tokens=(Z.input_tokens??0)+C1(H.inputTokens??H.input_tokens),Z.output_tokens=(Z.output_tokens??0)+C1(H.outputTokens??H.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+C1(H.reasoningOutputTokens??H.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+C1(H.cacheReadInputTokens??H.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+C1(H.cacheCreationInputTokens??H.cache_creation_input_tokens);let X=C1(H.contextWindow??H.context_window);if(X>0)J=Math.max(J??0,X)}let Q=(Z.input_tokens??0)+(Z.output_tokens??0)+(Z.cache_creation_input_tokens??0)+(Z.cache_read_input_tokens??0);if(Q<=0)return{usage:null,contextWindow:J};return Z.total_tokens=Q,{usage:Z,contextWindow:J}}function M4($){return{...$}}function H6($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function $G($,Z){let J=$?{...$}:{},Q=(Y)=>{let H=Z[Y];if(typeof H!=="number"||!Number.isFinite(H))return;J[Y]=(J[Y]??0)+H};return Q("total_tokens"),Q("input_tokens"),Q("output_tokens"),Q("reasoning_output_tokens"),Q("cache_creation_input_tokens"),Q("cache_read_input_tokens"),J}function C1($){return typeof $==="number"&&Number.isFinite($)?$:0}function VZ($){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 ZG($){let Z=VZ($);try{let J=JSON.parse(Z);if(Array.isArray(J)){let Q=J.map((Y)=>{if(typeof Y==="string")return Y;if(Y&&typeof Y==="object"&&typeof Y.text==="string")return Y.text;return JSON.stringify(Y)}).filter(Boolean);if(Q.length>0)return Q.join(`
49
+ `)}}catch{}return Z}function JG($){return`server_tool:${$}`}function QG($){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 YG($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function HG($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[R0];return{id:O0($.value),model:O0($.value),displayName:$.displayName||O0($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(R0)?R0:Z[0]}}function VG($){if(!$?.settingSources)return[...ZZ];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...ZZ]}function WG($){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 GG($){let Z=l0($,".mcp.json"),J;try{J=JZ(Z,"utf8")}catch(Q){if(Q.code!=="ENOENT")z(`claude-agent-process: project .mcp.json not readable at ${Z}: ${Q}`);return}try{let Q=JSON.parse(J);if(Q&&typeof Q==="object"&&Q.mcpServers&&typeof Q.mcpServers==="object")return Q.mcpServers;z(`claude-agent-process: project .mcp.json has no mcpServers object at ${Z}`);return}catch(Q){z(`claude-agent-process: project .mcp.json parse failed at ${Z}: ${Q}`);return}}function zG($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Q)=>KG(Q)).filter((Q)=>Q!==null)}function KG($){let Z=$&&typeof $==="object"?$:{question:$},J=V6(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Q=_G(Z.options??Z.choices??Z.suggestions);return{...Z,question:J,options:Q,...typeof Z.header==="string"?{header:Z.header}:{},...typeof Z.multiSelect==="boolean"?{multiSelect:Z.multiSelect}:{}}}function _G($){if(!Array.isArray($))return[];let Z=[];for(let J of $){if(typeof J==="string"){Z.push({label:J});continue}if(!J||typeof J!=="object")continue;let Q=J,Y=V6(Q.label,Q.value,Q.text,Q.title);if(!Y?.trim())continue;let H=V6(Q.description,Q.detail,Q.preview);Z.push(H?{label:Y,description:H}:{label:Y})}return Z}function V6(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var YZ,j2,XG="default",ZZ,D2;var O4=k(()=>{N$();w();c0();d5();U4();YZ=class YZ{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($))}};j2=new Map;ZZ=["project","local"];D2=class D2 extends uW{provider="claude";tokenSourceId;opts;input=new YZ;query=null;abortController=new AbortController;alive=!0;expectedExit=!1;exitPromise;resolveExit;started=!1;pendingPermissions=new Map;pendingInjectedContext=[];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?O0($.model):null}sendInitialize(){if(this.started)return;this.started=!0;let $=Z6(this.opts.model),Z=this.opts.profile;if(Z)z(`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??VG(Z),Q=lW(J,this.opts.managedSkillPluginPath,this.opts.safeMode===!0),Y=WG(Z),H=Z?.strictMcp===!0,X=Z?.loadProjectMcp!==!1?GG(this.opts.workDir):void 0;try{let V=aW();z(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${V.description}`),this.query=pW({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}:{},...a5(this.opts.safeMode)?{extraArgs:a5(this.opts.safeMode)}:{},...V.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:V.pathToClaudeCodeExecutable}:{},...V.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:V.spawnClaudeCodeProcess}:{},permissionMode:XG,env:this.opts.transformEnv?this.opts.transformEnv({...process.env,PATH:s5(),...b.claude.env,...this.opts.hostEnv??{}}):{...process.env,PATH:s5(),...b.claude.env,...this.opts.hostEnv??{}},settingSources:[...J],...Q,tools:Y,...H?{strictMcpConfig:!0}:{},...X?{mcpServers:X}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(W,G,K)=>this.canUseTool(W,G,K),includePartialMessages:!1,systemPrompt:this.opts.systemPrompt??{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(W)=>{let G=W.trim();if(G)z(`claude-agent-process[stderr]: ${G}`)}}})}catch(V){let W=V instanceof Error?V:Error(String(V));this.emit("error",W),this.finishExit(1,null);return}this.readLoop(this.query)}sendUserText($,Z=[]){if(!this.alive){z("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
51
  `:"",Q=this.pendingInjectedContext.length?this.pendingInjectedContext.splice(0).join(`
52
52
 
53
53
  `)+`
54
54
 
55
- `:"";try{this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:Q+J+$}]},parent_tool_use_id:null,priority:"now"})}catch(Y){let H=Y instanceof Error?Y:Error(String(Y));G(`claude-agent-process: sendUserText failed: ${H.message}`),this.failTurnStart(H)}}sendInterrupt(){this.query?.interrupt().catch(($)=>G(`claude-agent-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Q=this.pendingPermissions.get(String($));if(!Q){G(`claude-agent-process: permission response for unknown request ${$}`);return}if(this.pendingPermissions.delete(String($)),Q.cleanup?.(),Z==="allow")Q.resolve({behavior:"allow",updatedInput:J?.updatedInput??{}});else Q.resolve({behavior:"deny",message:J?.denyMessage??""})}sendToolResult($,Z,J=!1){G("claude-agent-process: sendToolResult ignored; Claude Agent SDK executes built-in tools internally")}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(Jz)}async setModelSettings($,Z){let J=$8($);if(!o$(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?T0($):"claude:default",this.lastEffort=Z}async setModel($){await this.setModelSettings($,this.opts.effort)}async compactThread(){if(!this.input)throw Error("claude thread not initialized");return this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:"/compact"}]},parent_tool_use_id:null,priority:"now"}),new Promise(($,Z)=>{let J=!1,Q=()=>{this.off("context_compacted",Y),this.off("assistant_text",H),this.off("exit",V),this.off("error",X)},Y=()=>{if(J)return;J=!0,Q(),$()},H=(W)=>{if(J)return;if((W?.text??"").includes("Not enough messages to compact"))J=!0,Q(),Z(new G2)},V=()=>{if(J)return;J=!0,Q(),Z(Error("claude thread exited during /compact"))},X=(W)=>{if(J)return;J=!0,Q(),Z(W instanceof Error?W:Error(String(W)))};this.on("context_compacted",Y),this.on("assistant_text",H),this.once("exit",V),this.once("error",X)})}async injectThreadItems($){if(!Array.isArray($)||$.length===0)return;this.pendingInjectedContext.push(["Host-injected prior tool context for this continuation:",JSON.stringify($,null,2)].join(`
56
- `))}canUseTool($,Z,J){if(this.opts.readOnlyRoots){let z=uW($,Z,this.opts.workDir,this.opts.readOnlyRoots,this.opts.readOnlyExtraTools);if(!z.allowed)return G(`claude-agent-process: denied read-only worker tool ${$}: ${z.message}`),Promise.resolve({behavior:"deny",message:z.message})}if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Q=Xz(Z);if(Q.length===0)return G("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Y={...Z,questions:Q},H=`claude_perm_${++this.requestCounter}`,V=J.toolUseID||H,X={request_id:H,tool_name:"AskUserQuestion",input:Y,tool_use_id:V},W=new Promise((z)=>{let K=(j)=>{J.signal.removeEventListener("abort",_),z(j)},_=()=>{if(!this.pendingPermissions.delete(H))return;K({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",_,{once:!0}),this.pendingPermissions.set(H,{kind:"dialog",resolve:K,request:X})});return this.emitToolUseOnce(V,"AskUserQuestion",Y,null),this.emit("can_use_tool",X),W}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,Q=(H)=>{if(J)return;J=!0,clearTimeout(Y),Z(H)},Y=setTimeout(()=>Q(!this.alive),Math.max(0,$));this.exitPromise.then(()=>Q(!0))})}handleMessage($){let Z=$;if(typeof Z.session_id==="string"&&Z.session_id)this.sessionId=Z.session_id;switch(Z.type){case"system":this.handleSystemMessage(Z);return;case"assistant":this.handleAssistantMessage(Z);return;case"user":this.handleUserMessage(Z);return;case"result":this.handleResultMessage(Z);return;case"rate_limit_event":this.emit("rate_limits_updated",Z.rate_limit_info);return;case"stream_event":return;default: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=T0($.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;if(typeof $.uuid==="string")this.lastAssistantUuid=$.uuid;if(typeof Z?.model==="string"&&Z.model)this.lastModel=T0(Z.model);let J=Array.isArray(Z?.content)?Z.content:[];for(let Q of J){if(!Q||typeof Q!=="object")continue;if(Q.type==="text"&&typeof Q.text==="string"&&Q.text.length>0){let Y=$z(Q.text);if(Y){if(this.pendingServerToolInputs.push(Y),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(Zz(Q.text))continue;let H=$.uuid??Z?.id;this.emit("assistant_text",{uuid:H,text:Q.text}),this.emit("assistant_block_stop",{index:H})}else if(Q.type==="tool_use"&&typeof Q.id==="string"&&typeof Q.name==="string")this.emitToolUseOnce(Q.id,Q.name,Q.input??{},$.parent_tool_use_id??null);else if(Q.type==="server_tool_use"&&typeof Q.id==="string"&&typeof Q.name==="string")this.emitToolUseOnce(Q.id,eW(Q.name),{tool:Q.name,input:this.serverToolInput(Q.name,Q.input??{})},$.parent_tool_use_id??null);else if(Q.type==="tool_result"&&typeof Q.tool_use_id==="string")this.emitToolResultOnce(Q.tool_use_id,sW(Q.content),Q.is_error===!0,$.parent_tool_use_id??null)}}emitToolUseOnce($,Z,J,Q){if(this.emittedToolUseIds.has($))return;this.emittedToolUseIds.add($),this.emit("tool_use",{id:$,name:Z,input:J,parentToolUseId:Q})}serverToolInput($,Z){let J=Z;if(J&&typeof J==="object"&&!Array.isArray(J)&&Object.keys(J).length>0)return J;let Q=this.pendingServerToolInputs.findIndex((Y)=>Y.name===$);if(Q>=0){let[Y]=this.pendingServerToolInputs.splice(Q,1);return Y.input}return J}emitToolResultOnce($,Z,J,Q){if(this.emittedToolResultIds.has($))return;this.emittedToolResultIds.add($),this.emit("tool_result",{tool_use_id:$,content:Z,is_error:J,parentToolUseId:Q})}handleUserMessage($){let Z=Array.isArray($.message?.content)?$.message.content:[];for(let J of Z){if(!J||typeof J!=="object")continue;if(J.type!=="tool_result"||typeof J.tool_use_id!=="string")continue;let Q=$.tool_use_result,Y=VZ(J.content),H=Q&&typeof Q==="object"?[typeof Q.stdout==="string"?Q.stdout:"",typeof Q.stderr==="string"?Q.stderr:""].filter(Boolean).join(`
57
- `):"",V=Y||H;this.emitToolResultOnce(J.tool_use_id,V,J.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=oW($.usage),J=$.modelUsage??$.model_usage,Q=rW(J);if(!Z&&!Q.usage)G(`claude-agent-process: result usage missing rootKeys=${Y8($).join(",")||"-"} usageKeys=${Y8($.usage).join(",")||"-"} modelUsageKeys=${Y8(J).join(",")||"-"}`);if(this.lastUsage=Z,Q.usage)this.cumulativeUsageFromResults=M4(Q.usage),this.lastTotalUsage=M4(Q.usage);else if(Z)this.cumulativeUsageFromResults=tW(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=M4(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?M4(this.cumulativeUsageFromResults):null;if(Q.contextWindow!=null){let X=e3(this.opts.model,this.tokenSourceId),W=B2.get(X)??0;if(Q.contextWindow>W)B2.set(X,Q.contextWindow),G(`claude-agent-process: SDK contextWindow ${Q.contextWindow} (global max for ${X}, prev ${W||"-"})`);else if(Q.contextWindow<(B2.get(X)??0))G(`claude-agent-process: SDK contextWindow ${Q.contextWindow} ignored (global max ${B2.get(X)} locked for ${X})`);if(this.tokenSourceId)for(let[z,K]of Object.entries(J??{})){let _=K?.contextWindow;if(typeof _==="number"&&_>0)Q8(this.tokenSourceId,z,_)}}this.lastContextWindow=B2.get(e3(this.opts.model,this.tokenSourceId))??Q.contextWindow??null;let Y=W8(this.opts.workDir,this.sessionId??""),H=aW(Y);if(this.lastContextTokens=s3(H)??(R4(Y)?s3(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 V=typeof $.subtype==="string"?$.subtype:$.is_error?"error":"success";if(this.tokenSourceId&&$.is_error===!0){let X=String($.result??$.error??$.api_error_message??"");if(/context.?window|prompt is too long|exceeds?.*(?:context|token)|too many (?:input )?tokens/i.test(X)){let K=(this.lastModel??(this.opts.model?.trim()||"claude:default")).replace(/^claude:/,"");i3(this.tokenSourceId,K),G(`claude-agent-process: context window exceeded on ${K} — downgraded to 200K (no [1m] next spawn)`)}}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:V,is_error:$.is_error===!0||V!=="success"},this.emit("result",{subtype:V,is_error:this.lastResult.is_error,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})}}});async function z8($){let Z=await _8("feishu chat.get",()=>r.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)T4("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 G8($,Z){let J=await _8("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)T4("feishu tasklist.create",J);let Q=J.data?.tasklist,Y=Q?.guid;if(!Y)throw Error("feishu tasklist.create returned no guid");return{guid:Y,name:Q?.name||$,url:Q?.url??"",createdAt:Q?.created_at}}async function K8($){let Z=await _8("feishu tasklist.delete",()=>r.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)T4("feishu tasklist.delete",Z)}function XZ($,Z){let J=Z&&typeof Z==="object"?Z:{},Q=J.response?.data&&typeof J.response.data==="object"?J.response.data:J.data&&typeof J.data==="object"?J.data:J,Y=Q.code??J.code,H=Q.msg??Q.message??J.msg??J.message??"unknown error",V=Q.error?.permission_violations??Q.permission_violations??J.error?.permission_violations,X=Array.isArray(V)?V.map((W)=>W?.scope??W?.subject??W?.name??W).filter(Boolean).join(", "):"";return`${$} failed code=${Y??"unknown"} msg=${H}${X?` missing_scopes=${X}`:""}`}async function _8($,Z){try{return await Z()}catch(J){T4($,J)}}function T4($,Z){throw Error(XZ($,Z))}var WZ=E(()=>{n()});var e={};F1(e,{writeAliveMarker:()=>R2,urgentApp:()=>a0,uploadImageKey:()=>g8,uploadAndSend:()=>I8,updateCard:()=>W0,unbindSessionChat:()=>x4,truncateTurnAnchors:()=>Uz,tempProjectName:()=>a$,tempChatName:()=>k8,setSessionBranchBase:()=>Rz,setPendingConversationLaunchChecked:()=>k0,sendTextRaw:()=>N,sendText:()=>O,sendImage:()=>fZ,sendFile:()=>vZ,sendCard:()=>c,seedTurnAnchors:()=>Mz,sanitizeSessionName:()=>y2,resolveProjectDir:()=>b4,replaceTurnAnchors:()=>C$,registerTempSessionLease:()=>F8,refreshChatList:()=>O2,readAliveMarker:()=>b8,provisionProject:()=>c8,projectProfile:()=>C4,preferredChatForSession:()=>Q$,loadTempSessionLeases:()=>P8,loadSessionTurnsMap:()=>O8,loadSessionResumeMap:()=>M8,loadSessionModelMap:()=>y8,loadSessionChatMap:()=>U8,listNormalChatIdsByName:()=>w4,isOpenAIChatGPTAuthenticated:()=>k2,hasTempSessionLease:()=>A8,getTurnAnchors:()=>v1,getTenantToken:()=>X0,getSessionResumeRef:()=>o0,getSessionResume:()=>Bz,getSessionModelSelection:()=>N8,getSessionModel:()=>Tz,getSessionBranchBase:()=>U2,getPendingConversationLaunch:()=>M2,formatFeishuApiError:()=>XZ,findNormalChatIdByName:()=>f4,fetchChatOwnerOpenId:()=>z8,fetchChatName:()=>h8,ensureChatForSession:()=>S8,downloadAttachment:()=>T2,disbandChatForSessionExact:()=>v8,disbandChatForSession:()=>f8,deleteTasklistByGuid:()=>K8,deleteReaction:()=>P$,createTempChatForSession:()=>w8,createTasklistWithOwner:()=>G8,client:()=>r,clearTurnAnchors:()=>Oz,clearTempSessionLease:()=>_z,clearSessionResumeChecked:()=>f1,clearSessionResume:()=>Lz,clearSessionModelSelection:()=>kz,clearSessionConversationState:()=>C8,chatNameCache:()=>Y$,chatIdForSession:()=>h1,bindSessionToChat:()=>S1,bindSessionResumeChecked:()=>A2,bindSessionResume:()=>jz,bindSessionModelChecked:()=>x8,bindSessionModel:()=>E8,appendTurnAnchorChecked:()=>S4,appendTurnAnchor:()=>Az,addReaction:()=>R$,PROJECTS_ROOT:()=>RZ});import*as BZ from"@larksuiteoapi/node-sdk";import{execSync as LZ}from"node:child_process";import{randomUUID as D8}from"node:crypto";import{existsSync as Gz,mkdirSync as j8,readFileSync as d0,statSync as DZ,writeFileSync as PZ}from"node:fs";import{readFile as FZ}from"node:fs/promises";import{homedir as zZ}from"node:os";import{basename as i0,extname as Kz,isAbsolute as AZ,join as y4}from"node:path";function E4(){let $={};for(let[Z,J]of K$)$[Z]=J;V$(G6,$)}function P8(){K$.clear();try{let $=JSON.parse(d0(G6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("lease file must contain an object");for(let[Z,J]of Object.entries($)){let Q=J;if(typeof Z!=="string"||!Z||Q.chatId!==Z||typeof Q.sessionName!=="string"||!a$(Q.sessionName)||typeof Q.createdAt!=="number"||!Number.isFinite(Q.createdAt)){G(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}K$.set(Z,{chatId:Z,sessionName:Q.sessionName,createdAt:Q.createdAt})}G(`feishu: loaded ${K$.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")G(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function F8($,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 Y of K$.values())if(Y.sessionName===$&&Y.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Y.chatId}`);let J=K$.get(Z),Q={sessionName:$,chatId:Z,createdAt:Date.now()};K$.set(Z,Q);try{E4()}catch(Y){if(J)K$.set(Z,J);else K$.delete(Z);throw Y}}function A8($,Z){let J=K$.get(Z);return J?.sessionName===$&&J.chatId===Z}function _z($,Z){let J=[...K$.entries()].filter(([Q,Y])=>Y.sessionName===$&&(!Z||Q===Z));if(!J.length)return;for(let[Q]of J)K$.delete(Q);try{E4()}catch(Q){for(let[Y,H]of J)K$.set(Y,H);throw Q}}function C4($){return S.projects[$]}function b4($){return C4($)?.cwd?.trim()||y4(RZ,$)}function n0($,Z={}){return fetch($,{...Z,signal:Z.signal??AbortSignal.timeout(qz)})}async function X0(){if(k4&&Date.now()<GZ)return k4;return q8??=(async()=>{let $=await n0("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:UZ,app_secret:MZ})}),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,GZ=Date.now()+Math.max(0,(Z.expire??7200)-60)*1000,k4})().finally(()=>{q8=null}),q8}function U8(){try{let $=JSON.parse(d0(V6,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")Q$.set(Z,J);G(`feishu: loaded ${Q$.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")G(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function OZ(){try{B8()}catch($){G(`feishu: save session-chat-map failed: ${$}`)}}function B8(){let $={};for(let[Z,J]of Q$)$[Z]=J;V$(V6,$)}function S1($,Z){if(Q$.get($)===Z)return;let J=Q$.get($);Q$.set($,Z),OZ(),G(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function x4($){let Z=Q$.get($);if(!Z)return;Q$.delete($),OZ(),G(`feishu: unbound session "${$}" from ${Z}`)}function b1($,Z){let J=l.get($)??{};J[Z.provider]=Z,l.set($,J)}function KZ($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Q=J.provider==="claude"||J.provider==="codex"?J.provider:Z??null;if(!Q||Z&&Q!==Z)return null;let Y=typeof J.sessionId==="string"?J.sessionId.trim():typeof J.session_id==="string"?J.session_id.trim():"";if(!Y)return null;if(J.cwd===void 0||J.cwd===null)return{provider:Q,sessionId:Y,cwd:null};if(typeof J.cwd!=="string"||!AZ(J.cwd))return null;return{provider:Q,sessionId:Y,cwd:J.cwd}}function _Z($){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"||!AZ($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function TZ($,Z,J){if(typeof $!=="string")return _Z($);if(!Z)throw Error("cannot bind a conversation without a provider");return _Z({provider:Z,sessionId:$,cwd:J??null})}function M8(){try{let $=JSON.parse(d0(X6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");l.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){b1(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Q=J,Y=KZ(Q);if(Y){b1(Z,Y);continue}for(let H of["codex","claude"]){let V=Q[H];if(typeof V==="string"&&V.trim()){b1(Z,{provider:H,sessionId:V.trim(),cwd:null});continue}let X=KZ(V,H);if(X)b1(Z,X)}}G(`feishu: loaded ${l.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")G(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function L8(){try{F2()}catch($){G(`feishu: save session-resume-map failed: ${$}`)}}function F2(){let $={};for(let[Z,J]of l){let Q={};if(J.codex)Q.codex={...J.codex};if(J.claude)Q.claude={...J.claude};$[Z]=Q}V$(X6,$)}function jz($,Z,J,Q){let Y=TZ(Z,J,Q),H=l.get($)?.[Y.provider];if(H?.sessionId===Y.sessionId&&H.cwd===Y.cwd)return;b1($,Y),L8()}function A2($,Z,J,Q){let Y=TZ(Z,J,Q),H=l.get($),V=H?{...H}:void 0,X=H?.[Y.provider];if(X?.sessionId===Y.sessionId&&X.cwd===Y.cwd)return;b1($,Y);try{F2()}catch(W){if(V)l.set($,V);else l.delete($);throw W}}function Bz($,Z="codex"){return l.get($)?.[Z]?.sessionId??null}function o0($,Z="codex"){let J=l.get($)?.[Z];return J?{...J}:null}function Lz($,Z){let J=l.get($);if(!J)return;if(!Z){l.delete($),L8();return}if(J[Z]===void 0)return;if(delete J[Z],!J.codex&&!J.claude)l.delete($);L8()}function f1($,Z){let J=l.get($);if(!J||Z&&J[Z]===void 0)return;let Q={...J};if(!Z)l.delete($);else{let Y={...J};if(delete Y[Z],!Y.codex&&!Y.claude)l.delete($);else l.set($,Y)}try{F2()}catch(Y){throw l.set($,Q),Y}}function kZ($){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 Q;if(Z.cwd===void 0||Z.cwd===null)Q=null;else if(typeof Z.cwd==="string"&&Z.cwd.trim())Q=Z.cwd;else return null;return{provider:Z.provider,sessionId:J,cwd:Q}}function yZ($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Q=kZ(J),Y=typeof Z.id==="string"?Z.id.trim():"";if(!Y||!Q)return null;if(Z.provider==="claude"&&Z.kind==="assistant-message"&&Q.provider==="claude")return{provider:"claude",kind:"assistant-message",id:Y,source:{...Q,provider:"claude"}};if(Z.provider==="codex"&&Z.kind==="turn"&&Q.provider==="codex")return{provider:"codex",kind:"turn",id:Y,source:{...Q,provider:"codex"}};return null}function EZ($){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=kZ(Z.source);if(!J)return null;let Q=Z.kind==="resume"?{kind:"resume",source:J}:(()=>{if(!Object.prototype.hasOwnProperty.call(Z,"through"))return{kind:"fork",source:J};let Y=yZ(Z.through);return Y?{kind:"fork",source:J,through:Y}:null})();if(!Q)return null;try{G$(Q,J.provider)}catch{return null}return Q}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 Pz($,Z){if(!$||typeof $!=="object")return null;let J=$;if(typeof J.ts!=="number"||!Number.isFinite(J.ts))return null;let Q=Object.prototype.hasOwnProperty.call(J,"checkpoint"),Y=yZ(J.checkpoint);if(Q&&!Y)return null;if(!Y){if(Z!=="claude")return null;let H=typeof J.uuid==="string"?J.uuid.trim():"",V=typeof J.sid==="string"?J.sid.trim():"";if(!H||!V)return null;Y={provider:"claude",kind:"assistant-message",id:H,source:{provider:"claude",sessionId:V,cwd:null}}}return{checkpoint:Y,preview:String(J.preview??""),ts:J.ts,writes:Dz(J.writes)}}function Fz($){if(!$||typeof $!=="object")return null;let Z=$,J=EZ(Z.launch);if(J?.kind!=="fork"||J.source.provider!=="claude"||J.source.cwd===null)return null;let Q=Z.previousSessionId,Y=Q===null?null:typeof Q==="string"&&Q.trim()?Q.trim():void 0;if(Y===void 0)return null;return{launch:{...J,source:{...J.source,provider:"claude"}},previousSessionId:Y}}function R8($){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 O8(){try{let $=JSON.parse(d0(W6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");h.clear();let Z=0,J=0;for(let[Q,Y]of Object.entries($)){let H,V,X=null;if(Array.isArray(Y))H=Y,V=null;else if(Y&&typeof Y==="object"&&!Array.isArray(Y)){let _=Y;if(!Array.isArray(_.anchors)||!Object.prototype.hasOwnProperty.call(_,"base")){J++;continue}if(H=_.anchors,_.base===null)V=null;else{let j=EZ(_.base);if(!j){J++;continue}V=j}if(Object.prototype.hasOwnProperty.call(_,"pendingLaunch")){let j=Fz(_.pendingLaunch);if(!j){J++;continue}X=j}}else{J++;continue}let W=l.get(Q),z=W?.claude!==void 0&&W.codex===void 0?"claude":null,K=[];for(let _ of H){let j=Pz(_,z);if(j)K.push(j);else J++}if(K.length||V!==null||X)h.set(Q,{base:V,anchors:K,...X?{pendingLaunch:X}:{}}),Z+=K.length}if(G(`feishu: loaded ${Z} turn anchors across ${h.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 T8(){try{w1()}catch($){G(`feishu: save session-turns-map failed: ${$}`)}}function w1(){let $={};for(let[Z,J]of h)$[Z]=J;V$(W6,$)}function Az($,Z){try{S4($,Z)}catch(J){G(`feishu: append turn anchor failed: ${J}`)}}function S4($,Z){let J=h.get($),Q=[...J?.anchors??[],Z],Y=J?.base??null;if(Q.length>qZ){let H=Q.splice(0,Q.length-qZ),V=H[H.length-1].checkpoint;Y={kind:"fork",source:V.source,through:V}}h.set($,{base:Y,anchors:Q,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{w1()}catch(H){if(J)h.set($,J);else h.delete($);throw H}}function v1($){return h.get($)?.anchors??[]}function U2($){return h.get($)?.base??null}function M2($){let Z=h.get($)?.pendingLaunch;return Z?R8(Z):null}function k0($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");G$(Z.launch,"claude",Z.launch.source.cwd)}let J=h.get($),Q=J?.base??null,Y=J?.anchors.slice()??[];if(!Z&&Y.length===0&&Q===null)h.delete($);else h.set($,{base:Q,anchors:Y,...Z?{pendingLaunch:R8(Z)}:{}});try{w1()}catch(H){if(J)h.set($,J);else h.delete($);throw H}}function Uz($,Z){let J=h.get($);if(!J||J.anchors.length<=Z)return;h.set($,{...J,anchors:J.anchors.slice(0,Z)}),T8()}function Mz($,Z){if(Z.length===0)return;h.set($,{base:null,anchors:Z.slice()}),T8()}function C$($,Z,J,Q){let Y=h.get($),H=Q===void 0?Y?.pendingLaunch:Q??void 0,V=H?R8(H):void 0;if(Z.length===0&&J===null&&!V)h.delete($);else h.set($,{base:J,anchors:Z.slice(),...V?{pendingLaunch:V}:{}});try{w1()}catch(X){if(Y)h.set($,Y);else h.delete($);throw X}}function Rz($,Z){C$($,v1($),Z)}function Oz($){if(!h.has($))return;h.delete($),T8()}function a$($){return jZ.test($)?$.replace(jZ,""):null}function k8($,Z=[]){let J=new Date,Q=(X)=>String(X).padStart(2,"0"),Y=`${Q(J.getMonth()+1)}${Q(J.getDate())}-${Q(J.getHours())}${Q(J.getMinutes())}`,H=new Set([...Y$.values(),...h.keys(),...Z]),V=`${$}*${Y}`;for(let X=2;H.has(V);X++)V=`${$}*${Y}-${X}`;return V}function y8(){try{let $=JSON.parse(d0(z6,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){J$.set(Z,{provider:E1(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Q,provider:Y}=J,H=Y==="claude"||Y==="codex"?Y:typeof Q==="string"&&Q.trim()?E1(Q):"claude",V=typeof Q==="string"&&Q.trim()?Q:null;if(H==="claude"&&!V)continue;let{effort:X,tokenSourceId:W}=J,z=typeof W==="string"&&W.trim()?W.trim():null,K=H==="claude"?o$(X)?X:null:E$(X)?X:null;J$.set(Z,{provider:H,model:V,effort:K,...z?{tokenSourceId:z}:{}})}G(`feishu: loaded ${J$.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")G(`feishu: load session-model-map failed: ${$?.message??$}`)}}function xZ(){try{N4()}catch($){G(`feishu: save session-model-map failed: ${$}`)}}function N4(){let $={};for(let[Z,J]of J$)$[Z]=J;V$(z6,$)}function E8($,Z,J,Q,Y){let H=J$.get($);if(H?.provider===Z&&H.model===J&&H.effort===Q&&(H.tokenSourceId??null)===(Y??null))return;J$.set($,{provider:Z,model:J,effort:Q,...Y?{tokenSourceId:Y}:{}}),xZ()}function x8($,Z,J,Q,Y){let H=J$.get($),V={provider:Z,model:J,effort:Q,...Y?{tokenSourceId:Y}:{}};if(H?.provider===Z&&H.model===J&&H.effort===Q&&(H.tokenSourceId??null)===(Y??null))return;J$.set($,V);try{N4()}catch(X){if(H)J$.set($,H);else J$.delete($);throw X}}function N8($){let Z=J$.get($);if(Z)return Z;let J=a$($);return J?J$.get(J)??null:null}function Tz($){return J$.get($)?.model??null}function kz($){if(!J$.has($))return;J$.delete($),xZ()}function C8($){let Z=Q$.get($),J=l.get($),Q=J$.get($),Y=h.get($),H=[...K$.entries()].filter(([,V])=>V.sessionName===$);Q$.delete($),l.delete($),J$.delete($),h.delete($);for(let[V]of H)K$.delete(V);try{B8(),F2(),N4(),w1(),E4()}catch(V){if(Z)Q$.set($,Z);if(J)l.set($,J);if(Q)J$.set($,Q);if(Y)h.set($,Y);for(let[W,z]of H)K$.set(W,z);let X=[V];for(let W of[B8,F2,N4,w1,E4])try{W()}catch(z){X.push(z)}throw X.length===1?X[0]:AggregateError(X,`failed to clear and restore conversation state for ${$}`)}}function R2($){try{V$($4,$)}catch(Z){G(`feishu: write alive marker failed: ${Z}`)}}function b8(){if(!Gz($4))return[];try{let $=d0($4,"utf8"),Z=JSON.parse($);return Array.isArray(Z)?Z.filter((J)=>typeof J==="string"):[]}catch($){return G(`feishu: read alive marker failed: ${$}`),[]}}function h1($){let Z=Q$.get($);if(Z){let Q=Y$.get(Z);if(Q&&Q!==$)G(`feishu: chatIdForSession("${$}"): persisted binding ${Z} has cached name "${Q}", using persisted binding`);return Z}let J=[];for(let[Q,Y]of Y$)if(Y===$)J.push(Q);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 O2(){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 w4(){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 Q of J.data?.items??[]){if(!Q.chat_id||!Q.name)continue;if(Q.chat_status&&Q.chat_status!=="normal")continue;Y$.set(Q.chat_id,Q.name);let Y=$.get(Q.name)??[];Y.push(Q.chat_id),$.set(Q.name,Y)}Z=J.data?.page_token}while(Z);return $}async function f4($){let Z=Q$.get($);if(Z&&Y$.get(Z)===$){let H=await CZ(Z);if(H.name===$&&bZ(H.status))return Z;Y$.delete(Z),x4($)}let Q=(await w4()).get($)??[];if(Q.length===0)return null;let Y=Q$.get($);if(Y&&Q.includes(Y))return Y;if(Q.length===1)return Q[0];throw Error(`multiple Feishu groups named "${$}": ${Q.join(", ")}`)}async function S8($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await f4($);if(J){let H=await yz(J,Z);return S1($,J),{chatId:J,created:!1,joined:H}}let Q=await r.im.chat.create({params:{user_id_type:"open_id",uuid:D8()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw Error(`feishu chat.create failed code=${Q.code} msg=${Q.msg}`);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return Y$.set(Y,$),S1($,Y),{chatId:Y,created:!0,joined:!0}}async function w8($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await f4($))throw Error(`temporary group name already exists: ${$}`);let Q=await r.im.chat.create({params:{user_id_type:"open_id",uuid:D8()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw Error(`feishu chat.create failed code=${Q.code} msg=${Q.msg}`);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return Y$.set(Y,$),S1($,Y),{chatId:Y,created:!0,joined:!0}}async function f8($){let Z=await f4($);if(!Z)return x4($),{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),Q$.get($)===Z)x4($);return{chatId:Z,disbanded:!0}}async function v8($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await CZ(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!bZ(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Q=await r.im.chat.delete({path:{chat_id:Z}});if(Q.code&&Q.code!==0)throw Error(`feishu chat.delete failed code=${Q.code} msg=${Q.msg}`);return Y$.delete(Z),{chatId:Z,disbanded:!0}}async function yz($,Z){let J;do{let Y=await r.im.chatMembers.get({path:{chat_id:$},params:{member_id_type:"open_id",page_size:100,...J?{page_token:J}:{}}});if(Y.code&&Y.code!==0)throw Error(`feishu chatMembers.get failed code=${Y.code} msg=${Y.msg}`);for(let H of Y.data?.items??[])if(H.member_id===Z)return!1;J=Y.data?.page_token}while(J);let Q=await r.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Q.code&&Q.code!==0)throw Error(`feishu chatMembers.create failed code=${Q.code} msg=${Q.msg}`);return!0}async function h8($){try{let Z=await X0(),Q=await(await n0(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}})).json();if(Q?.code!==0)return G(`feishu: fetchChatName ${$} code=${Q?.code} msg=${Q?.msg}`),null;let Y=Q.data?.name;if(typeof Y==="string"&&Y)return Y$.set($,Y),G(`feishu: fetchChatName ${$} → "${Y}" (point lookup)`),Y;return G(`feishu: fetchChatName ${$} — chat has no name (unnamed group?)`),null}catch(Z){return G(`feishu: fetchChatName ${$} failed: ${Z}`),null}}async function NZ($,Z,J,Q){let Y=D8(),H=null;for(let V=0;V<P2.length;V++){if(P2[V]>0)await new Promise((X)=>setTimeout(X,P2[V]));try{let X=await r.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Q,uuid:Y}});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){H=X,G(`feishu: send${$==="text"?"Text":"Card"} attempt ${V+1}/${P2.length} chat=${Z} failed: ${X}`)}}return G(`feishu: send${$==="text"?"Text":"Card"} chat=${Z} EXHAUSTED ${P2.length} retries: ${H}`),null}async function CZ($){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 bZ($){return $===null||$==="normal"}async function O($,Z){return NZ("text",$,"text",JSON.stringify({text:Z}))}async function c($,Z){return NZ("card",$,"interactive",JSON.stringify(U0(Z)))}async function W0($,Z){let J=await r.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(U0(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function N($,Z){try{let J=await X0(),Y=await(await n0("https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id",{method:"POST",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({receive_id:$,msg_type:"text",content:JSON.stringify({text:Z})})})).json();if(Y?.code!==0)return G(`feishu: sendTextRaw rejected chat=${$} code=${Y?.code} msg=${Y?.msg}`),null;return Y.data?.message_id??null}catch(J){return G(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function R$($,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 a0($,Z){if(!$){G("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){G(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await X0(),Q=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let H=await(await n0(Q,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})})).json();if(H?.code!==0){G(`feishu: urgentApp ${$} code=${H?.code} msg=${H?.msg}`);return}let V=H.data?.invalid_user_id_list??[],X=Z.length-V.length;G(`feishu: urgentApp ${$} ok — delivered=${X}${V.length?` invalid=${V.length}`:""}`)}catch(Y){G(`feishu: urgentApp ${$} failed: ${Y}`)}}async function T2($,Z,J,Q){try{let Y=await X0(),H=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,V=await n0(H,{headers:{Authorization:`Bearer ${Y}`}});if(!V.ok){G(`feishu: download ${J} HTTP ${V.status}: ${(await V.text()).slice(0,200)}`);return}let X=Buffer.from(await V.arrayBuffer());j8(K6,{recursive:!0});let W=Q?Q.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,z=y4(K6,`${Date.now()}-${W}`);return PZ(z,X),G(`feishu: downloaded ${J} ${z} (${X.length}B)`),z}catch(Y){G(`feishu: download ${J} failed: ${Y instanceof Error?Y.message:Y}`);return}}function xz($){return Ez.has(Kz($).toLowerCase())}async function wZ($){let Z=await X0(),J=new Blob([Uint8Array.from(await FZ($))]),Q=new FormData;Q.append("image_type","message"),Q.append("image",J,i0($));let H=await(await n0("https://open.feishu.cn/open-apis/im/v1/images",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Q})).json();if(H?.code!==0)return G(`feishu: uploadImage ${$} code=${H.code} msg=${H.msg}`),null;return H.data?.image_key??null}async function g8($){try{let Z=DZ($);if(!Z.isFile())return G(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>SZ)return G(`feishu: uploadImageKey oversize — ${$} (${(Z.size/1024/1024).toFixed(1)} MB)`),null}catch(Z){return G(`feishu: uploadImageKey stat failed — ${$}: ${Z}`),null}return wZ($)}async function Nz($){let Z=await X0(),J=new Blob([Uint8Array.from(await FZ($))]),Q=new FormData;Q.append("file_type","stream"),Q.append("file_name",i0($)),Q.append("file",J,i0($));let H=await(await n0("https://open.feishu.cn/open-apis/im/v1/files",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Q})).json();if(H?.code!==0)return G(`feishu: uploadFile ${$} code=${H.code} msg=${H.msg}`),null;return H.data?.file_key??null}async function fZ($,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 vZ($,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 I8($,Z){try{let Q=DZ(Z);if(!Q.isFile())return await O($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Q.size>SZ)return await O($,`❌ 出站文件: ${i0(Z)} 超过 30 MB (${(Q.size/1024/1024).toFixed(1)} MB)`),!1}catch(Q){return await O($,`❌ 出站文件: 无法读取 ${Z} (${Q})`),!1}let J=xz(Z);try{if(J){let Q=await wZ(Z);if(!Q)return await O($,`❌ 出站图片上传失败: ${i0(Z)}`),!1;return await fZ($,Q)!=null}else{let Q=await Nz(Z);if(!Q)return await O($,`❌ 出站文件上传失败: ${i0(Z)}`),!1;return await vZ($,Q)!=null}}catch(Q){return G(`feishu: uploadAndSend ${Z} failed: ${Q}`),await O($,`❌ 出站文件异常: ${i0(Z)} — ${Q}`),!1}}function c8($){j8($,{recursive:!0}),G(`feishu: provisioned ${$}`);let Z=y4(zZ(),".codex","config.toml");try{j8(y4(zZ(),".codex"),{recursive:!0});let J="";try{J=d0(Z,"utf8")}catch{}let Q=`[projects.${JSON.stringify($)}]`;if(!J.includes(Q)){let Y=J.trimEnd();J=`${Y}${Y?`
55
+ `:"";try{this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:Q+J+$}]},parent_tool_use_id:null,priority:"now"})}catch(Y){let H=Y instanceof Error?Y:Error(String(Y));z(`claude-agent-process: sendUserText failed: ${H.message}`),this.failTurnStart(H)}}sendInterrupt(){this.query?.interrupt().catch(($)=>z(`claude-agent-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Q=this.pendingPermissions.get(String($));if(!Q){z(`claude-agent-process: permission response for unknown request ${$}`);return}if(this.pendingPermissions.delete(String($)),Q.cleanup?.(),Z==="allow")Q.resolve({behavior:"allow",updatedInput:J?.updatedInput??{}});else Q.resolve({behavior:"deny",message:J?.denyMessage??""})}sendToolResult($,Z,J=!1){z("claude-agent-process: sendToolResult ignored; Claude Agent SDK executes built-in tools internally")}sendHookResponse($,Z={}){z("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 z(`claude-agent-process: kill failed: ${J.message}`),J}if(Z){let J=Error(`claude Agent SDK close failed: ${Z.message}`,{cause:Z});throw z(`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(HG)}async setModelSettings($,Z){let J=Z6($);if(!o$(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?O0($):"claude:default",this.lastEffort=Z}async setModel($){await this.setModelSettings($,this.opts.effort)}async compactThread(){if(!this.input)throw Error("claude thread not initialized");return this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:"/compact"}]},parent_tool_use_id:null,priority:"now"}),new Promise(($,Z)=>{let J=!1,Q=()=>{this.off("context_compacted",Y),this.off("assistant_text",H),this.off("exit",X),this.off("error",V)},Y=()=>{if(J)return;J=!0,Q(),$()},H=(W)=>{if(J)return;if((W?.text??"").includes("Not enough messages to compact"))J=!0,Q(),Z(new z2)},X=()=>{if(J)return;J=!0,Q(),Z(Error("claude thread exited during /compact"))},V=(W)=>{if(J)return;J=!0,Q(),Z(W instanceof Error?W:Error(String(W)))};this.on("context_compacted",Y),this.on("assistant_text",H),this.once("exit",X),this.once("error",V)})}async injectThreadItems($){if(!Array.isArray($)||$.length===0)return;this.pendingInjectedContext.push(["Host-injected prior tool context for this continuation:",JSON.stringify($,null,2)].join(`
56
+ `))}canUseTool($,Z,J){if(this.opts.readOnlyRoots){let G=dW($,Z,this.opts.workDir,this.opts.readOnlyRoots,this.opts.readOnlyExtraTools);if(!G.allowed)return z(`claude-agent-process: denied read-only worker tool ${$}: ${G.message}`),Promise.resolve({behavior:"deny",message:G.message})}if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Q=zG(Z);if(Q.length===0)return z("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Y={...Z,questions:Q},H=`claude_perm_${++this.requestCounter}`,X=J.toolUseID||H,V={request_id:H,tool_name:"AskUserQuestion",input:Y,tool_use_id:X},W=new Promise((G)=>{let K=(B)=>{J.signal.removeEventListener("abort",_),G(B)},_=()=>{if(!this.pendingPermissions.delete(H))return;K({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",_,{once:!0}),this.pendingPermissions.set(H,{kind:"dialog",resolve:K,request:V})});return this.emitToolUseOnce(X,"AskUserQuestion",Y,null),this.emit("can_use_tool",V),W}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){z(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}z(`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(),z(`claude-agent-process: exited code=${$} signal=${Z} expected=${this.expectedExit}`),this.emit("exit",{code:$,signal:Z,expected:this.expectedExit})}denyPendingPermissions($){for(let[Z,J]of this.pendingPermissions)J.cleanup?.(),J.resolve({behavior:"deny",message:$}),this.pendingPermissions.delete(Z)}async waitForExit($){if(!this.alive)return!0;return new Promise((Z)=>{let J=!1,Q=(H)=>{if(J)return;J=!0,clearTimeout(Y),Z(H)},Y=setTimeout(()=>Q(!this.alive),Math.max(0,$));this.exitPromise.then(()=>Q(!0))})}handleMessage($){let Z=$;if(typeof Z.session_id==="string"&&Z.session_id)this.sessionId=Z.session_id;switch(Z.type){case"system":this.handleSystemMessage(Z);return;case"assistant":this.handleAssistantMessage(Z);return;case"user":this.handleUserMessage(Z);return;case"result":this.handleResultMessage(Z);return;case"rate_limit_event":this.emit("rate_limits_updated",Z.rate_limit_info);return;case"stream_event":return;default:z(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=O0($.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":z(`claude-agent-process: api retry attempt=${$.attempt}/${$.max_retries} status=${$.error_status} error=${$.error}`);return;case"permission_denied":z(`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){z("claude-agent-process: task_notification missing task_id");return}if($.status!=="completed"&&$.status!=="failed"&&$.status!=="stopped"){z(`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:z(`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=O0(Z.model);let Q=Array.isArray(Z?.content)?Z.content:[];for(let Y of Q){if(!Y||typeof Y!=="object")continue;if(Y.type==="text"&&typeof Y.text==="string"&&Y.text.length>0){let H=QG(Y.text);if(H){if(this.pendingServerToolInputs.push(H),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(YG(Y.text))continue;let X=$.uuid??Z?.id;this.emit("assistant_text",{uuid:X,text:Y.text,parentToolUseId:J}),this.emit("assistant_block_stop",{index:X,parentToolUseId:J})}else if(Y.type==="tool_use"&&typeof Y.id==="string"&&typeof Y.name==="string")this.emitToolUseOnce(Y.id,Y.name,Y.input??{},J);else if(Y.type==="server_tool_use"&&typeof Y.id==="string"&&typeof Y.name==="string")this.emitToolUseOnce(Y.id,JG(Y.name),{tool:Y.name,input:this.serverToolInput(Y.name,Y.input??{})},J);else if(Y.type==="tool_result"&&typeof Y.tool_use_id==="string")this.emitToolResultOnce(Y.tool_use_id,ZG(Y.content),Y.is_error===!0,J)}}emitToolUseOnce($,Z,J,Q){if(this.emittedToolUseIds.has($))return;this.emittedToolUseIds.add($),this.emit("tool_use",{id:$,name:Z,input:J,parentToolUseId:Q})}serverToolInput($,Z){let J=Z;if(J&&typeof J==="object"&&!Array.isArray(J)&&Object.keys(J).length>0)return J;let Q=this.pendingServerToolInputs.findIndex((Y)=>Y.name===$);if(Q>=0){let[Y]=this.pendingServerToolInputs.splice(Q,1);return Y.input}return J}emitToolResultOnce($,Z,J,Q){if(this.emittedToolResultIds.has($))return;this.emittedToolResultIds.add($),this.emit("tool_result",{tool_use_id:$,content:Z,is_error:J,parentToolUseId:Q})}handleUserMessage($){let Z=$.message?.content;if($.isMeta===!0&&$.promptSource==="sdk"&&typeof Z==="string"&&Z.trim())this.emit("scheduled_turn_input",{text:Z,promptId:typeof $.promptId==="string"&&$.promptId?$.promptId:null});let J=Array.isArray(Z)?Z:[];for(let Q of J){if(!Q||typeof Q!=="object")continue;if(Q.type!=="tool_result"||typeof Q.tool_use_id!=="string")continue;let Y=$.tool_use_result,H=VZ(Q.content),X=Y&&typeof Y==="object"?[typeof Y.stdout==="string"?Y.stdout:"",typeof Y.stderr==="string"?Y.stderr:""].filter(Boolean).join(`
57
+ `):"",V=H||X;this.emitToolResultOnce(Q.tool_use_id,V,Q.is_error===!0||Y?.interrupted===!0,$.parent_tool_use_id??null)}}handleResultMessage($){if(typeof $.session_id==="string"&&$.session_id)this.sessionId=$.session_id;this.turnActive=!1;let Z=tW($.usage),J=$.modelUsage??$.model_usage,Q=eW(J);if(!Z&&!Q.usage)z(`claude-agent-process: result usage missing rootKeys=${H6($).join(",")||"-"} usageKeys=${H6($.usage).join(",")||"-"} modelUsageKeys=${H6(J).join(",")||"-"}`);if(this.lastUsage=Z,Q.usage)this.cumulativeUsageFromResults=M4(Q.usage),this.lastTotalUsage=M4(Q.usage);else if(Z)this.cumulativeUsageFromResults=$G(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=M4(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?M4(this.cumulativeUsageFromResults):null;if(Q.contextWindow!=null){let V=$Z(this.opts.model,this.tokenSourceId),W=j2.get(V)??0;if(Q.contextWindow>W)j2.set(V,Q.contextWindow),z(`claude-agent-process: SDK contextWindow ${Q.contextWindow} (global max for ${V}, prev ${W||"-"})`);else if(Q.contextWindow<(j2.get(V)??0))z(`claude-agent-process: SDK contextWindow ${Q.contextWindow} ignored (global max ${j2.get(V)} locked for ${V})`);if(this.tokenSourceId)for(let[G,K]of Object.entries(J??{})){let _=K?.contextWindow;if(typeof _==="number"&&_>0)Y6(this.tokenSourceId,G,_)}}this.lastContextWindow=j2.get($Z(this.opts.model,this.tokenSourceId))??Q.contextWindow??null;let Y=G6(this.opts.workDir,this.sessionId??""),H=sW(Y);if(this.lastContextTokens=e5(H)??(R4(Y)?e5(Z):null),this.lastTotalUsage||this.lastUsage)this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:this.sessionId??void 0,turnId:$.uuid});let X=typeof $.subtype==="string"?$.subtype:$.is_error?"error":"success";if(this.tokenSourceId&&$.is_error===!0){let V=String($.result??$.error??$.api_error_message??"");if(/context.?window|prompt is too long|exceeds?.*(?:context|token)|too many (?:input )?tokens/i.test(V)){let K=(this.lastModel??(this.opts.model?.trim()||"claude:default")).replace(/^claude:/,"");i5(this.tokenSourceId,K),z(`claude-agent-process: context window exceeded on ${K} — downgraded to 200K (no [1m] next spawn)`)}}this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof $.duration_ms==="number"?$.duration_ms:null,num_turns:typeof $.num_turns==="number"?$.num_turns:1,usage:this.lastUsage,subtype:X,is_error:$.is_error===!0||X!=="success"},this.emit("result",{subtype:X,is_error:this.lastResult.is_error,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})}}});async function z6($){let Z=await q6("feishu chat.get",()=>a.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)T4("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 K6($,Z){let J=await q6("feishu tasklist.create",()=>a.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)T4("feishu tasklist.create",J);let Q=J.data?.tasklist,Y=Q?.guid;if(!Y)throw Error("feishu tasklist.create returned no guid");return{guid:Y,name:Q?.name||$,url:Q?.url??"",createdAt:Q?.created_at}}async function _6($){let Z=await q6("feishu tasklist.delete",()=>a.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)T4("feishu tasklist.delete",Z)}function WZ($,Z){let J=Z&&typeof Z==="object"?Z:{},Q=J.response?.data&&typeof J.response.data==="object"?J.response.data:J.data&&typeof J.data==="object"?J.data:J,Y=Q.code??J.code,H=Q.msg??Q.message??J.msg??J.message??"unknown error",X=Q.error?.permission_violations??Q.permission_violations??J.error?.permission_violations,V=Array.isArray(X)?X.map((W)=>W?.scope??W?.subject??W?.name??W).filter(Boolean).join(", "):"";return`${$} failed code=${Y??"unknown"} msg=${H}${V?` missing_scopes=${V}`:""}`}async function q6($,Z){try{return await Z()}catch(J){T4($,J)}}function T4($,Z){throw Error(WZ($,Z))}var GZ=k(()=>{n()});var e={};F1(e,{writeAliveMarker:()=>R2,urgentApp:()=>a0,uploadImageKey:()=>g6,uploadAndSend:()=>c6,updateCard:()=>W0,unbindSessionChat:()=>x4,truncateTurnAnchors:()=>OG,tempProjectName:()=>a$,tempChatName:()=>N6,setSessionBranchBase:()=>EG,setPendingConversationLaunchChecked:()=>T0,sendTextRaw:()=>y,sendText:()=>O,sendImage:()=>vZ,sendFile:()=>hZ,sendCard:()=>c,seedTurnAnchors:()=>TG,sanitizeSessionName:()=>N2,resolveProjectDir:()=>S4,replaceTurnAnchors:()=>C$,registerTempSessionLease:()=>P6,refreshChatList:()=>O2,readAliveMarker:()=>b6,provisionProject:()=>m6,projectProfile:()=>C4,preferredChatForSession:()=>Q$,loadTempSessionLeases:()=>F6,loadSessionTurnsMap:()=>T6,loadSessionResumeMap:()=>R6,loadSessionModelMap:()=>k6,loadSessionChatMap:()=>M6,listNormalChatIdsByName:()=>w4,isOpenAIChatGPTAuthenticated:()=>E2,hasTempSessionLease:()=>U6,getTurnAnchors:()=>v1,getTenantToken:()=>V0,getSessionResumeRef:()=>o0,getSessionResume:()=>AG,getSessionModelSelection:()=>C6,getSessionModel:()=>kG,getSessionBranchBase:()=>U2,getPendingConversationLaunch:()=>M2,formatFeishuApiError:()=>WZ,findNormalChatIdByName:()=>f4,fetchChatOwnerOpenId:()=>z6,fetchChatName:()=>I6,ensureChatForSession:()=>w6,downloadAttachment:()=>T2,disbandChatForSessionExact:()=>h6,disbandChatForSession:()=>v6,deleteTasklistByGuid:()=>_6,deleteReaction:()=>A$,createTempChatForSession:()=>f6,createTasklistWithOwner:()=>K6,client:()=>a,clearTurnAnchors:()=>NG,clearTempSessionLease:()=>jG,clearSessionResumeChecked:()=>f1,clearSessionResume:()=>FG,clearSessionModelSelection:()=>xG,clearSessionConversationState:()=>S6,chatNameCache:()=>Y$,chatIdForSession:()=>h1,bindSessionToChat:()=>b1,bindSessionResumeChecked:()=>P2,bindSessionResume:()=>DG,bindSessionModelChecked:()=>y6,bindSessionModel:()=>x6,appendTurnAnchorChecked:()=>b4,appendTurnAnchor:()=>RG,addReaction:()=>R$,PROJECTS_ROOT:()=>OZ});import*as LZ from"@larksuiteoapi/node-sdk";import{execSync as DZ}from"node:child_process";import{randomUUID as A6}from"node:crypto";import{existsSync as qG,mkdirSync as j6,readFileSync as i0,statSync as AZ,writeFileSync as FZ}from"node:fs";import{readFile as PZ}from"node:fs/promises";import{homedir as zZ}from"node:os";import{basename as d0,extname as BG,isAbsolute as UZ,join as N4}from"node:path";function k4(){let $={};for(let[Z,J]of K$)$[Z]=J;X$(K8,$)}function F6(){K$.clear();try{let $=JSON.parse(i0(K8,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("lease file must contain an object");for(let[Z,J]of Object.entries($)){let Q=J;if(typeof Z!=="string"||!Z||Q.chatId!==Z||typeof Q.sessionName!=="string"||!a$(Q.sessionName)||typeof Q.createdAt!=="number"||!Number.isFinite(Q.createdAt)){z(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}K$.set(Z,{chatId:Z,sessionName:Q.sessionName,createdAt:Q.createdAt})}z(`feishu: loaded ${K$.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")z(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function P6($,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 Y of K$.values())if(Y.sessionName===$&&Y.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Y.chatId}`);let J=K$.get(Z),Q={sessionName:$,chatId:Z,createdAt:Date.now()};K$.set(Z,Q);try{k4()}catch(Y){if(J)K$.set(Z,J);else K$.delete(Z);throw Y}}function U6($,Z){let J=K$.get(Z);return J?.sessionName===$&&J.chatId===Z}function jG($,Z){let J=[...K$.entries()].filter(([Q,Y])=>Y.sessionName===$&&(!Z||Q===Z));if(!J.length)return;for(let[Q]of J)K$.delete(Q);try{k4()}catch(Q){for(let[Y,H]of J)K$.set(Y,H);throw Q}}function C4($){return b.projects[$]}function S4($){return C4($)?.cwd?.trim()||N4(OZ,$)}function n0($,Z={}){return fetch($,{...Z,signal:Z.signal??AbortSignal.timeout(LG)})}async function V0(){if(E4&&Date.now()<KZ)return E4;return B6??=(async()=>{let $=await n0("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:MZ,app_secret:RZ})}),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 E4=Z.tenant_access_token,KZ=Date.now()+Math.max(0,(Z.expire??7200)-60)*1000,E4})().finally(()=>{B6=null}),B6}function M6(){try{let $=JSON.parse(i0(V8,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")Q$.set(Z,J);z(`feishu: loaded ${Q$.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")z(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function TZ(){try{L6()}catch($){z(`feishu: save session-chat-map failed: ${$}`)}}function L6(){let $={};for(let[Z,J]of Q$)$[Z]=J;X$(V8,$)}function b1($,Z){if(Q$.get($)===Z)return;let J=Q$.get($);Q$.set($,Z),TZ(),z(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function x4($){let Z=Q$.get($);if(!Z)return;Q$.delete($),TZ(),z(`feishu: unbound session "${$}" from ${Z}`)}function S1($,Z){let J=l.get($)??{};J[Z.provider]=Z,l.set($,J)}function _Z($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Q=J.provider==="claude"||J.provider==="codex"?J.provider:Z??null;if(!Q||Z&&Q!==Z)return null;let Y=typeof J.sessionId==="string"?J.sessionId.trim():typeof J.session_id==="string"?J.session_id.trim():"";if(!Y)return null;if(J.cwd===void 0||J.cwd===null)return{provider:Q,sessionId:Y,cwd:null};if(typeof J.cwd!=="string"||!UZ(J.cwd))return null;return{provider:Q,sessionId:Y,cwd:J.cwd}}function qZ($){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"||!UZ($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function EZ($,Z,J){if(typeof $!=="string")return qZ($);if(!Z)throw Error("cannot bind a conversation without a provider");return qZ({provider:Z,sessionId:$,cwd:J??null})}function R6(){try{let $=JSON.parse(i0(W8,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");l.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){S1(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Q=J,Y=_Z(Q);if(Y){S1(Z,Y);continue}for(let H of["codex","claude"]){let X=Q[H];if(typeof X==="string"&&X.trim()){S1(Z,{provider:H,sessionId:X.trim(),cwd:null});continue}let V=_Z(X,H);if(V)S1(Z,V)}}z(`feishu: loaded ${l.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")z(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function D6(){try{F2()}catch($){z(`feishu: save session-resume-map failed: ${$}`)}}function F2(){let $={};for(let[Z,J]of l){let Q={};if(J.codex)Q.codex={...J.codex};if(J.claude)Q.claude={...J.claude};$[Z]=Q}X$(W8,$)}function DG($,Z,J,Q){let Y=EZ(Z,J,Q),H=l.get($)?.[Y.provider];if(H?.sessionId===Y.sessionId&&H.cwd===Y.cwd)return;S1($,Y),D6()}function P2($,Z,J,Q){let Y=EZ(Z,J,Q),H=l.get($),X=H?{...H}:void 0,V=H?.[Y.provider];if(V?.sessionId===Y.sessionId&&V.cwd===Y.cwd)return;S1($,Y);try{F2()}catch(W){if(X)l.set($,X);else l.delete($);throw W}}function AG($,Z="codex"){return l.get($)?.[Z]?.sessionId??null}function o0($,Z="codex"){let J=l.get($)?.[Z];return J?{...J}:null}function FG($,Z){let J=l.get($);if(!J)return;if(!Z){l.delete($),D6();return}if(J[Z]===void 0)return;if(delete J[Z],!J.codex&&!J.claude)l.delete($);D6()}function f1($,Z){let J=l.get($);if(!J||Z&&J[Z]===void 0)return;let Q={...J};if(!Z)l.delete($);else{let Y={...J};if(delete Y[Z],!Y.codex&&!Y.claude)l.delete($);else l.set($,Y)}try{F2()}catch(Y){throw l.set($,Q),Y}}function NZ($){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 Q;if(Z.cwd===void 0||Z.cwd===null)Q=null;else if(typeof Z.cwd==="string"&&Z.cwd.trim())Q=Z.cwd;else return null;return{provider:Z.provider,sessionId:J,cwd:Q}}function kZ($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Q=NZ(J),Y=typeof Z.id==="string"?Z.id.trim():"";if(!Y||!Q)return null;if(Z.provider==="claude"&&Z.kind==="assistant-message"&&Q.provider==="claude")return{provider:"claude",kind:"assistant-message",id:Y,source:{...Q,provider:"claude"}};if(Z.provider==="codex"&&Z.kind==="turn"&&Q.provider==="codex")return{provider:"codex",kind:"turn",id:Y,source:{...Q,provider:"codex"}};return null}function xZ($){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=NZ(Z.source);if(!J)return null;let Q=Z.kind==="resume"?{kind:"resume",source:J}:(()=>{if(!Object.prototype.hasOwnProperty.call(Z,"through"))return{kind:"fork",source:J};let Y=kZ(Z.through);return Y?{kind:"fork",source:J,through:Y}:null})();if(!Q)return null;try{z$(Q,J.provider)}catch{return null}return Q}function PG($){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 UG($,Z){if(!$||typeof $!=="object")return null;let J=$;if(typeof J.ts!=="number"||!Number.isFinite(J.ts))return null;let Q=Object.prototype.hasOwnProperty.call(J,"checkpoint"),Y=kZ(J.checkpoint);if(Q&&!Y)return null;if(!Y){if(Z!=="claude")return null;let H=typeof J.uuid==="string"?J.uuid.trim():"",X=typeof J.sid==="string"?J.sid.trim():"";if(!H||!X)return null;Y={provider:"claude",kind:"assistant-message",id:H,source:{provider:"claude",sessionId:X,cwd:null}}}return{checkpoint:Y,preview:String(J.preview??""),ts:J.ts,writes:PG(J.writes)}}function MG($){if(!$||typeof $!=="object")return null;let Z=$,J=xZ(Z.launch);if(J?.kind!=="fork"||J.source.provider!=="claude"||J.source.cwd===null)return null;let Q=Z.previousSessionId,Y=Q===null?null:typeof Q==="string"&&Q.trim()?Q.trim():void 0;if(Y===void 0)return null;return{launch:{...J,source:{...J.source,provider:"claude"}},previousSessionId:Y}}function O6($){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 T6(){try{let $=JSON.parse(i0(G8,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");h.clear();let Z=0,J=0;for(let[Q,Y]of Object.entries($)){let H,X,V=null;if(Array.isArray(Y))H=Y,X=null;else if(Y&&typeof Y==="object"&&!Array.isArray(Y)){let _=Y;if(!Array.isArray(_.anchors)||!Object.prototype.hasOwnProperty.call(_,"base")){J++;continue}if(H=_.anchors,_.base===null)X=null;else{let B=xZ(_.base);if(!B){J++;continue}X=B}if(Object.prototype.hasOwnProperty.call(_,"pendingLaunch")){let B=MG(_.pendingLaunch);if(!B){J++;continue}V=B}}else{J++;continue}let W=l.get(Q),G=W?.claude!==void 0&&W.codex===void 0?"claude":null,K=[];for(let _ of H){let B=UG(_,G);if(B)K.push(B);else J++}if(K.length||X!==null||V)h.set(Q,{base:X,anchors:K,...V?{pendingLaunch:V}:{}}),Z+=K.length}if(z(`feishu: loaded ${Z} turn anchors across ${h.size} sessions`),J>0)z(`feishu: rejected ${J} malformed turn anchors while loading`)}catch($){if($?.code!=="ENOENT")z(`feishu: load session-turns-map failed: ${$?.message??$}`)}}function E6(){try{w1()}catch($){z(`feishu: save session-turns-map failed: ${$}`)}}function w1(){let $={};for(let[Z,J]of h)$[Z]=J;X$(G8,$)}function RG($,Z){try{b4($,Z)}catch(J){z(`feishu: append turn anchor failed: ${J}`)}}function b4($,Z){let J=h.get($),Q=[...J?.anchors??[],Z],Y=J?.base??null;if(Q.length>BZ){let H=Q.splice(0,Q.length-BZ),X=H[H.length-1].checkpoint;Y={kind:"fork",source:X.source,through:X}}h.set($,{base:Y,anchors:Q,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{w1()}catch(H){if(J)h.set($,J);else h.delete($);throw H}}function v1($){return h.get($)?.anchors??[]}function U2($){return h.get($)?.base??null}function M2($){let Z=h.get($)?.pendingLaunch;return Z?O6(Z):null}function T0($,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=h.get($),Q=J?.base??null,Y=J?.anchors.slice()??[];if(!Z&&Y.length===0&&Q===null)h.delete($);else h.set($,{base:Q,anchors:Y,...Z?{pendingLaunch:O6(Z)}:{}});try{w1()}catch(H){if(J)h.set($,J);else h.delete($);throw H}}function OG($,Z){let J=h.get($);if(!J||J.anchors.length<=Z)return;h.set($,{...J,anchors:J.anchors.slice(0,Z)}),E6()}function TG($,Z){if(Z.length===0)return;h.set($,{base:null,anchors:Z.slice()}),E6()}function C$($,Z,J,Q){let Y=h.get($),H=Q===void 0?Y?.pendingLaunch:Q??void 0,X=H?O6(H):void 0;if(Z.length===0&&J===null&&!X)h.delete($);else h.set($,{base:J,anchors:Z.slice(),...X?{pendingLaunch:X}:{}});try{w1()}catch(V){if(Y)h.set($,Y);else h.delete($);throw V}}function EG($,Z){C$($,v1($),Z)}function NG($){if(!h.has($))return;h.delete($),E6()}function a$($){return jZ.test($)?$.replace(jZ,""):null}function N6($,Z=[]){let J=new Date,Q=(V)=>String(V).padStart(2,"0"),Y=`${Q(J.getMonth()+1)}${Q(J.getDate())}-${Q(J.getHours())}${Q(J.getMinutes())}`,H=new Set([...Y$.values(),...h.keys(),...Z]),X=`${$}*${Y}`;for(let V=2;H.has(X);V++)X=`${$}*${Y}-${V}`;return X}function k6(){try{let $=JSON.parse(i0(z8,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){J$.set(Z,{provider:k1(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Q,provider:Y}=J,H=Y==="claude"||Y==="codex"?Y:typeof Q==="string"&&Q.trim()?k1(Q):"claude",X=typeof Q==="string"&&Q.trim()?Q:null;if(H==="claude"&&!X)continue;let{effort:V,tokenSourceId:W}=J,G=typeof W==="string"&&W.trim()?W.trim():null,K=H==="claude"?o$(V)?V:null:k$(V)?V:null;J$.set(Z,{provider:H,model:X,effort:K,...G?{tokenSourceId:G}:{}})}z(`feishu: loaded ${J$.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")z(`feishu: load session-model-map failed: ${$?.message??$}`)}}function yZ(){try{y4()}catch($){z(`feishu: save session-model-map failed: ${$}`)}}function y4(){let $={};for(let[Z,J]of J$)$[Z]=J;X$(z8,$)}function x6($,Z,J,Q,Y){let H=J$.get($);if(H?.provider===Z&&H.model===J&&H.effort===Q&&(H.tokenSourceId??null)===(Y??null))return;J$.set($,{provider:Z,model:J,effort:Q,...Y?{tokenSourceId:Y}:{}}),yZ()}function y6($,Z,J,Q,Y){let H=J$.get($),X={provider:Z,model:J,effort:Q,...Y?{tokenSourceId:Y}:{}};if(H?.provider===Z&&H.model===J&&H.effort===Q&&(H.tokenSourceId??null)===(Y??null))return;J$.set($,X);try{y4()}catch(V){if(H)J$.set($,H);else J$.delete($);throw V}}function C6($){let Z=J$.get($);if(Z)return Z;let J=a$($);return J?J$.get(J)??null:null}function kG($){return J$.get($)?.model??null}function xG($){if(!J$.has($))return;J$.delete($),yZ()}function S6($){let Z=Q$.get($),J=l.get($),Q=J$.get($),Y=h.get($),H=[...K$.entries()].filter(([,X])=>X.sessionName===$);Q$.delete($),l.delete($),J$.delete($),h.delete($);for(let[X]of H)K$.delete(X);try{L6(),F2(),y4(),w1(),k4()}catch(X){if(Z)Q$.set($,Z);if(J)l.set($,J);if(Q)J$.set($,Q);if(Y)h.set($,Y);for(let[W,G]of H)K$.set(W,G);let V=[X];for(let W of[L6,F2,y4,w1,k4])try{W()}catch(G){V.push(G)}throw V.length===1?V[0]:AggregateError(V,`failed to clear and restore conversation state for ${$}`)}}function R2($){try{X$($4,$)}catch(Z){z(`feishu: write alive marker failed: ${Z}`)}}function b6(){if(!qG($4))return[];try{let $=i0($4,"utf8"),Z=JSON.parse($);return Array.isArray(Z)?Z.filter((J)=>typeof J==="string"):[]}catch($){return z(`feishu: read alive marker failed: ${$}`),[]}}function h1($){let Z=Q$.get($);if(Z){let Q=Y$.get(Z);if(Q&&Q!==$)z(`feishu: chatIdForSession("${$}"): persisted binding ${Z} has cached name "${Q}", using persisted binding`);return Z}let J=[];for(let[Q,Y]of Y$)if(Y===$)J.push(Q);if(J.length===1)return J[0];if(J.length>1)z(`feishu: chatIdForSession("${$}"): ${J.length} candidates with no binding — [${J.join(", ")}]`);return null}async function O2(){try{let $;do{let Z=await a.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($);z(`feishu: refreshed chat list — ${Y$.size} groups`)}catch($){z(`feishu: refresh chat list failed: ${$}`)}}async function w4(){let $=new Map,Z;do{let J=await a.im.chat.list({params:{page_size:100,...Z?{page_token:Z}:{}}});if(J.code&&J.code!==0)throw Error(`feishu chat.list failed code=${J.code} msg=${J.msg}`);for(let Q of J.data?.items??[]){if(!Q.chat_id||!Q.name)continue;if(Q.chat_status&&Q.chat_status!=="normal")continue;Y$.set(Q.chat_id,Q.name);let Y=$.get(Q.name)??[];Y.push(Q.chat_id),$.set(Q.name,Y)}Z=J.data?.page_token}while(Z);return $}async function f4($){let Z=Q$.get($);if(Z&&Y$.get(Z)===$){let H=await SZ(Z);if(H.name===$&&bZ(H.status))return Z;Y$.delete(Z),x4($)}let Q=(await w4()).get($)??[];if(Q.length===0)return null;let Y=Q$.get($);if(Y&&Q.includes(Y))return Y;if(Q.length===1)return Q[0];throw Error(`multiple Feishu groups named "${$}": ${Q.join(", ")}`)}async function w6($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await f4($);if(J){let H=await yG(J,Z);return b1($,J),{chatId:J,created:!1,joined:H}}let Q=await a.im.chat.create({params:{user_id_type:"open_id",uuid:A6()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw Error(`feishu chat.create failed code=${Q.code} msg=${Q.msg}`);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return Y$.set(Y,$),b1($,Y),{chatId:Y,created:!0,joined:!0}}async function f6($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await f4($))throw Error(`temporary group name already exists: ${$}`);let Q=await a.im.chat.create({params:{user_id_type:"open_id",uuid:A6()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw Error(`feishu chat.create failed code=${Q.code} msg=${Q.msg}`);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return Y$.set(Y,$),b1($,Y),{chatId:Y,created:!0,joined:!0}}async function v6($){let Z=await f4($);if(!Z)return x4($),{chatId:null,disbanded:!1};let J=await a.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),Q$.get($)===Z)x4($);return{chatId:Z,disbanded:!0}}async function h6($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await SZ(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!bZ(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Q=await a.im.chat.delete({path:{chat_id:Z}});if(Q.code&&Q.code!==0)throw Error(`feishu chat.delete failed code=${Q.code} msg=${Q.msg}`);return Y$.delete(Z),{chatId:Z,disbanded:!0}}async function yG($,Z){let J;do{let Y=await a.im.chatMembers.get({path:{chat_id:$},params:{member_id_type:"open_id",page_size:100,...J?{page_token:J}:{}}});if(Y.code&&Y.code!==0)throw Error(`feishu chatMembers.get failed code=${Y.code} msg=${Y.msg}`);for(let H of Y.data?.items??[])if(H.member_id===Z)return!1;J=Y.data?.page_token}while(J);let Q=await a.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Q.code&&Q.code!==0)throw Error(`feishu chatMembers.create failed code=${Q.code} msg=${Q.msg}`);return!0}async function I6($){try{let Z=await V0(),Q=await(await n0(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}})).json();if(Q?.code!==0)return z(`feishu: fetchChatName ${$} code=${Q?.code} msg=${Q?.msg}`),null;let Y=Q.data?.name;if(typeof Y==="string"&&Y)return Y$.set($,Y),z(`feishu: fetchChatName ${$} → "${Y}" (point lookup)`),Y;return z(`feishu: fetchChatName ${$} — chat has no name (unnamed group?)`),null}catch(Z){return z(`feishu: fetchChatName ${$} failed: ${Z}`),null}}async function CZ($,Z,J,Q){let Y=A6(),H=null;for(let X=0;X<A2.length;X++){if(A2[X]>0)await new Promise((V)=>setTimeout(V,A2[X]));try{let V=await a.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Q,uuid:Y}});if(V?.code&&V.code!==0)return z(`feishu: send${$==="text"?"Text":"Card"} rejected chat=${Z} code=${V.code} msg=${V.msg}`),null;return V?.data?.message_id??null}catch(V){H=V,z(`feishu: send${$==="text"?"Text":"Card"} attempt ${X+1}/${A2.length} chat=${Z} failed: ${V}`)}}return z(`feishu: send${$==="text"?"Text":"Card"} chat=${Z} EXHAUSTED ${A2.length} retries: ${H}`),null}async function SZ($){let Z=await a.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 bZ($){return $===null||$==="normal"}async function O($,Z){return CZ("text",$,"text",JSON.stringify({text:Z}))}async function c($,Z){return CZ("card",$,"interactive",JSON.stringify(U0(Z)))}async function W0($,Z){let J=await a.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(U0(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function y($,Z){try{let J=await V0(),Y=await(await n0("https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id",{method:"POST",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({receive_id:$,msg_type:"text",content:JSON.stringify({text:Z})})})).json();if(Y?.code!==0)return z(`feishu: sendTextRaw rejected chat=${$} code=${Y?.code} msg=${Y?.msg}`),null;return Y.data?.message_id??null}catch(J){return z(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function R$($,Z){if(!$)return null;try{return(await a.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}}))?.data?.reaction_id??null}catch(J){return z(`feishu: addReaction ${Z} on ${$} failed: ${J}`),null}}async function A$($,Z){if(!$||!Z)return;try{await a.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}})}catch(J){z(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function a0($,Z){if(!$){z("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){z(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await V0(),Q=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let H=await(await n0(Q,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})})).json();if(H?.code!==0){z(`feishu: urgentApp ${$} code=${H?.code} msg=${H?.msg}`);return}let X=H.data?.invalid_user_id_list??[],V=Z.length-X.length;z(`feishu: urgentApp ${$} ok — delivered=${V}${X.length?` invalid=${X.length}`:""}`)}catch(Y){z(`feishu: urgentApp ${$} failed: ${Y}`)}}async function T2($,Z,J,Q){try{let Y=await V0(),H=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,X=await n0(H,{headers:{Authorization:`Bearer ${Y}`}});if(!X.ok){z(`feishu: download ${J} HTTP ${X.status}: ${(await X.text()).slice(0,200)}`);return}let V=Buffer.from(await X.arrayBuffer());j6(_8,{recursive:!0});let W=Q?Q.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,G=N4(_8,`${Date.now()}-${W}`);return FZ(G,V),z(`feishu: downloaded ${J} ${G} (${V.length}B)`),G}catch(Y){z(`feishu: download ${J} failed: ${Y instanceof Error?Y.message:Y}`);return}}function SG($){return CG.has(BG($).toLowerCase())}async function fZ($){let Z=await V0(),J=new Blob([Uint8Array.from(await PZ($))]),Q=new FormData;Q.append("image_type","message"),Q.append("image",J,d0($));let H=await(await n0("https://open.feishu.cn/open-apis/im/v1/images",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Q})).json();if(H?.code!==0)return z(`feishu: uploadImage ${$} code=${H.code} msg=${H.msg}`),null;return H.data?.image_key??null}async function g6($){try{let Z=AZ($);if(!Z.isFile())return z(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>wZ)return z(`feishu: uploadImageKey oversize — ${$} (${(Z.size/1024/1024).toFixed(1)} MB)`),null}catch(Z){return z(`feishu: uploadImageKey stat failed — ${$}: ${Z}`),null}return fZ($)}async function bG($){let Z=await V0(),J=new Blob([Uint8Array.from(await PZ($))]),Q=new FormData;Q.append("file_type","stream"),Q.append("file_name",d0($)),Q.append("file",J,d0($));let H=await(await n0("https://open.feishu.cn/open-apis/im/v1/files",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Q})).json();if(H?.code!==0)return z(`feishu: uploadFile ${$} code=${H.code} msg=${H.msg}`),null;return H.data?.file_key??null}async function vZ($,Z){try{let J=await a.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 z(`feishu: sendImage rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return z(`feishu: sendImage failed chat=${$}: ${J}`),null}}async function hZ($,Z){try{let J=await a.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 z(`feishu: sendFile rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return z(`feishu: sendFile failed chat=${$}: ${J}`),null}}async function c6($,Z){try{let Q=AZ(Z);if(!Q.isFile())return await O($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Q.size>wZ)return await O($,`❌ 出站文件: ${d0(Z)} 超过 30 MB (${(Q.size/1024/1024).toFixed(1)} MB)`),!1}catch(Q){return await O($,`❌ 出站文件: 无法读取 ${Z} (${Q})`),!1}let J=SG(Z);try{if(J){let Q=await fZ(Z);if(!Q)return await O($,`❌ 出站图片上传失败: ${d0(Z)}`),!1;return await vZ($,Q)!=null}else{let Q=await bG(Z);if(!Q)return await O($,`❌ 出站文件上传失败: ${d0(Z)}`),!1;return await hZ($,Q)!=null}}catch(Q){return z(`feishu: uploadAndSend ${Z} failed: ${Q}`),await O($,`❌ 出站文件异常: ${d0(Z)} — ${Q}`),!1}}function m6($){j6($,{recursive:!0}),z(`feishu: provisioned ${$}`);let Z=N4(zZ(),".codex","config.toml");try{j6(N4(zZ(),".codex"),{recursive:!0});let J="";try{J=i0(Z,"utf8")}catch{}let Q=`[projects.${JSON.stringify($)}]`;if(!J.includes(Q)){let Y=J.trimEnd();J=`${Y}${Y?`
58
58
 
59
59
  `:""}${Q}
60
60
  trust_level = "trusted"
61
- `,PZ(Z,J)}}catch(J){G(`feishu: codex trust write failed for ${$}: ${J}`)}try{LZ("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function k2(){try{let $=LZ(`"${X2()}" login status 2>&1`,{timeout:1e4}).toString();return/Logged in using ChatGPT/i.test($)}catch{return!1}}function y2($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var UZ,MZ,RZ,K$,r,qz=15000,k4="",GZ=0,q8=null,Y$,Q$,l,h,qZ=200,jZ,J$,P2,SZ=31457280,Ez;var n=E(()=>{y$();k1();c0();D$();w();h$();x$();T1();WZ();UZ=S.feishu.app_id,MZ=S.feishu.app_secret,RZ=S.runtime.projects_root,K$=new Map;r=new BZ.Client({appId:UZ,appSecret:MZ,disableTokenCache:!1});Y$=new Map,Q$=new Map;l=new Map;h=new Map;jZ=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;J$=new Map;P2=[0,1000,4000];Ez=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});function gZ($,Z){if($===300305)return!0;if($!==300315)return!1;let J=Z?.message??"";return/(?:code\s*[:=]\s*300305\b|number of card components[^\n.]{0,60}exceed)/i.test(J)}function IZ($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function z0($){let Z=I$.get($);if(!Z)Z={sequence:0,queue:Promise.resolve(),elementCount:0,deadElements:new Set},I$.set($,Z);return Z}function hZ($){_$.delete($),_$.add($);while(_$.size>fz){let Z=_$.values().next().value;if(typeof Z!=="string")break;_$.delete(Z)}}function c$($,Z,J){_$.delete($),I$.delete($);let Q=z0($);Q.elementCount=Z,Q.onFailure=J,Q.writeDead=!1,Q.closing=!1}function m8($){return I$.get($)?.elementCount??0}function g1($,Z){return I$.get($)?.deadElements.has(Z)??!1}function cZ($,Z){I$.get($)?.deadElements.delete(Z)}function v4($){if(_$.has($))return;let Z=z0($);if(Z.closing)return;Z.writeDead=!0,X$($)}function h4($){let Z=z0($);return Z.sequence+=1,Z.sequence}function vz($,Z){$.deadElements.add(Z)}async function E2($,Z,J){let Q=await X0(),Y=await fetch(`${Cz}${Z}`,{method:$,headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},...J?{body:JSON.stringify(J)}:{},signal:AbortSignal.timeout(bz)}),H=await Y.json();if(!Y.ok||H?.code!==0){let V=typeof H?.code==="number"?H.code:Y.status,X=Y.headers.get("x-tt-logid")??Y.headers.get("x-request-id")??Y.headers.get("request-id")??void 0,W=Error(`cardkit ${$} ${Z}: HTTP ${Y.status} code=${String(H?.code??"MISS")} msg=${H?.msg??"MISS"}${X?` log_id=${X}`:""}`);throw W.code=V,W.httpStatus=Y.status,W.logId=X,W}return H?.data}function hz($){return new Promise((Z)=>setTimeout(Z,$))}function gz($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function Iz($){let Z=h4($);await E2("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function u8($,Z,J,Q,Y=!1,H={}){let V=(X)=>{let W=typeof X==="object"&&X!==null?X:null,z={cardId:$,operation:Z,...H,code:W?.code,httpStatus:W?.httpStatus,logId:W?.logId,message:X instanceof Error?X.message:String(X)};try{if(!Y)z0($).onFailure?.(z.code,z)}catch(K){G(`cardkit failure callback ${$}: ${K}`)}try{Q?.(z)}catch(K){G(`cardkit per-call failure callback ${$}: ${K}`)}};try{await J();return}catch(X){if(!gz(X)){G(`cardkit ${Z} ${$}: ${X}`),V(X);return}G(`cardkit ${Z} ${$}: streaming closed (code=${X.code}) — reopening`)}try{await Iz($)}catch(X){G(`cardkit STREAMING_REOPEN_FAILED ${$}: ${X}`),V(X);return}try{await J()}catch(X){G(`cardkit ${Z} ${$} retry-after-reopen: ${X}`),V(X)}}function cz($){return typeof $==="object"&&$!==null&&$.code===200740}async function r$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:Sz,Q=null;for(let Y=0;Y<J.length;Y++){let H=J[Y]??0;if(H>0)await hz(H);try{let V=await E2("POST","/cards/id_convert",{message_id:$});if(typeof V?.card_id!=="string"||!V.card_id)throw Error("cardkit POST /cards/id_convert: missing card_id");return V.card_id}catch(V){if(Q=V,!cz(V)||Y===J.length-1)throw V;let X=J[Y+1]??0;G(`cardkit id_convert ${$}: empty result, retry ${Y+2}/${J.length} in ${X}ms`)}}throw Q}async function m$($){let Z=I$.get($);if(!Z)return;await Z.queue}function W$($,Z,J={},Q){if(_$.has($))return Promise.resolve();let Y=z0($);if(Y.closing||Y.writeDead)return Promise.resolve();let H=U0(Z),V=H.element_id;return Y.queue=Y.queue.then(()=>u8($,"addElement",async()=>{if(Y.writeDead)return;let X=h4($);if(await E2("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([H]),sequence:X}),Y.elementCount+=1,V)Y.deadElements.delete(V)},(X)=>{if(V)vz(Y,V);Q?.(X.code,X)},!1,{elementId:V,targetElementId:J.targetElementId})),Y.queue}function d($,Z,J,Q,Y=!0){if(_$.has($))return Promise.resolve();let H=z0($);if(H.closing||H.writeDead||H.deadElements.has(Z))return Promise.resolve();let V=U0(J);return H.queue=H.queue.then(()=>u8($,`replaceElement ${Z}`,async()=>{if(H.writeDead||H.deadElements.has(Z))return;let X=h4($);await E2("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(V),sequence:X})},(X)=>Q?.(X.code,X),!Y,{elementId:Z})),H.queue}async function U$($,Z,J,Q={}){if(_$.has($))return!1;let Y=z0($);if(Y.closing||Y.writeDead||Y.deadElements.has(Z))return!1;let H=!1;return await d($,Z,J,()=>{H=!0},Q.notifyCardFailure!==!1),!H&&!Y.writeDead&&!Y.deadElements.has(Z)}async function y0($,Z,J={}){return(await g4($,Z,J)).landed}async function g4($,Z,J={}){if(_$.has($))return{landed:!1};let Q=z0($);if(Q.closing||Q.writeDead)return{landed:!1};let Y=Z.element_id,H;return await W$($,Z,J,(V,X)=>{H=X}),{landed:!H&&!Q.writeDead&&!(Y&&Q.deadElements.has(Y)),...H?{failure:H}:{}}}function G0($,Z){if(_$.has($)||I$.get($)?.closing||I$.get($)?.writeDead)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Q=r0.get($);if(!Q)Q={latest:J,lastSent:"",timer:null},r0.set($,Q);else Q.latest=J;if(Q.timer)return;Q.timer=setTimeout(()=>{let Y=r0.get($);if(!Y)return;if(_$.has($)){r0.delete($);return}if(Y.timer=null,Y.latest===Y.lastSent)return;let H=Y.latest;q$($,{config:{summary:{content:H}}}).then((V)=>{let X=r0.get($);if(V&&X===Y)X.lastSent=H})},wz)}function X$($){let Z=r0.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;r0.delete($)}function I4($,Z){return q$($,Z).then(()=>{})}async function q$($,Z){if(_$.has($))return!1;let J=z0($);if(J.closing||J.writeDead)return!1;let Q=!1,Y=!1;return J.queue=J.queue.then(()=>u8($,"patchSettings",async()=>{if(_$.has($)||J.writeDead)return;let H=h4($);await E2("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:H}),Q=!0},()=>{Y=!0},!0)),await J.queue,Q&&!Y&&!_$.has($)&&!J.writeDead}async function b$($){let Z=I$.get($);if(!Z){hZ($),X$($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,X$($),await Z.queue,hZ($),I$.delete($)}var Cz="https://open.feishu.cn/open-apis/cardkit/v1",bz=15000,Sz,I$,r0,wz=1500,_$,fz=5000;var t0=E(()=>{n();w();x$();Sz=[0,250,750,1500];I$=new Map,r0=new Map;_$=new Set});function c4($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function m4($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function mz($,Z,J=12000){if(Z==null||Z<=0)return null;if(Z<=J)return 0;let Q=Z-J,Y=Math.max(0,$-J),H=Math.max(0,Q-Y);return Math.round(Math.min(100,Math.max(0,H/Q*100)))}function uZ($,Z,J){let Q=mz($,Z,J??12000);if(Q==null)return null;return{used:Math.min(100,Math.max(0,100-Q)),remaining:Q}}function mZ($){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 u4($,Z){let J=mZ($);return Z!=null&&Z>0?`${J}/${mZ(Z)}`:`${J}/--`}function pZ($,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))}%`}import{isAbsolute as p8,relative as uz}from"node:path";function l4($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function i4($){return $==="write_stdin"||$.endsWith(".write_stdin")}function lz($){return l4($)||i4($)}function d4($){return $==="FileChange"||$==="fileChange"}function N2($){return $==="WebSearch"||$==="webSearch"}function n4($){return $==="WebFetch"||$==="webFetch"}function a8($){return $==="MCP"}function o4($){return $==="ImageGeneration"||$==="imageGeneration"}function r8($){return $==="Agent"||$==="Task"}function a4($){return $==="Read"}function r4($){return $==="Write"}function t4($){return $==="Edit"||$==="NotebookEdit"}function s4($){return $==="MultiEdit"}function t8($){return $==="Glob"||$==="Grep"||$==="LS"}function e4($){return $==="TodoWrite"}function $9($){return $==="ExitPlanMode"}function Z9($){return $.startsWith(iZ)}function dZ($){return Z9($)?$.slice(iZ.length):$}function s0($){if(Z9($))return"服务端工具";if(d4($))return"文件变更";if(N2($))return"网页搜索";if(n4($))return"网页读取";if(o4($))return"图片生成";if(a4($))return"读取文件";if(r4($))return"写入文件";if(t4($)||s4($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(e4($))return"更新待办";if($9($))return"确认计划";if($==="Task")return"子任务";return lz($)?"Bash":$}function _0($,Z){let J=(Q,Y)=>Q.length>Y?Q.slice(0,Y)+"…":Q;if(Z9($))return J(iz($,Z),80);if(!Z||typeof Z!=="object")return"";if(l4($))return dz(Z);if(i4($))return nz(Z);if(d4($))return J(rz(Z),80);if(N2($))return J(zJ(Z),80);if(n4($))return J(QG(Z),80);if(a8($))return J(HG(Z),80);if(o4($))return J(XG(Z),80);if(r8($))return J(WG(Z),80);if(a4($))return J(tz(Z),80);if(r4($))return J(sz(Z),80);if(t4($))return J(ez(Z),80);if(s4($))return J($G(Z),80);if(t8($))return J(ZG($,Z),80);if(e4($))return J(JG(Z),80);if($9($))return J(C2(Z)||"提交计划",80);switch($){case"Skill":return J(String(Z.skill??""),80)}for(let Q of Object.values(Z))if(typeof Q==="string"&&Q)return J(Q,80);return""}function iz($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:dZ($),Q=C2(Z?.input);return Q?`${J}: ${Q}`:J}function dz($){let Z=(H,V)=>H.length>V?H.slice(0,V)+"…":H,J=oZ($);if(J.description)return Z(J.description.replace(/\s+/g," "),80);let Q=J.command;if(!Q)return"";let Y=Q.split(/\r?\n/).map((H)=>H.trim()).filter(Boolean);if(Y.length<=1)return Z(Q.replace(/\s+/g," "),80);return`Shell 脚本 · ${Y.length} 行 · ${Z(O1(Q),46)}`}function nZ($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function nz($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${nZ($)}${J}`}function oZ($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Q=x6(Z);return{description:Q.description||J,command:Q.command}}function u$($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
61
+ `,FZ(Z,J)}}catch(J){z(`feishu: codex trust write failed for ${$}: ${J}`)}try{DZ("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function E2(){try{let $=DZ(`"${V2()}" login status 2>&1`,{timeout:1e4}).toString();return/Logged in using ChatGPT/i.test($)}catch{return!1}}function N2($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var MZ,RZ,OZ,K$,a,LG=15000,E4="",KZ=0,B6=null,Y$,Q$,l,h,BZ=200,jZ,J$,A2,wZ=31457280,CG;var n=k(()=>{N$();E1();c0();D$();w();h$();x$();T1();GZ();MZ=b.feishu.app_id,RZ=b.feishu.app_secret,OZ=b.runtime.projects_root,K$=new Map;a=new LZ.Client({appId:MZ,appSecret:RZ,disableTokenCache:!1});Y$=new Map,Q$=new Map;l=new Map;h=new Map;jZ=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;J$=new Map;A2=[0,1000,4000];CG=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});function gZ($,Z){if($===300305)return!0;if($!==300315)return!1;let J=Z?.message??"";return/(?:code\s*[:=]\s*300305\b|number of card components[^\n.]{0,60}exceed)/i.test(J)}function cZ($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function G0($){let Z=g$.get($);if(!Z)Z={sequence:0,queue:Promise.resolve(),elementCount:0,deadElements:new Set},g$.set($,Z);return Z}function IZ($){_$.delete($),_$.add($);while(_$.size>IG){let Z=_$.values().next().value;if(typeof Z!=="string")break;_$.delete(Z)}}function c$($,Z,J){_$.delete($),g$.delete($);let Q=G0($);Q.elementCount=Z,Q.onFailure=J,Q.writeDead=!1,Q.closing=!1}function u6($){return g$.get($)?.elementCount??0}function I1($,Z){return g$.get($)?.deadElements.has(Z)??!1}function mZ($,Z){g$.get($)?.deadElements.delete(Z)}function v4($){if(_$.has($))return;let Z=G0($);if(Z.closing)return;Z.writeDead=!0,V$($)}function h4($){let Z=G0($);return Z.sequence+=1,Z.sequence}function gG($,Z){$.deadElements.add(Z)}async function k2($,Z,J){let Q=await V0(),Y=await fetch(`${wG}${Z}`,{method:$,headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json"},...J?{body:JSON.stringify(J)}:{},signal:AbortSignal.timeout(fG)}),H=await Y.json();if(!Y.ok||H?.code!==0){let X=typeof H?.code==="number"?H.code:Y.status,V=Y.headers.get("x-tt-logid")??Y.headers.get("x-request-id")??Y.headers.get("request-id")??void 0,W=Error(`cardkit ${$} ${Z}: HTTP ${Y.status} code=${String(H?.code??"MISS")} msg=${H?.msg??"MISS"}${V?` log_id=${V}`:""}`);throw W.code=X,W.httpStatus=Y.status,W.logId=V,W}return H?.data}function cG($){return new Promise((Z)=>setTimeout(Z,$))}function mG($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function uG($){let Z=h4($);await k2("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function p6($,Z,J,Q,Y=!1,H={}){let X=(V)=>{let W=typeof V==="object"&&V!==null?V:null,G={cardId:$,operation:Z,...H,code:W?.code,httpStatus:W?.httpStatus,logId:W?.logId,message:V instanceof Error?V.message:String(V)};try{if(!Y)G0($).onFailure?.(G.code,G)}catch(K){z(`cardkit failure callback ${$}: ${K}`)}try{Q?.(G)}catch(K){z(`cardkit per-call failure callback ${$}: ${K}`)}};try{await J();return}catch(V){if(!mG(V)){z(`cardkit ${Z} ${$}: ${V}`),X(V);return}z(`cardkit ${Z} ${$}: streaming closed (code=${V.code}) — reopening`)}try{await uG($)}catch(V){z(`cardkit STREAMING_REOPEN_FAILED ${$}: ${V}`),X(V);return}try{await J()}catch(V){z(`cardkit ${Z} ${$} retry-after-reopen: ${V}`),X(V)}}function pG($){return typeof $==="object"&&$!==null&&$.code===200740}async function r$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:vG,Q=null;for(let Y=0;Y<J.length;Y++){let H=J[Y]??0;if(H>0)await cG(H);try{let X=await k2("POST","/cards/id_convert",{message_id:$});if(typeof X?.card_id!=="string"||!X.card_id)throw Error("cardkit POST /cards/id_convert: missing card_id");return X.card_id}catch(X){if(Q=X,!pG(X)||Y===J.length-1)throw X;let V=J[Y+1]??0;z(`cardkit id_convert ${$}: empty result, retry ${Y+2}/${J.length} in ${V}ms`)}}throw Q}async function m$($){let Z=g$.get($);if(!Z)return;await Z.queue}function W$($,Z,J={},Q){if(_$.has($))return Promise.resolve();let Y=G0($);if(Y.closing||Y.writeDead)return Promise.resolve();let H=U0(Z),X=H.element_id;return Y.queue=Y.queue.then(()=>p6($,"addElement",async()=>{if(Y.writeDead)return;let V=h4($);if(await k2("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([H]),sequence:V}),Y.elementCount+=1,X)Y.deadElements.delete(X)},(V)=>{if(X)gG(Y,X);Q?.(V.code,V)},!1,{elementId:X,targetElementId:J.targetElementId})),Y.queue}function i($,Z,J,Q,Y=!0){if(_$.has($))return Promise.resolve();let H=G0($);if(H.closing||H.writeDead||H.deadElements.has(Z))return Promise.resolve();let X=U0(J);return H.queue=H.queue.then(()=>p6($,`replaceElement ${Z}`,async()=>{if(H.writeDead||H.deadElements.has(Z))return;let V=h4($);await k2("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(X),sequence:V})},(V)=>Q?.(V.code,V),!Y,{elementId:Z})),H.queue}async function U$($,Z,J,Q={}){if(_$.has($))return!1;let Y=G0($);if(Y.closing||Y.writeDead||Y.deadElements.has(Z))return!1;let H=!1;return await i($,Z,J,()=>{H=!0},Q.notifyCardFailure!==!1),!H&&!Y.writeDead&&!Y.deadElements.has(Z)}async function E0($,Z,J={}){return(await I4($,Z,J)).landed}async function I4($,Z,J={}){if(_$.has($))return{landed:!1};let Q=G0($);if(Q.closing||Q.writeDead)return{landed:!1};let Y=Z.element_id,H;return await W$($,Z,J,(X,V)=>{H=V}),{landed:!H&&!Q.writeDead&&!(Y&&Q.deadElements.has(Y)),...H?{failure:H}:{}}}function z0($,Z){if(_$.has($)||g$.get($)?.closing||g$.get($)?.writeDead)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Q=r0.get($);if(!Q)Q={latest:J,lastSent:"",timer:null},r0.set($,Q);else Q.latest=J;if(Q.timer)return;Q.timer=setTimeout(()=>{let Y=r0.get($);if(!Y)return;if(_$.has($)){r0.delete($);return}if(Y.timer=null,Y.latest===Y.lastSent)return;let H=Y.latest;q$($,{config:{summary:{content:H}}}).then((X)=>{let V=r0.get($);if(X&&V===Y)V.lastSent=H})},hG)}function V$($){let Z=r0.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;r0.delete($)}function g4($,Z){return q$($,Z).then(()=>{})}async function q$($,Z){if(_$.has($))return!1;let J=G0($);if(J.closing||J.writeDead)return!1;let Q=!1,Y=!1;return J.queue=J.queue.then(()=>p6($,"patchSettings",async()=>{if(_$.has($)||J.writeDead)return;let H=h4($);await k2("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:H}),Q=!0},()=>{Y=!0},!0)),await J.queue,Q&&!Y&&!_$.has($)&&!J.writeDead}async function S$($){let Z=g$.get($);if(!Z){IZ($),V$($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,V$($),await Z.queue,IZ($),g$.delete($)}var wG="https://open.feishu.cn/open-apis/cardkit/v1",fG=15000,vG,g$,r0,hG=1500,_$,IG=5000;var t0=k(()=>{n();w();x$();vG=[0,250,750,1500];g$=new Map,r0=new Map;_$=new Set});function c4($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function m4($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function lG($,Z,J=12000){if(Z==null||Z<=0)return null;if(Z<=J)return 0;let Q=Z-J,Y=Math.max(0,$-J),H=Math.max(0,Q-Y);return Math.round(Math.min(100,Math.max(0,H/Q*100)))}function pZ($,Z,J){let Q=lG($,Z,J??12000);if(Q==null)return null;return{used:Math.min(100,Math.max(0,100-Q)),remaining:Q}}function uZ($){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 u4($,Z){let J=uZ($);return Z!=null&&Z>0?`${J}/${uZ(Z)}`:`${J}/--`}function lZ($,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))}%`}import{isAbsolute as l6,relative as dG}from"node:path";function l4($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function d4($){return $==="write_stdin"||$.endsWith(".write_stdin")}function nG($){return l4($)||d4($)}function i4($){return $==="FileChange"||$==="fileChange"}function y2($){return $==="WebSearch"||$==="webSearch"}function n4($){return $==="WebFetch"||$==="webFetch"}function r6($){return $==="MCP"}function o4($){return $==="ImageGeneration"||$==="imageGeneration"}function t6($){return $==="Agent"||$==="Task"}function a4($){return $==="Read"}function r4($){return $==="Write"}function t4($){return $==="Edit"||$==="NotebookEdit"}function s4($){return $==="MultiEdit"}function s6($){return $==="Glob"||$==="Grep"||$==="LS"}function e4($){return $==="TodoWrite"}function $9($){return $==="ExitPlanMode"}function Z9($){return $.startsWith(iZ)}function nZ($){return Z9($)?$.slice(iZ.length):$}function s0($){if(Z9($))return"服务端工具";if(i4($))return"文件变更";if(y2($))return"网页搜索";if(n4($))return"网页读取";if(o4($))return"图片生成";if(a4($))return"读取文件";if(r4($))return"写入文件";if(t4($)||s4($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(e4($))return"更新待办";if($9($))return"确认计划";if($==="Task")return"子任务";return nG($)?"Bash":$}function _0($,Z){let J=(Q,Y)=>Q.length>Y?Q.slice(0,Y)+"…":Q;if(Z9($))return J(oG($,Z),80);if(!Z||typeof Z!=="object")return"";if(l4($))return aG(Z);if(d4($))return rG(Z);if(i4($))return J(eG(Z),80);if(y2($))return J(zJ(Z),80);if(n4($))return J(Xz(Z),80);if(r6($))return J(Wz(Z),80);if(o4($))return J(zz(Z),80);if(t6($))return J(Kz(Z),80);if(a4($))return J($z(Z),80);if(r4($))return J(Zz(Z),80);if(t4($))return J(Jz(Z),80);if(s4($))return J(Qz(Z),80);if(s6($))return J(Yz($,Z),80);if(e4($))return J(Hz(Z),80);if($9($))return J(C2(Z)||"提交计划",80);switch($){case"Skill":return J(String(Z.skill??""),80)}for(let Q of Object.values(Z))if(typeof Q==="string"&&Q)return J(Q,80);return""}function oG($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:nZ($),Q=C2(Z?.input);return Q?`${J}: ${Q}`:J}function aG($){let Z=(H,X)=>H.length>X?H.slice(0,X)+"…":H,J=aZ($);if(J.description)return Z(J.description.replace(/\s+/g," "),80);let Q=J.command;if(!Q)return"";let Y=Q.split(/\r?\n/).map((H)=>H.trim()).filter(Boolean);if(Y.length<=1)return Z(Q.replace(/\s+/g," "),80);return`Shell 脚本 · ${Y.length} 行 · ${Z(O1(Q),46)}`}function oZ($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function rG($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${oZ($)}${J}`}function aZ($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Q=y8(Z);return{description:Q.description||J,command:Q.command}}function u$($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
62
62
  ${$}
63
- ${J}`}function K0($,Z=pz,J=""){if($.length<=Z)return u$($,J);let Q=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,u$(`${Q}
63
+ ${J}`}function K0($,Z=iG,J=""){if($.length<=Z)return u$($,J);let Q=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,u$(`${Q}
64
64
  ... output 已截断 ...`,J)].join(`
65
- `)}function b($){return"`"+String($??"").replace(/`/g,"'")+"`"}function S$($,Z=3000){return u$(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 Q=Z[J];if(typeof Q==="string"&&Q.length>0)return Q}for(let J of Object.values(Z))if(typeof J==="string"&&J.length>0)return J;return""}function aZ($,Z,J){let Q=oZ($),Y=Q.command,H=Q.description,V=[];if(H)V.push(`**目的**: ${H}`);let X=$?.cwd??$?.workdir;if(X)V.push(`**cwd**: ${b(X)}`);if($?.source)V.push(`**source**: ${b($.source)}`);if(V.length>0)V.push("");if(V.push("**命令**"),V.push(u$(Y||"(空命令)","bash")),J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(K0(Z));return V.join(`
66
- `)}function rZ($,Z,J){let Q=[],Y=$?.session_id??$?.sessionId;if(Q.push(`**操作**: ${nZ($)}`),Y!==void 0)Q.push(`**session**: ${b(Y)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let H=$.chars==="\x03"?"^C":$.chars;Q.push(""),Q.push("**输入**"),Q.push(u$(H))}if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("---"),Q.push("**output:**"),Q.push(K0(Z));return Q.join(`
67
- `)}function tZ($){return Array.isArray($?.changes)?$.changes:[]}function sZ($){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&&p8(J)&&p8(Z)){let Q=uz(Z,J);if(Q&&!Q.startsWith("..")&&!p8(Q))return Q}return J}function oz($){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 eZ($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function i8($){let Z=oz($);if(eZ($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function d8($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function n8($){let Z=0,J=0;for(let Q of $.split(/\r?\n/)){if(Q.startsWith("+++")||Q.startsWith("---"))continue;if(Q.startsWith("+"))Z++;if(Q.startsWith("-"))J++}return{added:Z,removed:J}}function $J($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function o8($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function az($){return $.length>1800?$.slice(0,1800)+`
68
- ... diff 已截断 ...`:$}function rz($){let Z=tZ($),J=sZ($);if(Z.length===0){let W=typeof $?.reason==="string"?$.reason.trim():"",z=$?.grantRoot?x2($.grantRoot):"";if(W&&z)return`${W} · ${z}`;return W||(z?`申请修改 ${z}`:"")}let Q=Z.map((W)=>n8(d8(W))).reduce($J,{added:0,removed:0}),Y=o8(Q),H=[...new Set(Z.map(i8))],V=x2(Z[0]?.path,J),X=Y?` · ${Y}`:"";if(Z.length===1)return`${H[0]} ${V}${X}`;return`${Z.length} 个文件 · ${H.join("/")} · ${V} 等${X}`}function ZJ($,Z,J){let Q=tZ($),Y=sZ($),H=[];if(Q.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"";if(z)H.push(`**原因**: ${z}`);if($?.grantRoot)H.push(`**范围**: ${b(x2($.grantRoot))}`);if(J)H.push(""),H.push(J);if(Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(u$(Z.slice(0,3000)));return H.length>0?H.join(`
69
- `):u$(JSON.stringify($??{},null,2).slice(0,2000))}let V=Q.map((z)=>n8(d8(z))).reduce($J,{added:0,removed:0}),X=o8(V);if(H.push(`**文件**: ${Q.length} 个`),X)H.push(`**行数**: ${X}`);if($?.status)H.push(`**状态**: ${b($.status)}`);let W=Q.slice(0,5);for(let z of W){let K=d8(z),_=o8(n8(K)),j=x2(z?.path,Y),B=_?`**${i8(z)}** ${b(j)} · ${_}`:`**${i8(z)}** ${b(j)}`;H.push(""),H.push(B);let L=eZ(z);if(L)H.push(`来自 ${b(x2(L,Y))}`);H.push(K?u$(az(K),"diff"):"_无 diff 内容_")}if(Q.length>W.length)H.push(""),H.push(`还有 ${Q.length-W.length} 个文件未展开显示。`);if(J)H.push(""),H.push(J);return H.join(`
70
- `)}function E0($){return String($?.file_path??$?.path??$?.notebook_path??"")}function tz($){let Z=E0($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function sz($){let Z=E0($),J=typeof $?.content==="string"?$.content:"",Q=J?J.split(/\r?\n/).length:0;return Z&&Q?`${Z} · ${Q} 行`:Z}function ez($){let Z=E0($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function $G($){let Z=E0($),J=Array.isArray($?.edits)?$.edits.length:0,Q=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Q}`:`批量编辑${Q}`}function ZG($,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 JJ($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function JG($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Y of Z){let H=JJ(Y?.status);J.set(H,(J.get(H)??0)+1)}let Q=[...J.entries()].map(([Y,H])=>`${Y} ${H}`).join(" · ");return`${Z.length} 项${Q?` · ${Q}`:""}`}function QG($){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(K0(Z,1200))}function QJ($,Z,J){let Q=[],Y=E0($);if(Y)Q.push(`**路径**: ${b(Y)}`);if($?.offset!=null)Q.push(`**offset**: ${b($.offset)}`);if($?.limit!=null)Q.push(`**limit**: ${b($.limit)}`);if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("_内容已读取,未展开到群聊卡片。_");return Q.length>0?Q.join(`
71
- `):S$($??{},2000)}function YJ($,Z,J){let Q=[],Y=E0($),H=typeof $?.content==="string"?$.content:"";if(Y)Q.push(`**路径**: ${b(Y)}`);if(H){let V=H.split(/\r?\n/).length;Q.push(`**内容**: ${V} 行 / ${H.length} 字符`),Q.push(K0(H,1200))}if(J)Q.push(""),Q.push(J);return c1(Q,Z),Q.length>0?Q.join(`
72
- `):S$($??{},2000)}function HJ($,Z,J){let Q=[],Y=E0($);if(Y)Q.push(`**路径**: ${b(Y)}`);if($?.cell_id)Q.push(`**cell**: ${b($.cell_id)}`);if($?.edit_mode)Q.push(`**模式**: ${b($.edit_mode)}`);if($?.replace_all)Q.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Q.push(""),Q.push("**查找**"),Q.push(K0($.old_string,800));let H=typeof $?.new_string==="string"?$.new_string:typeof $?.new_source==="string"?$.new_source:"";if(H)Q.push(""),Q.push("**替换为**"),Q.push(K0(H,800));if(J)Q.push(""),Q.push(J);return c1(Q,Z),Q.length>0?Q.join(`
73
- `):S$($??{},2000)}function VJ($,Z,J){let Q=[],Y=E0($),H=Array.isArray($?.edits)?$.edits:[];if(Y)Q.push(`**路径**: ${b(Y)}`);Q.push(`**编辑**: ${H.length} 处`);for(let[V,X]of H.slice(0,5).entries()){if(Q.push(""),Q.push(`**#${V+1}${X?.replace_all?" · 全局替换":""}**`),typeof X?.old_string==="string")Q.push("查找:"),Q.push(K0(X.old_string,500));if(typeof X?.new_string==="string")Q.push("替换为:"),Q.push(K0(X.new_string,500))}if(H.length>5)Q.push(""),Q.push(`还有 ${H.length-5} 处编辑未展开显示。`);if(J)Q.push(""),Q.push(J);return c1(Q,Z),Q.join(`
74
- `)}function XJ($,Z,J,Q){let Y=[];if($==="Glob"){if(Y.push("**动作**: 匹配文件"),Z?.pattern)Y.push(`**pattern**: ${b(Z.pattern)}`);if(Z?.path)Y.push(`**path**: ${b(Z.path)}`)}else if($==="Grep"){if(Y.push("**动作**: 搜索文件"),Z?.pattern)Y.push(`**pattern**: ${b(Z.pattern)}`);if(Z?.path)Y.push(`**path**: ${b(Z.path)}`);if(Z?.glob)Y.push(`**glob**: ${b(Z.glob)}`);if(Z?.type)Y.push(`**type**: ${b(Z.type)}`);if(Z?.output_mode)Y.push(`**output**: ${b(Z.output_mode)}`)}else{if(Y.push("**动作**: 列目录"),Z?.path)Y.push(`**path**: ${b(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Y.push(`**ignore**: ${Z.ignore.map(b).join(" ")}`)}if(Q)Y.push(""),Y.push(Q);return c1(Y,J),Y.join(`
75
- `)}function WJ($,Z,J){let Q=Array.isArray($?.todos)?$.todos:[],Y=[`**待办**: ${Q.length} 项`];for(let H of Q.slice(0,12)){let V=JJ(H?.status),X=String(H?.content??H?.activeForm??"").trim()||"(空)";Y.push(`- ${V}: ${X}`)}if(Q.length>12)Y.push(`- 还有 ${Q.length-12} 项未显示`);if(J)Y.push(""),Y.push(J);return c1(Y,Z),Y.join(`
76
- `)}function s8($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function e8($,Z){return s8(Z)??$?.action??{}}function $7($,Z){let J=e8($,Z),Q=Array.isArray(J?.queries)?J.queries.filter((H)=>typeof H==="string"&&H.length>0):[],Y=typeof J?.query==="string"&&J.query.length>0?J.query:typeof $?.query==="string"&&$.query.length>0?$.query:"";return Q.length>0?Q:Y?[Y]:[]}function Z7($,Z){let J=e8($,Z);return String(J?.url??$?.url??"")}function zJ($){let Z=$7($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=Z7($,null);if(J)return J;let Q=$?.action?.type;return typeof Q==="string"&&Q!=="other"?Q:""}function YG($,Z){let J=$7($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Q=Z7($,Z);if(Q)return Q;return zJ($)}function GJ($,Z,J){let Q=e8($,Z),Y=$7($,Z),H=Z7($,Z),V=[],X=typeof Q?.type==="string"?Q.type:"";if(X==="search"||Y.length>0){if(V.push("**动作**: 搜索"),Y.length>0){V.push(""),V.push("**查询**");for(let W of Y.slice(0,6))V.push(`- ${b(W)}`);if(Y.length>6)V.push(`- 还有 ${Y.length-6} 条未显示`)}}else if(X==="open_page"){if(V.push("**动作**: 打开页面"),H)V.push(`**URL**: ${b(H)}`)}else if(X==="find_in_page"){if(V.push("**动作**: 页内查找"),H)V.push(`**URL**: ${b(H)}`);if(Q?.pattern)V.push(`**关键词**: ${b(Q.pattern)}`)}else if(V.push(`**动作**: ${X?b(X):"网页搜索"}`),H)V.push(`**URL**: ${b(H)}`);if(J)V.push(""),V.push(J);if(V.length===1&&!Y.length&&!H&&Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(u$(Z.slice(0,3000),"json"));return V.join(`
77
- `)}function KJ($,Z,J){let Q=["**动作**: 读取网页"];if($?.url)Q.push(`**URL**: ${b($.url)}`);if($?.prompt)Q.push(""),Q.push("**问题**"),Q.push(String($.prompt).slice(0,1200));if(J)Q.push(""),Q.push(J);return c1(Q,Z),Q.join(`
78
- `)}function HG($){let Z=String($?.server??""),J=String($?.tool??""),Q=Z&&J?`${Z}.${J}`:J||Z,Y=C2($?.arguments);return Y&&Q?`${Q}: ${Y}`:Q||Y}function _J($,Z,J){let Q=[];if($?.server)Q.push(`**server**: ${b($.server)}`);if($?.tool)Q.push(`**tool**: ${b($.tool)}`);let Y=$?.arguments;if(Y&&typeof Y==="object"&&Object.keys(Y).length>0){if(Q.length>0)Q.push("");Q.push("**arguments**"),Q.push(S$(Y,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null){let H=s8(Z);if(Q.push(""),Q.push("---"),Q.push("**结果**"),H&&Array.isArray(H.content)){let V=H.content.map((X)=>typeof X?.text==="string"?X.text:"").filter(Boolean);if(V.length>0)Q.push(V.join(`
79
- `).slice(0,3000));if(H.structuredContent)Q.push(""),Q.push("**structuredContent**"),Q.push(S$(H.structuredContent,2000));if(V.length===0&&!H.structuredContent)Q.push(S$(H,3000))}else Q.push(H?S$(H,3000):u$(Z.slice(0,3000)))}return Q.length>0?Q.join(`
80
- `):S$($??{},2000)}function VG($,Z,J,Q){let Y=["**类型**: 模型服务端内置工具",`**tool**: ${b(typeof Z?.tool==="string"&&Z.tool?Z.tool:dZ($))}`],H=Z?.input;if(H&&typeof H==="object")if(Y.push(""),Y.push("**input**"),Object.keys(H).length>0)Y.push(S$(H,2000));else Y.push("_provider 未提供结构化 input_");else if(H!=null&&H!=="")Y.push(`**input**: ${b(H)}`);if(Q)Y.push(""),Y.push(Q);if(J!=null)Y.push(""),Y.push("---"),Y.push("**结果**"),Y.push(K0(J,3000));return Y.join(`
81
- `)}function XG($){let Z=typeof $?.revisedPrompt==="string"?$.revisedPrompt:"",J=typeof $?.status==="string"?$.status:"";return Z||J}function qJ($,Z,J){let Q=[];if($?.status)Q.push(`**状态**: ${b($.status)}`);if($?.revisedPrompt){if(Q.length>0)Q.push("");Q.push("**提示词**"),Q.push(String($.revisedPrompt).slice(0,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null&&Z.trim())Q.push(""),Q.push("---"),Q.push("**输出**"),Q.push(b(Z.trim()));return Q.length>0?Q.join(`
82
- `):S$($??{},2000)}function WG($){let Z=typeof $?.tool==="string"?$.tool:"",J=typeof $?.prompt==="string"?$.prompt:"",Q=typeof $?.description==="string"?$.description:"",Y=typeof $?.subject==="string"?$.subject:"",H=Q||Y||J;return Z&&H?`${Z}: ${H}`:H||Z}function p4($,Z,J){let Q=[];if($?.tool)Q.push(`**tool**: ${b($.tool)}`);if($?.model)Q.push(`**model**: ${b($.model)}`);if($?.description)Q.push(`**描述**: ${$.description}`);if($?.subagent_type)Q.push(`**类型**: ${b($.subagent_type)}`);if($?.prompt){if(Q.length>0)Q.push("");Q.push("**prompt**"),Q.push(String($.prompt).slice(0,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null){Q.push(""),Q.push("---"),Q.push("**状态**");let Y=s8(Z);Q.push(Y?S$(Y,3000):u$(Z.slice(0,3000)))}return Q.length>0?Q.join(`
83
- `):S$($??{},2000)}function q0($,Z,J,Q,Y="⏳",H){let V=N2(Z)&&Q!=null?YG(J,Q):_0(Z,J),X=V.length>80?V.slice(0,80)+"…":V,W=s0(Z),z=X?`${Y} \uD83D\uDD27 ${W}: ${X}`:`${Y} \uD83D\uDD27 ${W}`,K=H?`
84
-
85
- ${H}`:"",_=l4(Z)?aZ(J,Q,H):i4(Z)?rZ(J,Q,H):Z9(Z)?VG(Z,J,Q,H):d4(Z)?ZJ(J,Q,H):N2(Z)?GJ(J,Q,H):n4(Z)?KJ(J,Q,H):a8(Z)?_J(J,Q,H):o4(Z)?qJ(J,Q,H):a4(Z)?QJ(J,Q,H):r4(Z)?YJ(J,Q,H):t4(Z)?HJ(J,Q,H):s4(Z)?VJ(J,Q,H):t8(Z)?XJ(Z,J,Q,H):e4(Z)?WJ(J,Q,H):$9(Z)?p4({prompt:C2(J)||"提交计划"},Q,H):r8(Z)?p4(J,Q,H):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+K+(Q!=null?`
65
+ `)}function S($){return"`"+String($??"").replace(/`/g,"'")+"`"}function b$($,Z=3000){return u$(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 Q=Z[J];if(typeof Q==="string"&&Q.length>0)return Q}for(let J of Object.values(Z))if(typeof J==="string"&&J.length>0)return J;return""}function rZ($,Z,J){let Q=aZ($),Y=Q.command,H=Q.description,X=[];if(H)X.push(`**目的**: ${H}`);let V=$?.cwd??$?.workdir;if(V)X.push(`**cwd**: ${S(V)}`);if($?.source)X.push(`**source**: ${S($.source)}`);if(X.length>0)X.push("");if(X.push("**命令**"),X.push(u$(Y||"(空命令)","bash")),J)X.push(""),X.push(J);if(Z!=null)X.push(""),X.push("---"),X.push("**output:**"),X.push(K0(Z));return X.join(`
66
+ `)}function tZ($,Z,J){let Q=[],Y=$?.session_id??$?.sessionId;if(Q.push(`**操作**: ${oZ($)}`),Y!==void 0)Q.push(`**session**: ${S(Y)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let H=$.chars==="\x03"?"^C":$.chars;Q.push(""),Q.push("**输入**"),Q.push(u$(H))}if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("---"),Q.push("**output:**"),Q.push(K0(Z));return Q.join(`
67
+ `)}function sZ($){return Array.isArray($?.changes)?$.changes:[]}function eZ($){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&&l6(J)&&l6(Z)){let Q=dG(Z,J);if(Q&&!Q.startsWith("..")&&!l6(Q))return Q}return J}function tG($){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 $J($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function i6($){let Z=tG($);if($J($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function n6($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function o6($){let Z=0,J=0;for(let Q of $.split(/\r?\n/)){if(Q.startsWith("+++")||Q.startsWith("---"))continue;if(Q.startsWith("+"))Z++;if(Q.startsWith("-"))J++}return{added:Z,removed:J}}function ZJ($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function a6($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function sG($){return $.length>1800?$.slice(0,1800)+`
68
+ ... diff 已截断 ...`:$}function eG($){let Z=sZ($),J=eZ($);if(Z.length===0){let W=typeof $?.reason==="string"?$.reason.trim():"",G=$?.grantRoot?x2($.grantRoot):"";if(W&&G)return`${W} · ${G}`;return W||(G?`申请修改 ${G}`:"")}let Q=Z.map((W)=>o6(n6(W))).reduce(ZJ,{added:0,removed:0}),Y=a6(Q),H=[...new Set(Z.map(i6))],X=x2(Z[0]?.path,J),V=Y?` · ${Y}`:"";if(Z.length===1)return`${H[0]} ${X}${V}`;return`${Z.length} 个文件 · ${H.join("/")} · ${X} 等${V}`}function JJ($,Z,J){let Q=sZ($),Y=eZ($),H=[];if(Q.length===0){let G=typeof $?.reason==="string"?$.reason.trim():"";if(G)H.push(`**原因**: ${G}`);if($?.grantRoot)H.push(`**范围**: ${S(x2($.grantRoot))}`);if(J)H.push(""),H.push(J);if(Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(u$(Z.slice(0,3000)));return H.length>0?H.join(`
69
+ `):u$(JSON.stringify($??{},null,2).slice(0,2000))}let X=Q.map((G)=>o6(n6(G))).reduce(ZJ,{added:0,removed:0}),V=a6(X);if(H.push(`**文件**: ${Q.length} 个`),V)H.push(`**行数**: ${V}`);if($?.status)H.push(`**状态**: ${S($.status)}`);let W=Q.slice(0,5);for(let G of W){let K=n6(G),_=a6(o6(K)),B=x2(G?.path,Y),j=_?`**${i6(G)}** ${S(B)} · ${_}`:`**${i6(G)}** ${S(B)}`;H.push(""),H.push(j);let L=$J(G);if(L)H.push(`来自 ${S(x2(L,Y))}`);H.push(K?u$(sG(K),"diff"):"_无 diff 内容_")}if(Q.length>W.length)H.push(""),H.push(`还有 ${Q.length-W.length} 个文件未展开显示。`);if(J)H.push(""),H.push(J);return H.join(`
70
+ `)}function N0($){return String($?.file_path??$?.path??$?.notebook_path??"")}function $z($){let Z=N0($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function Zz($){let Z=N0($),J=typeof $?.content==="string"?$.content:"",Q=J?J.split(/\r?\n/).length:0;return Z&&Q?`${Z} · ${Q} 行`:Z}function Jz($){let Z=N0($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function Qz($){let Z=N0($),J=Array.isArray($?.edits)?$.edits.length:0,Q=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Q}`:`批量编辑${Q}`}function Yz($,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 QJ($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function Hz($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Y of Z){let H=QJ(Y?.status);J.set(H,(J.get(H)??0)+1)}let Q=[...J.entries()].map(([Y,H])=>`${Y} ${H}`).join(" · ");return`${Z.length} 项${Q?` · ${Q}`:""}`}function Xz($){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(K0(Z,1200))}function YJ($,Z,J){let Q=[],Y=N0($);if(Y)Q.push(`**路径**: ${S(Y)}`);if($?.offset!=null)Q.push(`**offset**: ${S($.offset)}`);if($?.limit!=null)Q.push(`**limit**: ${S($.limit)}`);if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("_内容已读取,未展开到群聊卡片。_");return Q.length>0?Q.join(`
71
+ `):b$($??{},2000)}function HJ($,Z,J){let Q=[],Y=N0($),H=typeof $?.content==="string"?$.content:"";if(Y)Q.push(`**路径**: ${S(Y)}`);if(H){let X=H.split(/\r?\n/).length;Q.push(`**内容**: ${X} 行 / ${H.length} 字符`),Q.push(K0(H,1200))}if(J)Q.push(""),Q.push(J);return c1(Q,Z),Q.length>0?Q.join(`
72
+ `):b$($??{},2000)}function XJ($,Z,J){let Q=[],Y=N0($);if(Y)Q.push(`**路径**: ${S(Y)}`);if($?.cell_id)Q.push(`**cell**: ${S($.cell_id)}`);if($?.edit_mode)Q.push(`**模式**: ${S($.edit_mode)}`);if($?.replace_all)Q.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Q.push(""),Q.push("**查找**"),Q.push(K0($.old_string,800));let H=typeof $?.new_string==="string"?$.new_string:typeof $?.new_source==="string"?$.new_source:"";if(H)Q.push(""),Q.push("**替换为**"),Q.push(K0(H,800));if(J)Q.push(""),Q.push(J);return c1(Q,Z),Q.length>0?Q.join(`
73
+ `):b$($??{},2000)}function VJ($,Z,J){let Q=[],Y=N0($),H=Array.isArray($?.edits)?$.edits:[];if(Y)Q.push(`**路径**: ${S(Y)}`);Q.push(`**编辑**: ${H.length} 处`);for(let[X,V]of H.slice(0,5).entries()){if(Q.push(""),Q.push(`**#${X+1}${V?.replace_all?" · 全局替换":""}**`),typeof V?.old_string==="string")Q.push("查找:"),Q.push(K0(V.old_string,500));if(typeof V?.new_string==="string")Q.push("替换为:"),Q.push(K0(V.new_string,500))}if(H.length>5)Q.push(""),Q.push(`还有 ${H.length-5} 处编辑未展开显示。`);if(J)Q.push(""),Q.push(J);return c1(Q,Z),Q.join(`
74
+ `)}function WJ($,Z,J,Q){let Y=[];if($==="Glob"){if(Y.push("**动作**: 匹配文件"),Z?.pattern)Y.push(`**pattern**: ${S(Z.pattern)}`);if(Z?.path)Y.push(`**path**: ${S(Z.path)}`)}else if($==="Grep"){if(Y.push("**动作**: 搜索文件"),Z?.pattern)Y.push(`**pattern**: ${S(Z.pattern)}`);if(Z?.path)Y.push(`**path**: ${S(Z.path)}`);if(Z?.glob)Y.push(`**glob**: ${S(Z.glob)}`);if(Z?.type)Y.push(`**type**: ${S(Z.type)}`);if(Z?.output_mode)Y.push(`**output**: ${S(Z.output_mode)}`)}else{if(Y.push("**动作**: 列目录"),Z?.path)Y.push(`**path**: ${S(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Y.push(`**ignore**: ${Z.ignore.map(S).join(" ")}`)}if(Q)Y.push(""),Y.push(Q);return c1(Y,J),Y.join(`
75
+ `)}function GJ($,Z,J){let Q=Array.isArray($?.todos)?$.todos:[],Y=[`**待办**: ${Q.length} 项`];for(let H of Q.slice(0,12)){let X=QJ(H?.status),V=String(H?.content??H?.activeForm??"").trim()||"(空)";Y.push(`- ${X}: ${V}`)}if(Q.length>12)Y.push(`- 还有 ${Q.length-12} 项未显示`);if(J)Y.push(""),Y.push(J);return c1(Y,Z),Y.join(`
76
+ `)}function e6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function $7($,Z){return e6(Z)??$?.action??{}}function Z7($,Z){let J=$7($,Z),Q=Array.isArray(J?.queries)?J.queries.filter((H)=>typeof H==="string"&&H.length>0):[],Y=typeof J?.query==="string"&&J.query.length>0?J.query:typeof $?.query==="string"&&$.query.length>0?$.query:"";return Q.length>0?Q:Y?[Y]:[]}function J7($,Z){let J=$7($,Z);return String(J?.url??$?.url??"")}function zJ($){let Z=Z7($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=J7($,null);if(J)return J;let Q=$?.action?.type;return typeof Q==="string"&&Q!=="other"?Q:""}function Vz($,Z){let J=Z7($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Q=J7($,Z);if(Q)return Q;return zJ($)}function KJ($,Z,J){let Q=$7($,Z),Y=Z7($,Z),H=J7($,Z),X=[],V=typeof Q?.type==="string"?Q.type:"";if(V==="search"||Y.length>0){if(X.push("**动作**: 搜索"),Y.length>0){X.push(""),X.push("**查询**");for(let W of Y.slice(0,6))X.push(`- ${S(W)}`);if(Y.length>6)X.push(`- 还有 ${Y.length-6} 条未显示`)}}else if(V==="open_page"){if(X.push("**动作**: 打开页面"),H)X.push(`**URL**: ${S(H)}`)}else if(V==="find_in_page"){if(X.push("**动作**: 页内查找"),H)X.push(`**URL**: ${S(H)}`);if(Q?.pattern)X.push(`**关键词**: ${S(Q.pattern)}`)}else if(X.push(`**动作**: ${V?S(V):"网页搜索"}`),H)X.push(`**URL**: ${S(H)}`);if(J)X.push(""),X.push(J);if(X.length===1&&!Y.length&&!H&&Z!=null)X.push(""),X.push("---"),X.push("**output:**"),X.push(u$(Z.slice(0,3000),"json"));return X.join(`
77
+ `)}function _J($,Z,J){let Q=["**动作**: 读取网页"];if($?.url)Q.push(`**URL**: ${S($.url)}`);if($?.prompt)Q.push(""),Q.push("**问题**"),Q.push(String($.prompt).slice(0,1200));if(J)Q.push(""),Q.push(J);return c1(Q,Z),Q.join(`
78
+ `)}function Wz($){let Z=String($?.server??""),J=String($?.tool??""),Q=Z&&J?`${Z}.${J}`:J||Z,Y=C2($?.arguments);return Y&&Q?`${Q}: ${Y}`:Q||Y}function qJ($,Z,J){let Q=[];if($?.server)Q.push(`**server**: ${S($.server)}`);if($?.tool)Q.push(`**tool**: ${S($.tool)}`);let Y=$?.arguments;if(Y&&typeof Y==="object"&&Object.keys(Y).length>0){if(Q.length>0)Q.push("");Q.push("**arguments**"),Q.push(b$(Y,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null){let H=e6(Z);if(Q.push(""),Q.push("---"),Q.push("**结果**"),H&&Array.isArray(H.content)){let X=H.content.map((V)=>typeof V?.text==="string"?V.text:"").filter(Boolean);if(X.length>0)Q.push(X.join(`
79
+ `).slice(0,3000));if(H.structuredContent)Q.push(""),Q.push("**structuredContent**"),Q.push(b$(H.structuredContent,2000));if(X.length===0&&!H.structuredContent)Q.push(b$(H,3000))}else Q.push(H?b$(H,3000):u$(Z.slice(0,3000)))}return Q.length>0?Q.join(`
80
+ `):b$($??{},2000)}function Gz($,Z,J,Q){let Y=["**类型**: 模型服务端内置工具",`**tool**: ${S(typeof Z?.tool==="string"&&Z.tool?Z.tool:nZ($))}`],H=Z?.input;if(H&&typeof H==="object")if(Y.push(""),Y.push("**input**"),Object.keys(H).length>0)Y.push(b$(H,2000));else Y.push("_provider 未提供结构化 input_");else if(H!=null&&H!=="")Y.push(`**input**: ${S(H)}`);if(Q)Y.push(""),Y.push(Q);if(J!=null)Y.push(""),Y.push("---"),Y.push("**结果**"),Y.push(K0(J,3000));return Y.join(`
81
+ `)}function zz($){let Z=typeof $?.revisedPrompt==="string"?$.revisedPrompt:"",J=typeof $?.status==="string"?$.status:"";return Z||J}function BJ($,Z,J){let Q=[];if($?.status)Q.push(`**状态**: ${S($.status)}`);if($?.revisedPrompt){if(Q.length>0)Q.push("");Q.push("**提示词**"),Q.push(String($.revisedPrompt).slice(0,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null&&Z.trim())Q.push(""),Q.push("---"),Q.push("**输出**"),Q.push(S(Z.trim()));return Q.length>0?Q.join(`
82
+ `):b$($??{},2000)}function Kz($){let Z=typeof $?.tool==="string"?$.tool:"",J=typeof $?.prompt==="string"?$.prompt:"",Q=typeof $?.description==="string"?$.description:"",Y=typeof $?.subject==="string"?$.subject:"",H=Q||Y||J;return Z&&H?`${Z}: ${H}`:H||Z}function p4($,Z,J){let Q=[];if($?.tool)Q.push(`**tool**: ${S($.tool)}`);if($?.model)Q.push(`**model**: ${S($.model)}`);if($?.description)Q.push(`**描述**: ${$.description}`);if($?.subagent_type)Q.push(`**类型**: ${S($.subagent_type)}`);if($?.prompt){if(Q.length>0)Q.push("");Q.push("**prompt**"),Q.push(String($.prompt).slice(0,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null){Q.push(""),Q.push("---"),Q.push("**状态**");let Y=e6(Z);Q.push(Y?b$(Y,3000):u$(Z.slice(0,3000)))}return Q.length>0?Q.join(`
83
+ `):b$($??{},2000)}function q0($,Z,J,Q,Y="⏳",H){let X=y2(Z)&&Q!=null?Vz(J,Q):_0(Z,J),V=X.length>80?X.slice(0,80)+"…":X,W=s0(Z),G=V?`${Y} \uD83D\uDD27 ${W}: ${V}`:`${Y} \uD83D\uDD27 ${W}`,K=H?`
84
+
85
+ ${H}`:"",_=l4(Z)?rZ(J,Q,H):d4(Z)?tZ(J,Q,H):Z9(Z)?Gz(Z,J,Q,H):i4(Z)?JJ(J,Q,H):y2(Z)?KJ(J,Q,H):n4(Z)?_J(J,Q,H):r6(Z)?qJ(J,Q,H):o4(Z)?BJ(J,Q,H):a4(Z)?YJ(J,Q,H):r4(Z)?HJ(J,Q,H):t4(Z)?XJ(J,Q,H):s4(Z)?VJ(J,Q,H):s6(Z)?WJ(Z,J,Q,H):e4(Z)?GJ(J,Q,H):$9(Z)?p4({prompt:C2(J)||"提交计划"},Q,H):t6(Z)?p4(J,Q,H):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+K+(Q!=null?`
86
86
  ---
87
87
  **output:**
88
88
  \`\`\`
89
- `+Q.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:a(_)}]}}function m1($,Z){let J=Z.length,Q=Z.some((W)=>W.isError),Y=Z.every((W)=>W.output!==null),H=Q?"❌":Y?"✅":"⏳",V=J===1?(()=>{let W=lZ(Z[0]);return W?`${H} \uD83D\uDD27 编辑文件: ${W}`:`${H} \uD83D\uDD27 编辑文件`})():`${H} \uD83D\uDD27 编辑文件 · ${J} 次`,X=Z.map((W)=>{let z=lZ(W);return z?`\`${z}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:V}},expanded:!1,elements:[{tag:"markdown",content:a(X.join(`
90
- `))}]}}function lZ($){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 u1($,Z){let J=Z.length,Q=Z.some((W)=>W.isError),Y=Z.every((W)=>W.output!==null),H=Q?"❌":Y?"✅":"⏳",V=J===1?(()=>{let W=_0("Read",Z[0]?.input);return W?`${H} \uD83D\uDD27 Read: ${W}`:`${H} \uD83D\uDD27 Read`})():`${H} \uD83D\uDD27 Read · ${J} 次`,X=Z.map((W)=>`\`${String(W.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:V}},expanded:!1,elements:[{tag:"markdown",content:a(X.join(`
91
- `))}]}}function J9($,Z,J,Q){let Y=_0(Z,J),H=s0(Z),V=Y?`\uD83D\uDD10 等审批 · ${H}: ${Y}`:`\uD83D\uDD10 等审批 · ${H}`,X=l4(Z)?aZ(J,null):i4(Z)?rZ(J,null):d4(Z)?ZJ(J,null):N2(Z)?GJ(J,null):n4(Z)?KJ(J,null):a8(Z)?_J(J,null):o4(Z)?qJ(J,null):a4(Z)?QJ(J,null):r4(Z)?YJ(J,null):t4(Z)?HJ(J,null):s4(Z)?VJ(J,null):t8(Z)?XJ(Z,J,null):e4(Z)?WJ(J,null):$9(Z)?p4({prompt:C2(J)||"提交计划"},null):r8(Z)?p4(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:V}},expanded:!0,elements:[{tag:"markdown",content:X},{tag:"column_set",columns:[l8("✅ 允许","primary",Q,"allow"),l8("♾️ 始终允许","default",Q,"allow_always"),l8("❌ 拒绝","danger",Q,"deny")]}]}}function l8($,Z,J,Q){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:Z,behaviors:[{type:"callback",value:{kind:"permission",request_id:J,decision:Q}}]}]}}var pz=300,iZ="server_tool:";var J7=E(()=>{x$();G4()});function Y9($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function zG($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function GG($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function Q9($){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 jJ($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function LJ($){let Z=$.filter((H)=>H.status==="completed").length,J=$.filter((H)=>H.status==="inProgress").length,Q=$.filter((H)=>H.status==="pending").length,Y=[`${$.length} 项`];if(J)Y.push(`${J} 进行中`);if(Z)Y.push(`${Z} 完成`);if(Q)Y.push(`${Q} 待办`);return Y.join(" · ")}function KG($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${LJ($)}`}function DJ($){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 Q=Math.floor(Z/60),Y=Z%60;return Y?`${Q}h ${Y}m`:`${Q}h`}function Q7($){return typeof $==="number"&&Number.isFinite($)?$:null}function _G($){let Z=Q7($.startedAtMs),J=Q7($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${DJ((J-Z)/1000)}`}function qG($){let Z=Q7($);return Z==null?null:Q9(Z)}function jG($,Z){if(!Z)return["压缩中..."];let J=[],Q=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Y=qG($.preTokens),H=typeof $.sourceType==="string"&&$.sourceType.trim()?$.sourceType.trim():"";if(Q)J.push(`**触发**: ${Q}`);if(Y)J.push(`**压缩前**: ${Y} tokens`);if(H)J.push(`**来源**: ${H}`);return J.length>0?J:["压缩完成,无摘要内容"]}function Y7($,Z,J){if($==null||!Number.isFinite($))return null;let Q=uZ($,Z,J);return Q?`${Q.used}% · ${u4($,Z)}`:"--"}function H7($){let Z=Q9($?.input_tokens??Number.NaN),J=Q9($?.cache_read_input_tokens??Number.NaN),Q=Q9($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Q}`}function b2($,Z,J){let Q=Z&&typeof Z==="object"?Z:{},Y=Q.phase==="end"||Q.phase==="event",H=Y?"✅":"⏳",V=Y?_G(Q):"",X=`${H} \uD83D\uDEA8 上下文压缩 #${$+1}${V}`,W=jG(Q,Y);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:W.join(`
92
- `)}]}}function PJ($,Z,J=""){let Q=["**\uD83D\uDCCB 当前计划**"],Y=Z?.trim();if(Y)Q.push(""),Q.push(Y);if($.length>0){Q.push("");for(let H of $)Q.push(`- ${zG(H.status)} ${H.step}`)}else{let H=J.trim();if(Q.push(""),H)Q.push("正在生成计划草稿..."),Q.push(""),Q.push(H);else Q.push("--")}return Q.join(`
93
- `)}function V7($,Z,J="",Q){return{tag:"collapsible_panel",element_id:Q,header:{title:{tag:"plain_text",content:KG($,J)}},expanded:!1,elements:[{tag:"markdown",content:PJ($,Z,J)}]}}function S2($,Z,J){let Q=$.length>0?`\uD83D\uDCCB 当前计划 · ${LJ($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Q}},expanded:!0,elements:[{tag:"markdown",content:PJ($,Z)}]}}function X7($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Q=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Y=[`**\uD83C\uDFAF 当前目标** · ${jJ($.status)}`,"",$.objective,"",`- 用量: ${J}${Q} tokens`,`- 用时: ${DJ($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${jJ($.status)}: ${GG($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Y.join(`
94
- `)}]}}function H9($){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}`}]:[],Q=$.userInputs??[],Y=`\uD83D\uDCE5 收到 (${Q.length}) ${$.directStart?"\uD83D\uDE80":`#${$.turn}`}`,H=Q.length>0?[{tag:"collapsible_panel",element_id:M.userInput,header:{title:{tag:"plain_text",content:Y}},expanded:!1,elements:Q.map((V)=>({tag:"markdown",content:a(V)}))}]:[];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,...H,{tag:"markdown",element_id:M.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function FJ($,Z,J){let Q=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Q}`}function BG($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function LG($,Z,J){let Q=[];for(let Y=0;Y<$.options.length;Y++){let H=$.options[Y],V=H.description?` · ${a(H.description)}`:"";Q.push({tag:"interactive_container",background_style:"default",has_border:!0,corner_radius:"6px",padding:"8px 12px",margin:"4px 0px 4px 0px",behaviors:[{type:"callback",value:{kind:"ask",tool_use_id:Z,question_idx:J,option_idx:Y}}],elements:[{tag:"markdown",content:`**${a(H.label)}**${V}`}]})}return Q}function BJ($,Z,J,Q){if($.length===0)return null;let Y=$.length,H=[];for(let V=0;V<$.length;V++){let X=$[V];if(!X)continue;let W=FJ(X,V,Y),z=Q.get(V);if(z){let K=BG(X,z),_=[`**✅ ${W}**`,`**回答**:${K}`];H.push({tag:"markdown",content:_.join(`
95
- `)});continue}if(V===J){if(H.push({tag:"markdown",content:`**\uD83E\uDD14 ${W}**`}),X.options.length>0)H.push(...LG(X,Z,V));H.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}H.push({tag:"markdown",content:`**⏳ ${W}**`})}return H}function w2($,Z,J,Q="\uD83E\uDD14",Y){let H=J.length,V=Y?.answered??new Map,X=Y?.currentIdx,W=X===void 0&&V.size>0,z=[],K;if(W){K=`${Q} 已回答 · ${H}/${H}`,z.push(...BJ(J,Z,X,V)??[]);let _=[...V.values()].reverse().find((j)=>j.user)?.user;if(_)z.push({tag:"markdown",content:`
96
- *— 由 ${_} 回答*`})}else if(X!==void 0&&J[X])K=`${Q} 等你确认 · ${X+1}/${H}`,z.push(...BJ(J,Z,X,V)??[]);else if(K=`${Q} 等你确认`,J[0])z.push({tag:"markdown",content:`**${FJ(J[0],0,H||1)}**`});return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:K}},expanded:!W,elements:z}}var AJ=E(()=>{x$();J7()});import{execFile as DG}from"node:child_process";import{readFileSync as W7,statfsSync as PG,statSync as UJ}from"node:fs";import{cpus as FG,homedir as AG}from"node:os";import{promisify as UG}from"node:util";function RG(){try{let $=W7("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:FG().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return G(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function OG(){try{let $=W7("/proc/meminfo","utf8"),Z=(H)=>{let V=$.match(new RegExp(`^${H}:\\s+(\\d+)\\s*kB`,"m"));return V?parseInt(V[1],10)*1024:0},J=Z("MemTotal"),Q=Z("MemAvailable");if(!J)return null;let Y=Math.max(0,J-Q);return{totalBytes:J,availBytes:Q,usedBytes:Y,percent:Math.round(Y/J*100)}}catch($){return G(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function MJ($,Z){try{let J=PG(Z,{bigint:!1}),Q=J.blocks*J.bsize,Y=J.bavail*J.bsize,H=Math.max(0,Q-Y);if(!Q)return null;return{label:$,path:Z,totalBytes:Q,availBytes:Y,usedBytes:H,percent:Math.round(H/Q*100)}}catch(J){return G(`sysinfo: statfs ${Z} failed: ${J}`),null}}function TG(){let $=[],Z=MJ("/","/");if(Z)$.push(Z);let J=AG();if(J&&J!=="/"){let Q=!1;try{let Y=UJ("/"),H=UJ(J);Q=Y.dev===H.dev}catch{}if(!Q){let Y=MJ("$HOME",J);if(Y)$.push(Y)}}return $}function kG(){try{let $=W7("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function RJ($,Z=2000){try{let{stdout:J}=await MG("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return G(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function OJ($){return TJ.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function yG(){let $=await RJ(["list-units","--type=service","--all","--no-legend","--plain",...TJ.map((W)=>`${W}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
97
- `).map((W)=>W.trim()).filter((W)=>W.length>0);if(Z.length===0)return{services:[],error:null};let J=[];for(let W of Z){let K=W.replace(/^●\s*/,"").split(/\s+/)[0];if(!K)continue;if(!OJ(K))continue;J.push(K)}if(J.length===0)return{services:[],error:null};let Q=await RJ(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Q===null)return{services:[],error:"systemctl show 失败"};let Y=kG(),H=Q.split(/\n\s*\n/),V=[],X=(W)=>{let z=parseInt(W??"0",10);if(z<=0||Y===null)return null;return Math.max(0,Y-z/1e6)};for(let W of H){let z={};for(let _ of W.split(`
98
- `)){let j=_.indexOf("=");if(j<=0)continue;z[_.slice(0,j)]=_.slice(j+1)}let K=z.Id??"";if(!OJ(K))continue;V.push({name:K.replace(/\.service$/,""),active:z.ActiveState??"unknown",sub:z.SubState??"",lastActiveAgoSec:X(z.ActiveEnterTimestampMonotonic),stateAgoSec:X(z.StateChangeTimestampMonotonic)})}return V.sort((W,z)=>W.name.localeCompare(z.name)),{services:V,error:null}}async function kJ(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=RG(),Z=OG(),J=TG(),{services:Q,error:Y}=await yG();return{cpu:$,mem:Z,disks:J,services:Q,servicesError:Y}}var MG,TJ,f2="cc-* / codex-*";var z7=E(()=>{w();MG=UG(DG),TJ=["cc-","codex-"]});function h2($,Z){return Z}function G7($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:M.footer,content:h2($.title,$.status)}]}}}function yJ($){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 v2($){if($<60000)return`${Math.round($/1000)}s`;let Z=Math.floor($/60000);if(Z<60)return`${Z}m`;let J=Math.floor(Z/60),Q=Z%60;if(J<24)return`${J}h ${Q}m`;return`${Math.floor(J/24)}d ${J%24}h`}function j0($){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 Q=[p1($.fiveHour.percent)];if($.fiveHour.resetsAt)Q.push(`重置 ${j0($.fiveHour.resetsAt)}`);J.push(` · ${EJ($.fiveHour.durationMins,"主窗口")} ${Q.join(" · ")}`)}if($.weekly){let Q=[p1($.weekly.percent)];if($.weekly.resetsAt)Q.push(`重置 ${j0($.weekly.resetsAt)}`);J.push(` · ${EJ($.weekly.durationMins,"次窗口")} ${Q.join(" · ")}`)}return J.length===1?"**\uD83D\uDCCA Codex 额度** _无数据_":J.join(`
99
- `)}function CG($){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):"",Q=[Z?`**\uD83D\uDCCA GLM 额度** · ${Z} 套餐`:"**\uD83D\uDCCA GLM 额度**"];if($.fiveHour){let Y=[p1($.fiveHour.percent)];if($.fiveHour.resetsAt)Y.push(`重置 ${j0($.fiveHour.resetsAt)}`);Q.push(` · 5h 窗口 ${Y.join(" · ")}`)}if($.weekly){let Y=[p1($.weekly.percent)];if($.weekly.resetsAt)Y.push(`重置 ${j0($.weekly.resetsAt)}`);Q.push(` · 周额度 ${Y.join(" · ")}`)}if($.monthly){let Y=[p1($.monthly.percent)];if(typeof $.monthly.used==="number"&&typeof $.monthly.total==="number")Y.push(`${$.monthly.used}/${$.monthly.total}`);if($.monthly.resetsAt)Y.push(`重置 ${j0($.monthly.resetsAt)}`);Q.push(` · 月度工具 ${Y.join(" · ")}`)}return Q.length===1?"**\uD83D\uDCCA GLM 额度** _无数据_":Q.join(`
100
- `)}function p1($){return typeof $==="number"&&Number.isFinite($)?`${Math.round($)}%`:"MISS"}function EJ($,Z){if(!$||$<=0)return Z;if($%1440===0)return`${$/1440}d`;if($%60===0)return`${$/60}h`;return`${$}m`}function SG($){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 wG($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${f2} _n/a_`].join(`
101
- `);let Z=[];if($.cpu){let{cores:J,load1:Q,load5:Y,load15:H}=$.cpu;Z.push(`**负载** ${Q.toFixed(2)} / ${Y.toFixed(2)} / ${H.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${yJ($.mem.usedBytes)}/${yJ($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${f2} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${f2} _无_`);else{Z.push(`**服务** ${f2} (${$.services.length})`);for(let J of $.services){let Q=bG[J.active]??"·",Y=J.lastActiveAgoSec,H=J.stateAgoSec,V=[J.active];if(J.active==="active"){if(H!=null)V.push(`已运行 ${v2(H*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Y!=null)V.push(`上次活跃 ${v2(Y*1000)}前`);else V.push("从未启动");if(H!=null){let X=J.active==="failed"?"已挂":"已停";V.push(`${X} ${v2(H*1000)}`)}}else if(H!=null)V.push(`已 ${v2(H*1000)}`);Z.push(` · ${Q} \`${J.name}\` · ${V.join(" · ")}`)}}return Z.join(`
102
- `)}function fG($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Q=xG[J.status]??"·",Y=NG[J.status]??J.status,H=J.uptimeMs!=null&&J.uptimeMs>0?` · ${v2(J.uptimeMs)}`:"",V=J.isCurrent?" · 当前":"";return` · ${Q} \`${J.name}\` · ${Y}${H}${V}`}).join(`
103
- `)}function V9($,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:fG($)}]}}function vG($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${L7($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
104
- `)}function X9($,Z=M.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:vG($)}}function W9($,Z=M.consoleHost){let J=SG($);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:wG($)}]}}function hG($){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 Q of $.windows){let Y=[p1(Q.percent)];if(typeof Q.used==="number"&&typeof Q.total==="number")Y.push(`${Q.used}/${Q.total}`);if(Q.resetsAt)Y.push(`重置 ${j0(Q.resetsAt)}`);J.push(` · ${Q.label} ${Y.join(" · ")}`)}return J.length===1&&!$.planLabel?"**\uD83D\uDCCA 额度** _无数据_":J.join(`
105
- `)}function g2($){let Z=$.unifiedUsage!==void 0?hG($.unifiedUsage):$.provider==="claude"?CG($.glmUsage):xJ($.usage);return{tag:"markdown",element_id:M.consoleUsage,content:Z}}function NJ($,Z){return[X9($,Z),V9($),W9($.sysinfo),g2($)]}function K7($){let{sessionName:Z,status:J}=$,Q=J==="working"?"blue":J==="awaiting_permission"?"orange":J==="stopped"?"grey":"green";return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83C\uDF1F Lodestar · ${Z}`},template:Q},body:{elements:NJ($)}}}function _7($){return l1($.sessionName,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${e0($.currentDisplay??"未选择")}
106
- 选账号进入模型选择。`},...$.providers.map((Z)=>gG(Z,$.panelId))]})}function gG($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${t$($.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:`**${t$($.display)}**
107
- ${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 q7($){return l1($.sessionName,CJ($))}function j7($){return l1($.sessionName,_9($))}function z9($){return l1($.sessionName,bJ($),"green")}function l1($,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 CJ($){let Z=cG($.models,$.panelId);return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${SJ($.currentModel,$.currentEffort)}`,"选模型进入 effort 选择。"].join(`
108
- `)},...$.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 G9($,Z="cancelled"){return l1($,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function B7($,Z,J){return l1($,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**(列表外的模型,端点会先校验真伪)`,"_裸词命令(hi/stop/model 等)不受影响_"].join(`
109
- `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function K9($,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 _9($){return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${pG($.model)}`,`当前: ${SJ($.currentModel,$.currentEffort)}`].join(`
110
- `)},...$.model.efforts.length?$.model.efforts.map((Z)=>mG($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function bJ($){return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",e0(wJ($.model,$.effort,$.provider)),t$($.scope)].join(`
111
- `)}]}}function IG($,Z){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${t$($.displayName)}** · 未配置
112
- ${t$($.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?`**${t$($.displayName)}**`:`**${e0($.model)}**`,Q=[$.isDefault?`${L7($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),Y=$.description?`
113
- `+t$(lG($.description,110)):"";return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[J,e0($.model),Q.length?Q.join(" · "):""].filter(Boolean).join(`
114
- `)+Y}]},{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 cG($,Z){let J=[{title:"Codex",models:$.filter((H)=>(H.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((H)=>H.provider==="claude")}].filter((H)=>H.models.length>0),Q=(H)=>H.flatMap((V)=>IG(V,Z));if(J.length<=1)return Q($);let Y=[];for(let H of J)Y.push({tag:"markdown",content:`**${H.title}**`}),Y.push(...Q(H.models));return Y}function mG($,Z,J,Q,Y){let H=Q===$.model&&Y===Z.effort,V=[Z.isDefault?"默认":"",H?"当前":""].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[`**${t$(Z.effort)}**`,V,Z.description?t$(Z.description):""].filter(Boolean).join(`
115
- `)}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:H?"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 pG($){return $.displayName&&$.displayName!==$.model?`${t$($.displayName)} (${e0($.model)})`:e0($.model)}function SJ($,Z){return e0(wJ($,Z))}function wJ($,Z,J){let Q=J&&J!=="codex"?`${L7(J)} · `:"";if($&&Z)return`${Q}${$}/${Z}`;if($)return`${Q}${$}`;if(Z)return`${Q}${Z}`;return"未选择"}function L7($){return $==="claude"?"Claude":"Codex"}function lG($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function t$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function e0($){return"`"+$.replace(/`/g,"\\`")+"`"}function p$($){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 xG,NG,bG;var fJ=E(()=>{z7();x$();xG={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},NG={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"};bG={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function D7($){let Z=nG($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:iG($.notice)},body:{elements:[...$.notice?[dG($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(oG)]}}}function iG($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function dG($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
89
+ `+Q.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!1,elements:[{tag:"markdown",content:s(_)}]}}function m1($,Z){let J=Z.length,Q=Z.some((W)=>W.isError),Y=Z.every((W)=>W.output!==null),H=Q?"❌":Y?"✅":"⏳",X=J===1?(()=>{let W=dZ(Z[0]);return W?`${H} \uD83D\uDD27 编辑文件: ${W}`:`${H} \uD83D\uDD27 编辑文件`})():`${H} \uD83D\uDD27 编辑文件 · ${J} 次`,V=Z.map((W)=>{let G=dZ(W);return G?`\`${G}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:s(V.join(`
90
+ `))}]}}function dZ($){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 u1($,Z){let J=Z.length,Q=Z.some((W)=>W.isError),Y=Z.every((W)=>W.output!==null),H=Q?"❌":Y?"✅":"⏳",X=J===1?(()=>{let W=_0("Read",Z[0]?.input);return W?`${H} \uD83D\uDD27 Read: ${W}`:`${H} \uD83D\uDD27 Read`})():`${H} \uD83D\uDD27 Read · ${J} 次`,V=Z.map((W)=>`\`${String(W.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:s(V.join(`
91
+ `))}]}}function J9($,Z,J,Q){let Y=_0(Z,J),H=s0(Z),X=Y?`\uD83D\uDD10 等审批 · ${H}: ${Y}`:`\uD83D\uDD10 等审批 · ${H}`,V=l4(Z)?rZ(J,null):d4(Z)?tZ(J,null):i4(Z)?JJ(J,null):y2(Z)?KJ(J,null):n4(Z)?_J(J,null):r6(Z)?qJ(J,null):o4(Z)?BJ(J,null):a4(Z)?YJ(J,null):r4(Z)?HJ(J,null):t4(Z)?XJ(J,null):s4(Z)?VJ(J,null):s6(Z)?WJ(Z,J,null):e4(Z)?GJ(J,null):$9(Z)?p4({prompt:C2(J)||"提交计划"},null):t6(Z)?p4(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:X}},expanded:!0,elements:[{tag:"markdown",content:V},{tag:"column_set",columns:[d6("✅ 允许","primary",Q,"allow"),d6("♾️ 始终允许","default",Q,"allow_always"),d6("❌ 拒绝","danger",Q,"deny")]}]}}function d6($,Z,J,Q){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:Z,behaviors:[{type:"callback",value:{kind:"permission",request_id:J,decision:Q}}]}]}}var iG=300,iZ="server_tool:";var Q7=k(()=>{x$();z4()});function Y9($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function _z($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function qz($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function Q9($){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 jJ($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function DJ($){let Z=$.filter((H)=>H.status==="completed").length,J=$.filter((H)=>H.status==="inProgress").length,Q=$.filter((H)=>H.status==="pending").length,Y=[`${$.length} 项`];if(J)Y.push(`${J} 进行中`);if(Z)Y.push(`${Z} 完成`);if(Q)Y.push(`${Q} 待办`);return Y.join(" · ")}function Bz($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${DJ($)}`}function AJ($){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 Q=Math.floor(Z/60),Y=Z%60;return Y?`${Q}h ${Y}m`:`${Q}h`}function Y7($){return typeof $==="number"&&Number.isFinite($)?$:null}function jz($){let Z=Y7($.startedAtMs),J=Y7($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${AJ((J-Z)/1000)}`}function Lz($){let Z=Y7($);return Z==null?null:Q9(Z)}function Dz($,Z){if(!Z)return["压缩中..."];let J=[],Q=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Y=Lz($.preTokens),H=typeof $.sourceType==="string"&&$.sourceType.trim()?$.sourceType.trim():"";if(Q)J.push(`**触发**: ${Q}`);if(Y)J.push(`**压缩前**: ${Y} tokens`);if(H)J.push(`**来源**: ${H}`);return J.length>0?J:["压缩完成,无摘要内容"]}function H7($,Z,J){if($==null||!Number.isFinite($))return null;let Q=pZ($,Z,J);return Q?`${Q.used}% · ${u4($,Z)}`:"--"}function X7($){let Z=Q9($?.input_tokens??Number.NaN),J=Q9($?.cache_read_input_tokens??Number.NaN),Q=Q9($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Q}`}function S2($,Z,J){let Q=Z&&typeof Z==="object"?Z:{},Y=Q.phase==="end"||Q.phase==="event",H=Y?"✅":"⏳",X=Y?jz(Q):"",V=`${H} \uD83D\uDEA8 上下文压缩 #${$+1}${X}`,W=Dz(Q,Y);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:V}},expanded:!1,elements:[{tag:"markdown",content:W.join(`
92
+ `)}]}}function FJ($,Z,J=""){let Q=["**\uD83D\uDCCB 当前计划**"],Y=Z?.trim();if(Y)Q.push(""),Q.push(Y);if($.length>0){Q.push("");for(let H of $)Q.push(`- ${_z(H.status)} ${H.step}`)}else{let H=J.trim();if(Q.push(""),H)Q.push("正在生成计划草稿..."),Q.push(""),Q.push(H);else Q.push("--")}return Q.join(`
93
+ `)}function V7($,Z,J="",Q){return{tag:"collapsible_panel",element_id:Q,header:{title:{tag:"plain_text",content:Bz($,J)}},expanded:!1,elements:[{tag:"markdown",content:FJ($,Z,J)}]}}function b2($,Z,J){let Q=$.length>0?`\uD83D\uDCCB 当前计划 · ${DJ($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Q}},expanded:!0,elements:[{tag:"markdown",content:FJ($,Z)}]}}function W7($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Q=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Y=[`**\uD83C\uDFAF 当前目标** · ${jJ($.status)}`,"",$.objective,"",`- 用量: ${J}${Q} tokens`,`- 用时: ${AJ($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${jJ($.status)}: ${qz($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Y.join(`
94
+ `)}]}}function H9($){let Z=$.provider==="claude"?"Claude":"Codex",J=$.kind==="card_full"?[{tag:"markdown",content:`\uD83D\uDCE8 接续上一张(同一轮 ${Z},前卡写满或写入受限)`}]:$.kind==="bg_task_resume"?[{tag:"markdown",content:`\uD83D\uDD01 后台任务完成,${Z} 继续处理结果 #${$.turn}`}]:$.kind==="scheduled_wakeup"?[{tag:"markdown",content:`⏰ 定时任务触发,${Z} 正在执行巡检 #${$.turn}`}]:[],Q=$.userInputs??[],Y=`\uD83D\uDCE5 收到 (${Q.length}) ${$.directStart?"\uD83D\uDE80":`#${$.turn}`}`,H=Q.length>0?[{tag:"collapsible_panel",element_id:M.userInput,header:{title:{tag:"plain_text",content:Y}},expanded:!1,elements:Q.map((X)=>({tag:"markdown",content:s(X)}))}]:[];return{schema:"2.0",config:{streaming_mode:!0,summary:{content:"[Lodestar 正在生成…]"},streaming_config:{print_frequency_ms:{default:60,android:60,ios:60,pc:30},print_step:{default:2,android:2,ios:2,pc:4},print_strategy:"fast"}},body:{elements:[...J,...H,{tag:"markdown",element_id:M.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function PJ($,Z,J){let Q=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Q}`}function Az($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function Fz($,Z,J){let Q=[];for(let Y=0;Y<$.options.length;Y++){let H=$.options[Y],X=H.description?` · ${s(H.description)}`:"";Q.push({tag:"interactive_container",background_style:"default",has_border:!0,corner_radius:"6px",padding:"8px 12px",margin:"4px 0px 4px 0px",behaviors:[{type:"callback",value:{kind:"ask",tool_use_id:Z,question_idx:J,option_idx:Y}}],elements:[{tag:"markdown",content:`**${s(H.label)}**${X}`}]})}return Q}function LJ($,Z,J,Q){if($.length===0)return null;let Y=$.length,H=[];for(let X=0;X<$.length;X++){let V=$[X];if(!V)continue;let W=PJ(V,X,Y),G=Q.get(X);if(G){let K=Az(V,G),_=[`**✅ ${W}**`,`**回答**:${K}`];H.push({tag:"markdown",content:_.join(`
95
+ `)});continue}if(X===J){if(H.push({tag:"markdown",content:`**\uD83E\uDD14 ${W}**`}),V.options.length>0)H.push(...Fz(V,Z,X));H.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}H.push({tag:"markdown",content:`**⏳ ${W}**`})}return H}function w2($,Z,J,Q="\uD83E\uDD14",Y){let H=J.length,X=Y?.answered??new Map,V=Y?.currentIdx,W=V===void 0&&X.size>0,G=[],K;if(W){K=`${Q} 已回答 · ${H}/${H}`,G.push(...LJ(J,Z,V,X)??[]);let _=[...X.values()].reverse().find((B)=>B.user)?.user;if(_)G.push({tag:"markdown",content:`
96
+ *— 由 ${_} 回答*`})}else if(V!==void 0&&J[V])K=`${Q} 等你确认 · ${V+1}/${H}`,G.push(...LJ(J,Z,V,X)??[]);else if(K=`${Q} 等你确认`,J[0])G.push({tag:"markdown",content:`**${PJ(J[0],0,H||1)}**`});return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:K}},expanded:!W,elements:G}}var UJ=k(()=>{x$();Q7()});import{execFile as Pz}from"node:child_process";import{readFileSync as G7,statfsSync as Uz,statSync as MJ}from"node:fs";import{cpus as Mz,homedir as Rz}from"node:os";import{promisify as Oz}from"node:util";function Ez(){try{let $=G7("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:Mz().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return z(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function Nz(){try{let $=G7("/proc/meminfo","utf8"),Z=(H)=>{let X=$.match(new RegExp(`^${H}:\\s+(\\d+)\\s*kB`,"m"));return X?parseInt(X[1],10)*1024:0},J=Z("MemTotal"),Q=Z("MemAvailable");if(!J)return null;let Y=Math.max(0,J-Q);return{totalBytes:J,availBytes:Q,usedBytes:Y,percent:Math.round(Y/J*100)}}catch($){return z(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function RJ($,Z){try{let J=Uz(Z,{bigint:!1}),Q=J.blocks*J.bsize,Y=J.bavail*J.bsize,H=Math.max(0,Q-Y);if(!Q)return null;return{label:$,path:Z,totalBytes:Q,availBytes:Y,usedBytes:H,percent:Math.round(H/Q*100)}}catch(J){return z(`sysinfo: statfs ${Z} failed: ${J}`),null}}function kz(){let $=[],Z=RJ("/","/");if(Z)$.push(Z);let J=Rz();if(J&&J!=="/"){let Q=!1;try{let Y=MJ("/"),H=MJ(J);Q=Y.dev===H.dev}catch{}if(!Q){let Y=RJ("$HOME",J);if(Y)$.push(Y)}}return $}function xz(){try{let $=G7("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function OJ($,Z=2000){try{let{stdout:J}=await Tz("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return z(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function TJ($){return EJ.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function yz(){let $=await OJ(["list-units","--type=service","--all","--no-legend","--plain",...EJ.map((W)=>`${W}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
97
+ `).map((W)=>W.trim()).filter((W)=>W.length>0);if(Z.length===0)return{services:[],error:null};let J=[];for(let W of Z){let K=W.replace(/^●\s*/,"").split(/\s+/)[0];if(!K)continue;if(!TJ(K))continue;J.push(K)}if(J.length===0)return{services:[],error:null};let Q=await OJ(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Q===null)return{services:[],error:"systemctl show 失败"};let Y=xz(),H=Q.split(/\n\s*\n/),X=[],V=(W)=>{let G=parseInt(W??"0",10);if(G<=0||Y===null)return null;return Math.max(0,Y-G/1e6)};for(let W of H){let G={};for(let _ of W.split(`
98
+ `)){let B=_.indexOf("=");if(B<=0)continue;G[_.slice(0,B)]=_.slice(B+1)}let K=G.Id??"";if(!TJ(K))continue;X.push({name:K.replace(/\.service$/,""),active:G.ActiveState??"unknown",sub:G.SubState??"",lastActiveAgoSec:V(G.ActiveEnterTimestampMonotonic),stateAgoSec:V(G.StateChangeTimestampMonotonic)})}return X.sort((W,G)=>W.name.localeCompare(G.name)),{services:X,error:null}}async function NJ(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=Ez(),Z=Nz(),J=kz(),{services:Q,error:Y}=await yz();return{cpu:$,mem:Z,disks:J,services:Q,servicesError:Y}}var Tz,EJ,f2="cc-* / codex-*";var z7=k(()=>{w();Tz=Oz(Pz),EJ=["cc-","codex-"]});function h2($,Z){return Z}function K7($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:M.footer,content:h2($.title,$.status)}]}}}function kJ($){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 Cz($){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 v2($){if($<60000)return`${Math.round($/1000)}s`;let Z=Math.floor($/60000);if(Z<60)return`${Z}m`;let J=Math.floor(Z/60),Q=Z%60;if(J<24)return`${J}h ${Q}m`;return`${Math.floor(J/24)}d ${J%24}h`}function B0($){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 yJ($){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 Q=[p1($.fiveHour.percent)];if($.fiveHour.resetsAt)Q.push(`重置 ${B0($.fiveHour.resetsAt)}`);J.push(` · ${xJ($.fiveHour.durationMins,"主窗口")} ${Q.join(" · ")}`)}if($.weekly){let Q=[p1($.weekly.percent)];if($.weekly.resetsAt)Q.push(`重置 ${B0($.weekly.resetsAt)}`);J.push(` · ${xJ($.weekly.durationMins,"次窗口")} ${Q.join(" · ")}`)}return J.length===1?"**\uD83D\uDCCA Codex 额度** _无数据_":J.join(`
99
+ `)}function wz($){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):"",Q=[Z?`**\uD83D\uDCCA GLM 额度** · ${Z} 套餐`:"**\uD83D\uDCCA GLM 额度**"];if($.fiveHour){let Y=[p1($.fiveHour.percent)];if($.fiveHour.resetsAt)Y.push(`重置 ${B0($.fiveHour.resetsAt)}`);Q.push(` · 5h 窗口 ${Y.join(" · ")}`)}if($.weekly){let Y=[p1($.weekly.percent)];if($.weekly.resetsAt)Y.push(`重置 ${B0($.weekly.resetsAt)}`);Q.push(` · 周额度 ${Y.join(" · ")}`)}if($.monthly){let Y=[p1($.monthly.percent)];if(typeof $.monthly.used==="number"&&typeof $.monthly.total==="number")Y.push(`${$.monthly.used}/${$.monthly.total}`);if($.monthly.resetsAt)Y.push(`重置 ${B0($.monthly.resetsAt)}`);Q.push(` · 月度工具 ${Y.join(" · ")}`)}return Q.length===1?"**\uD83D\uDCCA GLM 额度** _无数据_":Q.join(`
100
+ `)}function p1($){return typeof $==="number"&&Number.isFinite($)?`${Math.round($)}%`:"MISS"}function xJ($,Z){if(!$||$<=0)return Z;if($%1440===0)return`${$/1440}d`;if($%60===0)return`${$/60}h`;return`${$}m`}function vz($){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 hz($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${f2} _n/a_`].join(`
101
+ `);let Z=[];if($.cpu){let{cores:J,load1:Q,load5:Y,load15:H}=$.cpu;Z.push(`**负载** ${Q.toFixed(2)} / ${Y.toFixed(2)} / ${H.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${kJ($.mem.usedBytes)}/${kJ($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${f2} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${f2} _无_`);else{Z.push(`**服务** ${f2} (${$.services.length})`);for(let J of $.services){let Q=fz[J.active]??"·",Y=J.lastActiveAgoSec,H=J.stateAgoSec,X=[J.active];if(J.active==="active"){if(H!=null)X.push(`已运行 ${v2(H*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Y!=null)X.push(`上次活跃 ${v2(Y*1000)}前`);else X.push("从未启动");if(H!=null){let V=J.active==="failed"?"已挂":"已停";X.push(`${V} ${v2(H*1000)}`)}}else if(H!=null)X.push(`已 ${v2(H*1000)}`);Z.push(` · ${Q} \`${J.name}\` · ${X.join(" · ")}`)}}return Z.join(`
102
+ `)}function Iz($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Q=Sz[J.status]??"·",Y=bz[J.status]??J.status,H=J.uptimeMs!=null&&J.uptimeMs>0?` · ${v2(J.uptimeMs)}`:"",X=J.isCurrent?" · 当前":"";return` · ${Q} \`${J.name}\` · ${Y}${H}${X}`}).join(`
103
+ `)}function X9($,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:Iz($)}]}}function gz($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${D7($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
104
+ `)}function V9($,Z=M.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:gz($)}}function W9($,Z=M.consoleHost){let J=vz($);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:hz($)}]}}function cz($){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 Q of $.windows){let Y=[p1(Q.percent)];if(typeof Q.used==="number"&&typeof Q.total==="number")Y.push(`${Q.used}/${Q.total}`);if(Q.resetsAt)Y.push(`重置 ${B0(Q.resetsAt)}`);J.push(` · ${Q.label} ${Y.join(" · ")}`)}return J.length===1&&!$.planLabel?"**\uD83D\uDCCA 额度** _无数据_":J.join(`
105
+ `)}function I2($){let Z=$.unifiedUsage!==void 0?cz($.unifiedUsage):$.provider==="claude"?wz($.glmUsage):yJ($.usage);return{tag:"markdown",element_id:M.consoleUsage,content:Z}}function CJ($,Z){return[V9($,Z),X9($),W9($.sysinfo),I2($)]}function _7($){let{sessionName:Z,status:J}=$,Q=J==="working"?"blue":J==="awaiting_permission"?"orange":J==="stopped"?"grey":"green";return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83C\uDF1F Lodestar · ${Z}`},template:Q},body:{elements:CJ($)}}}function q7($){return l1($.sessionName,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${e0($.currentDisplay??"未选择")}
106
+ 选账号进入模型选择。`},...$.providers.map((Z)=>mz(Z,$.panelId))]})}function mz($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${t$($.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:`**${t$($.display)}**
107
+ ${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 B7($){return l1($.sessionName,SJ($))}function j7($){return l1($.sessionName,_9($))}function G9($){return l1($.sessionName,bJ($),"green")}function l1($,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 SJ($){let Z=pz($.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(`
108
+ `)},...$.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 z9($,Z="cancelled"){return l1($,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function L7($,Z,J){return l1($,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**(列表外的模型,端点会先校验真伪)`,"_裸词命令(hi/stop/model 等)不受影响_"].join(`
109
+ `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function K9($,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 _9($){return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${iz($.model)}`,`当前: ${wJ($.currentModel,$.currentEffort)}`].join(`
110
+ `)},...$.model.efforts.length?$.model.efforts.map((Z)=>lz($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function bJ($){return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",e0(fJ($.model,$.effort,$.provider)),t$($.scope)].join(`
111
+ `)}]}}function uz($,Z){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${t$($.displayName)}** · 未配置
112
+ ${t$($.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?`**${t$($.displayName)}**`:`**${e0($.model)}**`,Q=[$.isDefault?`${D7($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),Y=$.description?`
113
+ `+t$(nz($.description,110)):"";return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[J,e0($.model),Q.length?Q.join(" · "):""].filter(Boolean).join(`
114
+ `)+Y}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:dz($,Z)}]}]}]}]}function pz($,Z){let J=[{title:"Codex",models:$.filter((H)=>(H.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((H)=>H.provider==="claude")}].filter((H)=>H.models.length>0),Q=(H)=>H.flatMap((X)=>uz(X,Z));if(J.length<=1)return Q($);let Y=[];for(let H of J)Y.push({tag:"markdown",content:`**${H.title}**`}),Y.push(...Q(H.models));return Y}function lz($,Z,J,Q,Y){let H=Q===$.model&&Y===Z.effort,X=[Z.isDefault?"默认":"",H?"当前":""].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[`**${t$(Z.effort)}**`,X,Z.description?t$(Z.description):""].filter(Boolean).join(`
115
+ `)}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:H?"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 dz($,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 iz($){return $.displayName&&$.displayName!==$.model?`${t$($.displayName)} (${e0($.model)})`:e0($.model)}function wJ($,Z){return e0(fJ($,Z))}function fJ($,Z,J){let Q=J&&J!=="codex"?`${D7(J)} · `:"";if($&&Z)return`${Q}${$}/${Z}`;if($)return`${Q}${$}`;if(Z)return`${Q}${Z}`;return"未选择"}function D7($){return $==="claude"?"Claude":"Codex"}function nz($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function t$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function e0($){return"`"+$.replace(/`/g,"\\`")+"`"}function p$($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec)Z.push(`⏱ ${$.durationSec}s`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${Cz($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var Sz,bz,fz;var vJ=k(()=>{z7();x$();Sz={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},bz={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"};fz={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function A7($){let Z=rz($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:oz($.notice)},body:{elements:[...$.notice?[az($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(tz)]}}}function oz($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function az($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
116
116
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
117
- `)}}function nG($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${q9("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function oG($){let Z=$.error?"出错":$.mounted&&$.dirtyCount&&$.dirtyCount>0?`有未提交改动 ${$.dirtyCount}`:$.state==="merged"?"已合并":$.state==="stale"?"两边都有新改动":$.mounted?"进行中":"未挂载",J=$.duplicateChatCount>1?`群重复 ${$.duplicateChatCount} 个`:$.chatId?"群正常":"无群",Q=[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${q9($.slug)}**
117
+ `)}}function rz($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${q9("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function tz($){let Z=$.error?"出错":$.mounted&&$.dirtyCount&&$.dirtyCount>0?`有未提交改动 ${$.dirtyCount}`:$.state==="merged"?"已合并":$.state==="stale"?"两边都有新改动":$.mounted?"进行中":"未挂载",J=$.duplicateChatCount>1?`群重复 ${$.duplicateChatCount} 个`:$.chatId?"群正常":"无群",Q=[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${q9($.slug)}**
118
118
  ${Z} · ${J}
119
- ${q9($.branch)}`}]}];if($.mounted||$.chatId)Q.push({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"删"},type:"danger",behaviors:[{type:"callback",value:{kind:"worktree_disband",slug:$.slug}}]}]});return[{tag:"column_set",columns:Q}]}function I2($){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,q9($.branch),...$.body?[$.body]:[]].join(`
120
- `)}]}}}function q9($){return"`"+$.replace(/`/g,"\\`")+"`"}function F7($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Q=Z?"temp_fork_select":"temp_back_select",Y=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
119
+ ${q9($.branch)}`}]}];if($.mounted||$.chatId)Q.push({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"删"},type:"danger",behaviors:[{type:"callback",value:{kind:"worktree_disband",slug:$.slug}}]}]});return[{tag:"column_set",columns:Q}]}function g2($){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,q9($.branch),...$.body?[$.body]:[]].join(`
120
+ `)}]}}}function q9($){return"`"+$.replace(/`/g,"\\`")+"`"}function P7($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Q=Z?"temp_fork_select":"temp_back_select",Y=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
121
121
  分支与本群共享 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件,原会话不动。`:`⚠️ 选择一条「用户输入」,将停止本群当前 turn 和后台任务,并从它**之前**创建后续对话分支;选中的输入本身不包含。
122
- 只回退对话历史,不会回滚 cwd 中的文件。`,H=[];if($.notice)H.push({tag:"markdown",content:aG($.notice)});if(!$.entries.length)H.push({tag:"markdown",content:"_当前会话还没有已完成的 turn,无法分叉/回退。_"});else{H.push({tag:"markdown",content:Y});for(let V of $.entries)H.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${R7(V.ts)}**
123
- ${x0(V.preview.slice(0,60)||"(空)")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:J},type:Z?"primary":"danger",behaviors:[{type:"callback",value:{kind:Q,panel_id:$.panelId,choice_id:V.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:H}}}function A7($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
124
- 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${R7(J.ts)}**
125
- ${x0(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 U7($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Q=J.body.length>800?J.body.slice(0,800)+`
122
+ 只回退对话历史,不会回滚 cwd 中的文件。`,H=[];if($.notice)H.push({tag:"markdown",content:sz($.notice)});if(!$.entries.length)H.push({tag:"markdown",content:"_当前会话还没有已完成的 turn,无法分叉/回退。_"});else{H.push({tag:"markdown",content:Y});for(let X of $.entries)H.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${O7(X.ts)}**
123
+ ${k0(X.preview.slice(0,60)||"(空)")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:J},type:Z?"primary":"danger",behaviors:[{type:"callback",value:{kind:Q,panel_id:$.panelId,choice_id:X.choiceId}}]}]}]})}return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`${Z?"\uD83D\uDD31 fk 分叉":"⏪ bk 回退"} · ${$.projectName}`},template:Z?"turquoise":"orange"},body:{elements:H}}}function U7($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
124
+ 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${O7(J.ts)}**
125
+ ${k0(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 M7($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Q=J.body.length>800?J.body.slice(0,800)+`
126
126
  …(截断)`:J.body;return`${J.path} (${J.tool})
127
127
  ${Q}`}).join(`
128
128
 
129
- `);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 N0($){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?"✅":"❌"} ${P7($.message)}`}]}}}function M7($){let Z=$.provider==="codex"?"Codex":"Claude",J=$.bindingState==="changed"?"已接入":$.bindingState==="prepared"?"已准备":$.bindingState==="unchanged"?"未切换":"状态待确认",Q=$.bindingState==="changed"?"✅":$.bindingState==="prepared"?"⏳":$.bindingState==="unchanged"?"❌":"⚠️",Y=$.selectedPreview.slice(0,80)||"(无摘要)",H=$.sourceStatus?` · 状态 ${x0($.sourceStatus)}`:"",V=$.bindingState==="changed"?["**当前群**",`新会话 ${x0(j9($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
129
+ `);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 x0($){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?"✅":"❌"} ${F7($.message)}`}]}}}function R7($){let Z=$.provider==="codex"?"Codex":"Claude",J=$.bindingState==="changed"?"已接入":$.bindingState==="prepared"?"已准备":$.bindingState==="unchanged"?"未切换":"状态待确认",Q=$.bindingState==="changed"?"✅":$.bindingState==="prepared"?"⏳":$.bindingState==="unchanged"?"❌":"⚠️",Y=$.selectedPreview.slice(0,80)||"(无摘要)",H=$.sourceStatus?` · 状态 ${k0($.sourceStatus)}`:"",X=$.bindingState==="changed"?["**当前群**",`新会话 ${k0(B9($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
130
130
  `):$.bindingState==="prepared"?["**当前群**","Claude 独立分支已准备;发送下一条消息时生成并接入新会话。","","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
131
- `):$.bindingState==="unchanged"?[`${P7($.message)}`,"",`本群原绑定 ${x0(j9($.previousSessionId))};源会话未修改。`].join(`
132
- `):[`${P7($.message)}`,"",`后端返回会话 ${x0(j9($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
133
- `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDD01 rs ${J} · ${$.projectName}`},template:$.bindingState==="changed"?"green":$.bindingState==="prepared"?"purple":$.bindingState==="unchanged"?"red":"orange"},body:{elements:[{tag:"markdown",content:`${Q} ${$.bindingState==="changed"?"已从所选历史创建独立分支":$.bindingState==="prepared"?"已准备从所选历史创建独立分支":$.bindingState==="unchanged"?"历史分支创建失败":"分支结果需要确认"}`},{tag:"markdown",content:[`**所选历史 · ${Z}**`,`**${R7($.selectedTs)}**${H}`,x0(Y),`源会话 ${x0(j9($.sourceSessionId))}`].join(`
134
- `)},{tag:"markdown",content:V}]}}}function R7($){let Z=new Date($),J=(Q)=>String(Q).padStart(2,"0");return`${J(Z.getMonth()+1)}-${J(Z.getDate())} ${J(Z.getHours())}:${J(Z.getMinutes())}`}function x0($){return"`"+vJ($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function j9($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function P7($){return vJ($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function vJ($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function aG($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
131
+ `):$.bindingState==="unchanged"?[`${F7($.message)}`,"",`本群原绑定 ${k0(B9($.previousSessionId))};源会话未修改。`].join(`
132
+ `):[`${F7($.message)}`,"",`后端返回会话 ${k0(B9($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
133
+ `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDD01 rs ${J} · ${$.projectName}`},template:$.bindingState==="changed"?"green":$.bindingState==="prepared"?"purple":$.bindingState==="unchanged"?"red":"orange"},body:{elements:[{tag:"markdown",content:`${Q} ${$.bindingState==="changed"?"已从所选历史创建独立分支":$.bindingState==="prepared"?"已准备从所选历史创建独立分支":$.bindingState==="unchanged"?"历史分支创建失败":"分支结果需要确认"}`},{tag:"markdown",content:[`**所选历史 · ${Z}**`,`**${O7($.selectedTs)}**${H}`,k0(Y),`源会话 ${k0(B9($.sourceSessionId))}`].join(`
134
+ `)},{tag:"markdown",content:X}]}}}function O7($){let Z=new Date($),J=(Q)=>String(Q).padStart(2,"0");return`${J(Z.getMonth()+1)}-${J(Z.getDate())} ${J(Z.getHours())}:${J(Z.getMinutes())}`}function k0($){return"`"+hJ($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function B9($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function F7($){return hJ($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function hJ($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function sz($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
135
135
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
136
- `)}function hJ($,Z){if(!Z||typeof Z!=="object")return"";if(typeof Z.content==="string")return Z.content;if(typeof Z.new_string==="string")return Z.new_string;if(typeof Z.new_source==="string")return Z.new_source;if(Array.isArray(Z.edits))return Z.edits.map((J)=>typeof J?.new_string==="string"?J.new_string:"").filter(Boolean).join(`
136
+ `)}function IJ($,Z){if(!Z||typeof Z!=="object")return"";if(typeof Z.content==="string")return Z.content;if(typeof Z.new_string==="string")return Z.new_string;if(typeof Z.new_source==="string")return Z.new_source;if(Array.isArray(Z.edits))return Z.edits.map((J)=>typeof J?.new_string==="string"?J.new_string:"").filter(Boolean).join(`
137
137
  ---
138
- `);return""}function O7($,Z){if(!Z||typeof Z!=="object")return[];if($==="FileChange"||$==="fileChange"){if(!Array.isArray(Z.changes))return[];return Z.changes.filter((Q)=>Q&&typeof Q==="object").map((Q)=>({tool:$,path:typeof Q.path==="string"&&Q.path?Q.path:"?",body:typeof Q.diff==="string"?Q.diff:typeof Q.unified_diff==="string"?Q.unified_diff:""}))}if(!["Write","Edit","NotebookEdit","MultiEdit"].includes($))return[];let J=Z.file_path??Z.path??Z.notebook_path;return[{tool:$,path:typeof J==="string"&&J?J:"?",body:hJ($,Z)}]}function k7($){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?[sG($.notice)]:[],{tag:"markdown",element_id:M.tasklistPanel,content:rG($)},tG($)]}}}function rG($){let Z=[`项目:${T7($.projectName)}`,`清单:${T7($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
139
- `);if(Z.push("","已启用"),Z.push(`GUID:${T7($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
140
- `)}function tG($){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 sG($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
141
- `).map((J)=>`<font color='${Z}'>${eG(J)||" "}</font>`).join(`
142
- `)}}function T7($){return"`"+$.replace(/`/g,"\\`")+"`"}function eG($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var gJ=E(()=>{x$()});function $1($){switch($){case"correctness":return"正确性审查";case"architecture":return"架构审查";case"security":return"安全审查";case"testing":return"测试与回归";case"maintainability":return"简化与可维护性";default:return"通用顾问"}}function c2($){switch($){case"correctness":return"优先检查逻辑错误、边界条件、竞态和错误处理,每个结论给出可验证证据。";case"architecture":return"优先检查模块边界、状态所有权、协议契约和长期演进风险。";case"security":return"优先检查权限、凭据泄露、命令注入、路径越界、不可逆副作用和供应链风险。";case"testing":return"优先检查验收标准、回归面、失败路径、并发时序和测试可观测性。";case"maintainability":return"优先检查不必要的抽象、重复真相源、过度复杂度和可删减代码。";default:return"独立评估问题,明确区分已验证事实、推断、风险和待确认项。"}}var i1;var B9=E(()=>{i1=["general","correctness","architecture","security","testing","maintainability"]});import{createHash as $K}from"node:crypto";function y7($){let Z=[];if($.notice)Z.push(VK($.notice));if(Z.push({tag:"markdown",element_id:M.consultIdentityPanel,content:["**全局评审身份**","所有项目群共用。每个 Token Source 的每个模型都会自动生成 `max` 默认身份。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
138
+ `);return""}function T7($,Z){if(!Z||typeof Z!=="object")return[];if($==="FileChange"||$==="fileChange"){if(!Array.isArray(Z.changes))return[];return Z.changes.filter((Q)=>Q&&typeof Q==="object").map((Q)=>({tool:$,path:typeof Q.path==="string"&&Q.path?Q.path:"?",body:typeof Q.diff==="string"?Q.diff:typeof Q.unified_diff==="string"?Q.unified_diff:""}))}if(!["Write","Edit","NotebookEdit","MultiEdit"].includes($))return[];let J=Z.file_path??Z.path??Z.notebook_path;return[{tool:$,path:typeof J==="string"&&J?J:"?",body:IJ($,Z)}]}function N7($){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?[ZK($.notice)]:[],{tag:"markdown",element_id:M.tasklistPanel,content:ez($)},$K($)]}}}function ez($){let Z=[`项目:${E7($.projectName)}`,`清单:${E7($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
139
+ `);if(Z.push("","已启用"),Z.push(`GUID:${E7($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
140
+ `)}function $K($){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 ZK($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
141
+ `).map((J)=>`<font color='${Z}'>${JK(J)||" "}</font>`).join(`
142
+ `)}}function E7($){return"`"+$.replace(/`/g,"\\`")+"`"}function JK($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var gJ=k(()=>{x$()});function $1($){switch($){case"correctness":return"正确性审查";case"architecture":return"架构审查";case"security":return"安全审查";case"testing":return"测试与回归";case"maintainability":return"简化与可维护性";default:return"通用顾问"}}function c2($){switch($){case"correctness":return"优先检查逻辑错误、边界条件、竞态和错误处理,每个结论给出可验证证据。";case"architecture":return"优先检查模块边界、状态所有权、协议契约和长期演进风险。";case"security":return"优先检查权限、凭据泄露、命令注入、路径越界、不可逆副作用和供应链风险。";case"testing":return"优先检查验收标准、回归面、失败路径、并发时序和测试可观测性。";case"maintainability":return"优先检查不必要的抽象、重复真相源、过度复杂度和可删减代码。";default:return"独立评估问题,明确区分已验证事实、推断、风险和待确认项。"}}var d1;var j9=k(()=>{d1=["general","correctness","architecture","security","testing","maintainability"]});import{createHash as QK}from"node:crypto";function k7($){let Z=[];if($.notice)Z.push(qK($.notice));if(Z.push({tag:"markdown",element_id:M.consultIdentityPanel,content:["**全局评审身份**","所有项目群共用。每个 Token Source 的每个模型都会自动生成 `max` 默认身份。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
143
143
  `)}),$.presetFailure)Z.push({tag:"markdown",content:`<font color='red'>身份配置 MISS:${s$($.presetFailure)}</font>`});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)=>`- **${s$(J.display)}**:${s$(J.reason)}`).join(`
144
- `)}]});if(Z.push(...$.catalog.map((J)=>ZK($.panelId,J))),Z.push(YK($)),$.presets.length)Z.push({tag:"hr"}),Z.push({tag:"markdown",content:`**自定义身份 · ${$.presets.length}**`}),Z.push(...$.presets.map((J)=>JK($.panelId,J)));return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 reviewers"},template:$.notice?.type==="error"?"red":"purple"},body:{elements:Z}}}function E7($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"选择评审角色"},template:"purple"},body:{elements:[{tag:"markdown",content:[`底层身份:**${s$($.identity.displayName)}**`,`模型:${Z1($.identity.model)}`,`effort:${Z1("max")}`].join(`
145
- `)},...QK($.panelId,$.identity.id),HK($.panelId)]}}}function x7($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"删除全局身份"},template:"red"},body:{elements:[{tag:"markdown",content:`<font color='red'>确认删除 **${s$($.preset.name)}**?这会影响所有项目群。</font>`},{tag:"column_set",columns:[B0("取消","default",{kind:"consult_identity_back",panel_id:$.panelId}),B0("确认删除","danger",{kind:"consult_identity_delete_confirm",panel_id:$.panelId,preset_id:$.preset.id})]}]}}}function N7($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:$.status==="running",summary:{content:F9($)}},header:{title:{tag:"plain_text",content:`\uD83E\uDDE0 ${$.kind}`},template:$.status==="failed"?"red":$.status==="completed"?"green":"purple"},body:{elements:[{tag:"collapsible_panel",header:{title:{tag:"plain_text",content:`咨询目标 · ${WK($)}`}},expanded:!1,elements:[{tag:"markdown",content:[$.question?`**问题**
146
- ${a($.question)}`:"",$.instructions?`**要求**
147
- ${a($.instructions)}`:"",`fingerprint: ${Z1($.targetFingerprint.slice(0,16))}`,$.crossReview?"交叉复核:开启":"交叉复核:关闭"].filter(Boolean).join(`
148
-
149
- `)}]},...$.reviewers.map(L9),D9($)]}}}function L9($){let Z=XK($),J=[`**${s$(Z)}**`];if($.output)J.push("",zK(a($.output),7000));if($.error)J.push("",`<font color='red'>${a($.error)}</font>`);if(!$.output&&!$.error)J.push("","_等待结果…_");return J.push("",`${Z1($.tokenSourceId)} · ${Z1($.model)} · ${Z1($.effort)}`),{tag:"collapsible_panel",element_id:P9($.identityId),header:{title:{tag:"plain_text",content:`${Z} · ${GK($.identityName,48)}`}},expanded:$.status==="failed",elements:[{tag:"markdown",content:J.join(`
150
- `)}]}}function D9($){let Z=$.reviewers.filter((H)=>H.status==="completed").length,J=$.reviewers.filter((H)=>H.status==="failed").length,Q=$.reviewers.filter((H)=>H.status==="cancelled").length,Y=$.status==="completed"?"✅ 咨询完成":$.status==="failed"?"❌ 咨询失败":$.status==="cancelled"?"\uD83D\uDED1 咨询已取消":"⏳ 咨询中";return{tag:"markdown",element_id:M.consultRunFooter,content:`${Y} · 完成 ${Z}/${$.reviewers.length} · 失败 ${J} · 取消 ${Q}`}}function P9($){return`cr_${$K("sha256").update($).digest("hex").slice(0,16)}`}function F9($){let Z=$.reviewers.filter((J)=>J.status==="completed").length;return`${$.status==="running"?"⏳":$.status==="completed"?"✅":$.status==="cancelled"?"\uD83D\uDED1":"❌"} ${$.kind} · ${Z}/${$.reviewers.length}`}function ZK($,Z){let J=Z.status==="ready",Q=J?"ready":`${Z.status}: ${Z.reason??"MISS"}`;return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${s$(Z.displayName)}**
151
- ${Z1(Z.model)} · max · ${s$(Q)}`}]},{tag:"column",width:"weighted",weight:1,elements:[J?IJ("添加","primary",{kind:"consult_identity_add",panel_id:$,identity_id:Z.id}):{tag:"markdown",content:"`MISS`"}]}]}}function JK($,Z){return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${s$(Z.name)}**
152
- ${$1(Z.role)} · ${Z.enabled?"已启用":"已停用"}`}]},B0(Z.enabled?"停":"启","default",{kind:"consult_identity_toggle",panel_id:$,preset_id:Z.id}),B0("删","danger",{kind:"consult_identity_delete",panel_id:$,preset_id:Z.id})]}}function QK($,Z){let J=["general","correctness","architecture","security","testing","maintainability"],Q=[];for(let Y=0;Y<J.length;Y+=2){let H=J.slice(Y,Y+2);Q.push({tag:"column_set",columns:H.map((V)=>B0($1(V),V==="general"?"default":"primary",{kind:"consult_identity_role",panel_id:$,identity_id:Z,role:V}))})}return Q}function YK($){return{tag:"column_set",columns:[B0("上一页","default",{kind:"consult_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),B0("刷新","default",{kind:"consult_identity_page",panel_id:$.panelId,page:$.page}),B0("下一页","default",{kind:"consult_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function HK($){return{tag:"column_set",columns:[B0("返回","default",{kind:"consult_identity_back",panel_id:$})]}}function B0($,Z,J){return{tag:"column",width:"weighted",weight:1,elements:[IJ($,Z,J)]}}function IJ($,Z,J){return{tag:"button",text:{tag:"plain_text",content:$},type:Z,behaviors:[{type:"callback",value:J}]}}function VK($){return{tag:"markdown",content:`<font color='${$.type==="error"?"red":$.type==="success"?"green":"grey"}'>${s$($.content)}</font>`}}function Z1($){return"`"+$.replace(/`/g,"\\`")+"`"}function s$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function XK($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"running":return"⏳ 评审中";default:return"⏳ 排队中"}}function WK($){switch($.target.type){case"commit":return`commit ${$.target.sha}`;case"base_branch":return`${$.target.branch}...HEAD`;case"proposal":return"方案文本";case"uncommitted_changes":return"未提交变更";default:return"当前工作目录"}}function zK($,Z){return $.length<=Z?$:`${$.slice(0,Z-24)}
153
-
154
- _卡片输出已截断,完整结果由 CLI 返回。_`}function GK($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var cJ=E(()=>{x$();B9()});function Q1($){return KK.has($)?$:null}function A9($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function d1($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function J1($){return String($?.subject??$?.content??"").trim()}function C7($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function pJ($){return`subj:${$}`}function mJ($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function BK($){let Z=J1($);if(!Z)return null;return{id:d1($)||pJ(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:C7($)??"pending"}}function b7($,Z,J,Q){if(Z==="TaskList"){let Y=A9(Q),H=Array.isArray(Y?.tasks)?Y.tasks:Array.isArray(Y)?Y:null;if(H===null)return $;let V=[];for(let X of H){let W=BK(X);if(W)V.push(W)}return V}if(Z==="TaskCreate"){let Y=Array.isArray(J?.tasks)?J.tasks:null;if(Y){let z=A9(Q),K=Array.isArray(z?.tasks)?z.tasks:Array.isArray(z)?z:null,_=$;return Y.forEach((j,B)=>{let L=J1(j);if(!L)return;let P=K?.[B],A=P&&d1(P)||mJ(Q??"");_=uJ(_,A,L,j)}),_}let H=A9(Q),V=H?.task??H,X=d1(V)||mJ(Q??""),W=J1(V)||J1(J);if(!W)return $;return uJ($,X,W,J)}if(Z==="TaskUpdate"){let Y=d1(J);if(!Y)return $;let H=C7(J);if(H==="deleted")return $.filter((X)=>X.id!==Y);let V=J1(J);if($.some((X)=>X.id===Y))return $.map((X)=>X.id===Y?{...X,...H?{status:H}:{},...V?{subject:V}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:X);return $}if(Z==="TaskGet"){let Y=A9(Q),H=Y?.task??Y,V=d1(H)||d1(J);if(!V)return $;let X=$.find((K)=>K.id===V),W=J1(H)||X?.subject||J1(J);if(!W)return $;let z={id:V,subject:W,description:typeof H?.description==="string"?H.description:X?.description,activeForm:typeof H?.activeForm==="string"?H.activeForm:X?.activeForm,status:C7(H)??X?.status??"pending"};return X?$.map((K)=>K.id===V?z:K):[...$,z]}return $}function uJ($,Z,J,Q){let Y=Z||pJ(J),H={...typeof Q?.activeForm==="string"&&Q.activeForm?{activeForm:Q.activeForm}:{},...typeof Q?.description==="string"&&Q.description?{description:Q.description}:{}};if($.some((V)=>V.id===Y))return $.map((V)=>V.id===Y?{...V,id:Y,subject:J,...H}:V);return[...$,{id:Y,subject:J,status:"pending",...H}]}function S7($){let Z=$.filter((H)=>H.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let H of Z){let V=qK[H.status];J.set(V,(J.get(V)??0)+1)}let Y=["进行中","待办","完成"].map((H)=>J.has(H)?`${H} ${J.get(H)}`:"").filter(Boolean).join(" · ");return`${Z.length} 项${Y?` · ${Y}`:""}`}function lJ($,Z){let J=$.filter((V)=>V.status!=="deleted"),Q=[`**待办**: ${J.length} 项`],Y=(V)=>{let X=parseInt(V,10);return Number.isNaN(X)?Number.MAX_SAFE_INTEGER:X},H=[...J].sort((V,X)=>{let W=Y(V.id)-Y(X.id);return W!==0?W:V.id.localeCompare(X.id)});for(let V of H.slice(0,12)){let X=jK[V.status],W=V.status==="in_progress"&&V.activeForm?V.activeForm:V.subject;Q.push(`- ${X} ${W||"(空)"}`)}if(H.length>12)Q.push(`- 还有 ${H.length-12} 项未显示`);if(Z)Q.push(""),Q.push(Z);return Q.join(`
155
- `)}function C0($,Z,J,Q){let Y=_K[J.name],H=S7(Z),V=`${J.status} \uD83D\uDD27 ${Y}: ${H}`;return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:V}},expanded:!1,elements:[{tag:"markdown",content:lJ(Z,Q)}]}}function Y1($){return{tag:"collapsible_panel",element_id:M.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${S7($)}`}},expanded:!0,elements:[{tag:"markdown",content:lJ($)}]}}var KK,_K,qK,jK;var iJ=E(()=>{x$();KK=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);_K={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},qK={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},jK={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var w$=E(()=>{x$();AJ();J7();fJ();gJ();cJ();iJ();a6()});import{spawn as LK}from"node:child_process";class R9{proc;buf="";nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor(){this.proc=LK(X2(),["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,Q]of this.pending)clearTimeout(Q.timer),Q.reject(Error(`${Z.message}; pending ${Q.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(`
156
- `))>=0){let J=this.buf.slice(0,Z).trim();if(this.buf=this.buf.slice(Z+1),!J)continue;let Q;try{Q=JSON.parse(J)}catch{continue}if(!Object.prototype.hasOwnProperty.call(Q,"id"))continue;let Y=this.pending.get(Q.id);if(!Y)continue;if(this.pending.delete(Q.id),clearTimeout(Y.timer),Q.error)Y.reject(Error(JSON.stringify(Q.error)));else Y.resolve(Q.result)}}request($,Z,J=m2){let Q=this.nextId++;return new Promise((Y,H)=>{if(!this.alive){H(Error(`codex app-server is not alive; cannot request ${$}`));return}let V=setTimeout(()=>{if(!this.pending.delete(Q))return;H(Error(`codex app-server ${$} timed out after ${J}ms`))},J);this.pending.set(Q,{resolve:Y,reject:H,method:$,timer:V});try{this.proc.stdin.write(JSON.stringify({id:Q,method:$,params:Z})+`
157
- `,(X)=>{if(!X)return;let W=this.pending.get(Q);if(!W)return;this.pending.delete(Q),clearTimeout(W.timer),W.reject(Error(`codex app-server write failed for ${$}: ${X.message}`))})}catch(X){this.pending.delete(Q),clearTimeout(V),H(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((Q)=>setTimeout(()=>Q(!1),$))]))return;if(!this.proc.kill("SIGKILL"))throw Error("codex app-server rejected SIGKILL");if(!await Promise.race([this.exitPromise.then(()=>!0),new Promise((Q)=>setTimeout(()=>Q(!1),$))]))throw Error(`codex app-server did not exit after SIGKILL (${$}ms)`)}}function U9($,Z){return new Promise((J,Q)=>{let Y=setTimeout(()=>Q(Error(`timeout after ${Z}ms`)),Z);$.then((H)=>{clearTimeout(Y),J(H)},(H)=>{clearTimeout(Y),Q(H)})})}function DK($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function M9($){if(!$)return null;return{percent:DK($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function PK($){let Z=M9($?.primary),J=M9($?.secondary),Q=(H)=>H?.durationMins!=null&&H.durationMins>0&&H.durationMins<=720,Y=(H)=>H?.durationMins!=null&&H.durationMins>720;if(Q(Z)&&Y(J))return{fiveHour:Z,weekly:J};if(Q(J)&&Y(Z))return{fiveHour:J,weekly:Z};if(Y(Z)&&!J)return{fiveHour:null,weekly:Z};if(Y(J)&&!Z)return{fiveHour:null,weekly:J};return{fiveHour:Z,weekly:J}}function FK($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Q=[];for(let[Y,H]of J){let{fiveHour:V,weekly:X}=PK(H);if(!V&&!X)continue;Q.push({limitId:Y,limitName:H?.limitName??null,fiveHour:V,weekly:X})}return{buckets:Q,defaultLimitId:$?.rateLimits?.limitId??void 0}}function AK($){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 nJ($){let Z=AK($),J=H1?.state==="ok"?H1.buckets??[]:[],Q=J.filter((Y)=>dJ(Y.fiveHour,M9($?.primary))&&dJ(Y.weekly,M9($?.secondary)));if(J.length>0&&Q.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&&Q.length===1&&Q[0].limitId!==$.limitId)G(`usage: rate-limit notification labeled limitId=${$.limitId} but content matches bucket ${Q[0].limitId} (known codex parser fallback relabels; ignoring notification payload)`)}function dJ($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function UK(){let $=new R9;try{await U9($.request("initialize",{clientInfo:{name:"lodestar-usage",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}),m2);let J=(await U9($.request("account/read",{}),m2))?.account;if(!J)return{state:"no_credentials"};if(J.type!=="chatgpt")return{state:"auth_failed"};let Q=await U9($.request("account/rateLimits/read",{}),m2);return oJ(Q,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 oJ($,Z){let{buckets:J,defaultLimitId:Q}=FK($),Y=J.find((H)=>H.limitId===Q)??J[0];if(!Y)return{state:"network",reason:"empty rate limit response"};return{state:"ok",subscriptionType:Z??Y.limitName??$?.rateLimits?.planType??"chatgpt",fiveHour:Y.fiveHour,weekly:Y.weekly,buckets:J,defaultLimitId:Y.limitId,fetchedAt:Date.now()}}function aJ(){return H1}async function O9(){if(n1)return n1;return n1=UK().then(($)=>{if(n1=null,$.state==="network")return H1??$;return H1=$,$}).catch(($)=>{return G(`usage: fetchUsage threw: ${$}`),n1=null,H1??{state:"network",reason:String($)}}),n1}function rJ($){return w7??=U9($("account/rateLimits/read",{}),m2).then((Z)=>{let J=oJ(Z);if(J.state==="ok")H1=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(()=>{w7=null}),w7}var m2=1e4,H1=null,n1=null,w7=null;var T9=E(()=>{k1();w()});import{readFileSync as MK}from"node:fs";import{homedir as RK}from"node:os";import{join as $Q}from"node:path";function OK(){return process.env.CLAUDE_CONFIG_DIR||$Q(RK(),".claude")}function v7(){try{let $=MK($Q(OK(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return G(`glm-usage: read settings.json env failed: ${$}`),{}}}function k9($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function TK($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function kK($){let Z=TK($);return Z&&k9($)?Z:null}function sJ($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function eJ($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function yK($){let Z=Array.isArray($?.limits)?$.limits:[],J=Z.filter((K)=>K?.type==="TOKENS_LIMIT"),Q=J.find((K)=>K?.unit===3&&K?.number===5),Y=J.find((K)=>K?.unit===6&&K?.number===1),H=Z.find((K)=>K?.type==="TIME_LIMIT"),V=(K)=>K?{percent:sJ(K.percentage),resetsAt:eJ(K.nextResetTime)}:null,X=V(Q),W=V(Y),z=H?{percent:sJ(H.percentage),resetsAt:eJ(H.nextResetTime),...typeof H.currentValue==="number"?{used:H.currentValue}:{},...typeof H.usage==="number"?{total:H.usage}:{}}:null;return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:X,weekly:W,monthly:z,fetchedAt:Date.now()}}async function h7($,Z){let J=$&&Z?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:v7(),Q=J.ANTHROPIC_AUTH_TOKEN,Y=J.ANTHROPIC_BASE_URL||"";if(!Q)return{state:"no_credentials"};let H=kK(Y);if(!H)return{state:"not_glm",baseUrl:Y||void 0};let V=`${H}/api/monitor/usage/quota/limit`,X=new AbortController,W=setTimeout(()=>X.abort(),tJ);try{let z=await fetch(V,{headers:{Authorization:Q,"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 K=await z.json();if(K?.success===!1||typeof K?.code==="number"&&K.code!==200)return{state:"network",reason:K?.msg?String(K.msg):`code ${K?.code}`};let _=K?.data??K;return yK(_)}catch(z){let K=z?.name==="AbortError"?`timeout ${tJ}ms`:z?.message??String(z);return G(`glm-usage: quota/limit fetch failed: ${K}`),{state:"network",reason:K}}finally{clearTimeout(W)}}async function g7(){if(o1)return o1;return o1=h7().then(($)=>{if(o1=null,$.state==="network")return f7??$;return f7=$,$}).catch(($)=>{return G(`glm-usage: fetchGlmUsage threw: ${$}`),o1=null,f7??{state:"network",reason:String($)}}),o1}var tJ=1e4,f7=null,o1=null;var y9=E(()=>{w()});function ZQ($){let Z=[];for(let J of $.matchAll(EK)){let Q=J[1]?.trim();if(Q)Z.push(Q)}return Z}function E9($,Z=process.platform){if(Z!=="win32")return $;let J=xK.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var EK,xK;var I7=E(()=>{EK=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;xK=/^\/([a-zA-Z])\//});function YQ($){if(JQ.test($))return{marker:"start",body:$.replace(JQ,"")};if(QQ.test($))return{marker:"end",body:$.replace(QQ,"")};return{marker:"none",body:$}}var JQ,QQ;var HQ=E(()=>{JQ=/^>{3,}[ \t]?/,QQ=/^<{3,}[ \t]?/});async function VQ($,Z,J,Q,Y){let{marker:H,body:V}=YQ(Z);if(H==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)m7($,"reopen");return $.multiMsgBuffer=[],c7($,V,J,Q,Y),!0}if(H==="end"){if($.multiMsgBuffer===null){if(V.trim()||J.length)return!1;return G(`session "${$.sessionName}": end marker without active multi-msg buffer, ignoring`),!0}c7($,V,J,Q,Y);let{multiMsgBuffer:X,multiMsgReactions:W}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await CK($,X,W),!0}if($.multiMsgBuffer!==null)return c7($,Z,J,Q,Y),!0;return!1}function c7($,Z,J,Q,Y){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Q,msgId:Y});if(Y)NK($,Y)}function NK($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await R$(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else P$(Z,J)})()}async function CK($,Z,J){for(let[V,X]of J)if(X)P$(V,X);let Q=Z.filter((V)=>V.text.trim()||V.files.length);if(Q.length===0){G(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await O($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Y=Q.map((V)=>{return(V.files.length?V.files.map((W)=>`[file: ${W}]`).join(" ")+`
158
- `:"")+V.text}).join(`
159
-
160
- `),H=Q[Q.length-1];G(`session "${$.sessionName}": multi-msg flush ${Q.length} segment(s) → 1 turn`),await $.onUserMessage(Y,[],H.userOpenId,H.msgId)}function m7($,Z){if($.multiMsgBuffer===null)return;let J=$.multiMsgBuffer.length;G(`session "${$.sessionName}": clear multi-msg buffer (${Z}): ${J} segment(s)`);for(let[Q,Y]of $.multiMsgReactions){if(Y)P$(Q,Y);R$(Q,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var XQ=E(()=>{n();w();HQ()});import{mkdtemp as SK,rm as wK,writeFile as fK}from"node:fs/promises";import{createRequire as vK}from"node:module";import{tmpdir as hK}from"node:os";import{join as WQ}from"node:path";function iK($){let Z=_Q.get($);if(Z)return Z;let{liteAdaptor:J}=X1("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Q}=X1("mathjax-full/js/handlers/html.js"),{mathjax:Y}=X1("mathjax-full/js/mathjax.js"),{TeX:H}=X1("mathjax-full/js/input/tex.js"),{AllPackages:V}=X1("mathjax-full/js/input/tex/AllPackages.js"),{SVG:X}=X1("mathjax-full/js/output/svg.js"),W=J({fontSize:$});Q(W);let z=Y.document("",{InputJax:new H({packages:V}),OutputJax:new X({fontCache:"none"})}),K={adaptor:W,doc:z};return _Q.set($,K),K}function qQ($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function dK($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function nK($,Z=l7,J=!0){try{let Q=Z*gK,{adaptor:Y,doc:H}=iK(Z),V=H.convert($,{display:J,em:Z,ex:Q,containerWidth:80*Z}),X=Y.outerHTML(V);if(/data-mjx-error=|mjx-merror/.test(X)){let n$=X.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(n$)}let W=X.indexOf("<svg"),z=X.lastIndexOf("</svg>");if(W<0||z<0)throw Error("MathJax returned no SVG");let K=X.slice(W,z+6),_=K.match(/^<svg\b[^>]*>/)?.[0];if(!_)throw Error("MathJax returned malformed SVG root");let j=qQ(_.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),B=qQ(_.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((n$)=>!Number.isFinite(n$))||P[2]<=0||P[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[A,R,D,F]=P,y=/<text\b/.test(K)?pK:0,C=`${A} ${R} ${D+y} ${F}`,x=j*Q,m=y*(x/D),g=Math.max(1,Math.ceil(x+m)),f=Math.max(1,Math.ceil(B*Q)),T=IK-u7*2,k=Math.min(1,T/g),u=Math.max(1,Math.round(g*k)),p=Math.max(1,Math.round(f*k));if(k<1&&p<cK)throw Error(`formula would be unreadable after width cap (${u}x${p})`);let $$=u+u7*2,o=p+GQ*2,A0=K.slice(_.length,-6).replace(/currentColor/g,zQ).replace(/font-family="serif"/g,`font-family="${lK}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${$$}" height="${o}" viewBox="0 0 ${$$} ${o}" style="color:${zQ}">`,`<rect x="0" y="0" width="${$$}" height="${o}" rx="6" fill="${DQ}"/>`,`<svg x="${u7}" y="${GQ}" width="${u}" height="${p}" viewBox="${dK(C)}" preserveAspectRatio="xMidYMid meet">`,A0,"</svg>","</svg>"].join(""),width:$$,height:o}}catch(Q){return G(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Q}`),null}}function oK($,Z=l7,J=!0){let Q=nK($,Z,J);if(!Q)return null;try{let{Resvg:Y}=X1("@resvg/resvg-js"),V=new Y(Q.svg,{background:DQ,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:KQ,sansSerifFamily:KQ}}).render().asPng(),X=new DataView(V.buffer,V.byteOffset,V.byteLength),W=X.getUint32(16),z=X.getUint32(20);if(W!==Q.width||z!==Q.height)throw Error(`PNG dimensions ${W}x${z} != SVG ${Q.width}x${Q.height}`);return{png:V,width:W,height:z}}catch(Y){return G(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Y}`),null}}function aK($){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 jQ($,Z){let J=[],Q=(K,_,j)=>{let B=K[0],L=_.trim();if(!L)return;J.push({start:Z+K.index,end:Z+K.index+B.length,tex:L,raw:B,display:j})},Y,H=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Y=H.exec($))!==null)Q(Y,Y[1]??Y[2]??"",!0);let V=/\\\(([\s\S]+?)\\\)/g;while((Y=V.exec($))!==null)Q(Y,Y[1]??"",!1);let X=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Y=X.exec($))!==null){let K=(Y[1]??"").trim();if(aK(K))Q(Y,K,!1)}J.sort((K,_)=>K.start-_.start||_.end-K.end);let W=[],z=-1;for(let K of J){if(K.start<z)continue;W.push(K),z=K.end}return W}function PQ($){let Z=S6($),J=[],Q=0;for(let Y of Z){if(Q<Y.start)J.push(...jQ($.slice(Q,Y.start),Q));Q=Math.max(Q,Y.end)}if(Q<$.length)J.push(...jQ($.slice(Q),Q));return J}function rK($){let Z=$;if(Z=Z.replace(/\\text\{([^{}]*)\}/g,"$1"),Z=Z.replace(/\\left\s*/g,"").replace(/\\right\s*/g,""),Z=Z.replace(/\\([A-Za-z]+)\b/g,(J,Q)=>{if(BQ[Q])return BQ[Q];if(Q==="times")return"×";if(Q==="cdot")return"·";if(Q==="div")return"÷";if(Q==="pm")return"±";if(Q==="leq"||Q==="le")return"≤";if(Q==="geq"||Q==="ge")return"≥";if(Q==="neq"||Q==="ne")return"≠";if(Q==="approx")return"≈";if(Q==="sim")return"~";if(Q==="infty")return"∞";if(Q==="partial")return"∂";if(Q==="nabla")return"∇";if(Q==="sqrt")return"√";if(Q==="to")return"→";return J}),/\\/.test(Z))return null;if(Z=Z.replace(/([_^])\{([^{}]+)\}/g,(J,Q,Y)=>Y.length===1?`${Q}${Y}`:`${Q}(${Y})`),Z=Z.replace(/√\{([^{}]+)\}/g,"√($1)"),/[{}]/.test(Z))return null;return Z}function $_($){let Z=LQ.get($);if(Z!==void 0)return Z;return Z=sK++,LQ.set($,Z),Z}function Z_($,Z){return`${uK}\x00${$_(Z)}\x00${$}`}function J_($){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 Q_($,Z){let J=Z_($,Z),Q=V1.get(J);if(Q)return Q;let Y=p7.get(J);if(Y)return Y;let H=(async()=>{let V=oK($,l7,!0);if(!V)return null;let X=null;try{X=await SK(WQ(hK(),"lodestar-math-"));let W=WQ(X,`formula-${J_($)}.png`);await fK(W,V.png);let z=await Z(W,{tex:$,width:V.width,height:V.height});if(!z)return G(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let K={key:z,width:V.width,height:V.height};if(V1.has(J))V1.delete(J);V1.set(J,K);while(V1.size>eK){let _=V1.keys().next().value;if(typeof _!=="string")break;V1.delete(_)}return K}catch(W){return G(`math-render: upload failed for ${$.slice(0,80)}…: ${W}`),null}finally{if(X)try{await wK(X,{recursive:!0,force:!0})}catch(W){G(`math-render: temp cleanup failed for ${X}: ${W}`)}}})();p7.set(J,H);try{return await H}finally{p7.delete(J)}}function Y_($,Z,J){let Q=$.width<=mK;return{type:"image",tex:Z.tex,index:J,element:{tag:"img",img_key:$.key,alt:{tag:"plain_text",content:Z.tex.replace(/\s+/g," ").slice(0,80)},scale_type:Q?"crop_center":"fit_horizontal",...Q?{size:`${$.width}px ${$.height}px`}:{},preview:!1}}}async function FQ($,Z={}){let J=PQ($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Q=Z.uploader??tK,Y=await Promise.all(J.map(async(K)=>{if(!K.display){let _=rK(K.tex);if(_!==null)return{unicode:_,uploaded:null}}return{unicode:null,uploaded:await Q_(K.tex,Q)}})),H=[],V="",X=0,W=0,z=()=>{if(!V)return;if(V.trim())H.push({type:"markdown",text:V});V=""};for(let K=0;K<J.length;K++){let _=J[K],j=Y[K];if(V+=$.slice(X,_.start),j.unicode!==null){V+=j.unicode,X=_.end;continue}let B=j.uploaded;if(!B){V+=_.raw,X=_.end;continue}z(),H.push(Y_(B,_,W++)),X=_.end}if(V+=$.slice(X),z(),!H.length)H.push({type:"markdown",text:$});return{blocks:H,formulaCount:J.length,renderedImageCount:W}}function i7($){return PQ($).length>0}var X1,gK=0.5,l7=22,zQ="#1F2329",DQ="#F7F8FA",u7=12,GQ=8,IK=720,cK=14,mK=278,uK="v4-native-cjk-tail-pad",pK=1100,KQ,lK="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",_Q,BQ,tK=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (n(),e));return Z($)},LQ,sK=1,V1,p7,eK=512;var AQ=E(()=>{w();X1=vK(import.meta.url),KQ=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",_Q=new Map;BQ={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:"Ω"};LQ=new WeakMap,V1=new Map,p7=new Map});import{isAbsolute as V_}from"node:path";function j$($){if($?.planLiveInserted)return M.planLive;return $?.taskLiveInserted?M.taskBoardLive:M.footer}function X_($){return $==="ImageGeneration"||$==="imageGeneration"}function W_($,Z,J){if(J||!X_($))return null;let Q=E9(Z.trim());return V_(Q)?Q:null}function z_($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function UQ($,Z,J){return $==="read"?u1(Z,J):m1(Z,J)}function MQ($,Z,J,Q){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Y=z_(J);if(Y&&$.currentTurn.openBatchI!==null){let W=$.currentTurn.openBatchI,z=$.currentTurn.toolBatches.get(W);if(z&&z.kind===Y){let K=z.items.length;z.items.push({toolUseId:Z,input:Q,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:W,name:J,input:Q,batchSlot:K});let _=Y==="read"?u1(W,z.items):m1(W,z.items);d($.currentTurn.cardId,M.tool(W),_),x9($.currentTurn,J,Q);return}}if(!Y)$.currentTurn.openBatchI=null;let H=Q1(J);if(H){let W=$.currentTurn;if(H==="TaskCreate"&&!W.taskBoardResetThisTurn)$.taskBoard=[],W.taskBoardResetThisTurn=!0;if(!W.taskLiveInserted)W.taskLiveInserted=!0,W$(W.cardId,Y1($.taskBoard),{type:"insert_before",targetElementId:M.footer});else d(W.cardId,M.taskBoardLive,Y1($.taskBoard));let z=H==="TaskCreate";if(z)W.taskUpdateI=null;else W.taskCreateI=null;let K=(z?W.taskCreateI:W.taskUpdateI)===null;if(K)if(z)W.taskCreateI=W.toolCount++;else W.taskUpdateI=W.toolCount++;let _=z?W.taskCreateI:W.taskUpdateI;W.toolByUseId.set(Z,{i:_,name:J,input:Q});let j=C0(_,$.taskBoard,{name:H,status:"⏳"});K?W$(W.cardId,j,{type:"insert_before",targetElementId:j$(W)}):d(W.cardId,M.tool(_),j),x9(W,J,Q);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let V=$.currentTurn.toolCount++;if(Y){$.currentTurn.openBatchI=V;let W=[{toolUseId:Z,input:Q,output:null,isError:!1}];$.currentTurn.toolBatches.set(V,{kind:Y,items:W}),$.currentTurn.toolByUseId.set(Z,{i:V,name:J,input:Q,batchSlot:0});let z=Y==="read"?u1(V,W):m1(V,W);W$($.currentTurn.cardId,z,{type:"insert_before",targetElementId:j$($.currentTurn)}),x9($.currentTurn,J,Q);return}if($.currentTurn.toolByUseId.set(Z,{i:V,name:J,input:Q}),J==="AskUserQuestion"){let W=Array.isArray(Q?.questions)?Q.questions:[],z=W.length>0?0:void 0,K=new Map;$.pendingAsks.set(Z,{questions:W,i:V,answers:{},answered:K,currentIdx:z});let _=w2(V,Z,W,"\uD83E\uDD14",{currentIdx:z,answered:K});if(W$($.currentTurn.cardId,_,{type:"insert_before",targetElementId:j$($.currentTurn)}),$.currentTurn.userOpenId&&$.currentTurn.messageId){let j=$.currentTurn,B=W[0]?.question?.trim()??"",L=B.length>40?B.slice(0,40)+"…":B,P=W.length>1?`❓ 待回答 ${W.length} 题${L?`: ${L}`:""}`:L?`❓ ${L}`:"❓ 等你回答问题";(async()=>{X$(j.cardId),await I4(j.cardId,{config:{summary:{content:P}}}),await a0(j.messageId,[j.userOpenId])})()}return}let X=q0(V,J,Q,null,"⏳");W$($.currentTurn.cardId,X,{type:"insert_before",targetElementId:j$($.currentTurn)}),x9($.currentTurn,J,Q)}function x9($,Z,J){if(!$)return;let Q=_0(Z,J),Y=Q.length>80?Q.slice(0,80)+"…":Q,H=s0(Z),V=Y?`\uD83D\uDD27 ${H}: ${Y}`:`\uD83D\uDD27 ${H}`;G0($.cardId,V)}function RQ($,Z,J,Q){if(!$.currentTurn)return;let Y=$.currentTurn.toolByUseId.get(Z);if(!Y)return;let H=typeof J==="string"?J:Array.isArray(J)?J.map((z)=>z?.text??JSON.stringify(z)).join(`
161
- `):JSON.stringify(J);Y.output=H,Y.isError=Q;let V=W_(Y.name,H,Q);if(V)$.sendOutboundPath(V,Y.name);if(Y.name==="AskUserQuestion"){N9($);return}if(Y.batchSlot!=null){let z=$.currentTurn.toolBatches.get(Y.i);if(z){let K=z.items[Y.batchSlot];if(K)K.output=H,K.isError=Q;let _=UQ(z.kind,Y.i,z.items);d($.currentTurn.cardId,M.tool(Y.i),_)}N9($);return}let X=Q1(Y.name);if(X){G_($,Y,X,Y.input,H,Q,Y.resolvedNote);return}let W=q0(Y.i,Y.name,Y.input,H,Q?"❌":"✅",Y.resolvedNote);d($.currentTurn.cardId,M.tool(Y.i),W),N9($)}function G_($,Z,J,Q,Y,H,V){if(!$.currentTurn)return;if(!H)$.taskBoard=b7($.taskBoard,J,Q,Y);let X=C0(Z.i,$.taskBoard,{name:J,status:H?"❌":"✅"},V);if(d($.currentTurn.cardId,M.tool(Z.i),X),$.currentTurn.taskLiveInserted)d($.currentTurn.cardId,M.taskBoardLive,Y1($.taskBoard));N9($)}function N9($){let Z=$.currentTurn;if(!Z)return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function d7($,Z,J,Q,Y){let H=$.currentTurn;if(!H)return;for(let[V,X]of Q){if(H.toolByUseId.has(V))continue;let W=X.batchSlot??null,z=X.input,K,_;if(W!=null){let R=Y.get(X.i)?.items[W];if(!R)continue;z=R.input,K=R.output,_=R.isError}else K=X.output??null,_=X.isError??!1;let j=K!=null,B=g1(Z,M.tool(X.i));if(j&&!B)continue;if(W!=null){let R=Y.get(X.i)?.kind;if(!R)continue;let D=H.toolCount++,F={toolUseId:V,input:z,output:K,isError:_};H.toolBatches.set(D,{kind:R,items:[F]}),H.toolByUseId.set(V,{...X,i:D,batchSlot:0}),W$(J,UQ(R,D,[F]),{type:"insert_before",targetElementId:j$(H)});continue}let L=Q1(X.name);if(L){let R=L==="TaskCreate";if(R)H.taskUpdateI=null;else H.taskCreateI=null;let D=(R?H.taskCreateI:H.taskUpdateI)===null;if(D)if(R)H.taskCreateI=H.toolCount++;else H.taskUpdateI=H.toolCount++;let F=R?H.taskCreateI:H.taskUpdateI;H.toolByUseId.set(V,{...X,i:F});let y=!j?"⏳":_?"❌":"✅",C=C0(F,$.taskBoard,{name:L,status:y},X.resolvedNote);D?W$(J,C,{type:"insert_before",targetElementId:j$(H)}):d(J,M.tool(F),C);continue}let P=H.toolCount++;H.toolByUseId.set(V,{...X,i:P});let A=!j?"⏳":_?"❌":"✅";W$(J,q0(P,X.name,X.input,K,A,X.resolvedNote),{type:"insert_before",targetElementId:j$(H)})}}var OQ=E(()=>{I7();t0();w$();n()});function TQ($){return $.pendingAsks.size>0}async function kQ($,Z,J,Q){let Y=$.pendingAsks.entries().next();if(Y.done){G(`session "${$.sessionName}": onAskMessageAnswer with no pending — falling back to onUserMessage`),await $.onUserMessage(Z,[],J,Q);return}let[H,V]=Y.value;if(V.currentIdx===void 0){if(V.requestId){G(`session "${$.sessionName}": pending ask ${H} awaiting finalize — ignoring message`);return}G(`session "${$.sessionName}": pending ask ${H} orphaned (no can_use_tool) — dropping zombie, reprocessing as user message`),$.pendingAsks.delete(H),await $.onUserMessage(Z,[],J,Q);return}if(await n7($,H,V.currentIdx,Z,J)&&Q)R$(Q,"CheckMark")}async function yQ($,Z,J,Q,Y){let H=$.pendingAsks.get(Z);if(!H)return G(`session "${$.sessionName}": stray ask answer for ${Z}`),!1;if(J!==H.currentIdx)return G(`session "${$.sessionName}": stale ask click q=${J} current=${H.currentIdx}`),!1;return EQ($,Z,{optionIdx:Q,user:Y})}async function n7($,Z,J,Q,Y){let H=$.pendingAsks.get(Z);if(!H)return G(`session "${$.sessionName}": stray ask custom for ${Z}`),!1;let V=(Q??"").trim();if(!V)return G(`session "${$.sessionName}": empty custom answer, ignoring`),!1;if(J!==H.currentIdx)return G(`session "${$.sessionName}": stale ask custom q=${J} current=${H.currentIdx}`),!1;return EQ($,Z,{customText:V,user:Y})}function EQ($,Z,J){let Q=$.pendingAsks.get(Z);if(!Q||Q.currentIdx===void 0)return!1;let Y=Q.currentIdx,H=Q.questions[Y];if(!H)return G(`session "${$.sessionName}": advanceAsk currentIdx=${Y} out of range`),!1;let V;if(J.customText!==void 0)V=J.customText;else if(J.optionIdx!==void 0){let _=H.options?.[J.optionIdx];if(!_)return G(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;V=_.label}else return G(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Q.answers[H.question]=V,Q.answered.set(Y,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let X=Q.questions.length,W=void 0;for(let _=Y+1;_<X;_++)if(!Q.answered.has(_)){W=_;break}Q.currentIdx=W;let z=$.currentTurn,K=z?.toolByUseId.get(Z);if(z&&K){let _=w2(K.i,Z,Q.questions,W===void 0?"✅":"\uD83E\uDD14",{currentIdx:W,answered:Q.answered});d(z.cardId,M.tool(K.i),_)}if(W===void 0)if(Q.requestId)o7($,Z);else G(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`);return!0}function o7($,Z){let J=$.pendingAsks.get(Z);if(!J||!J.requestId)return;let Q=$.currentTurn?.toolByUseId.get(Z),Y=Q?.input??{};if($.proc?.sendPermissionResponse(J.requestId,"allow",{updatedInput:{...Y,answers:J.answers}}),$.pendingPermissions.delete(J.requestId),Q)Q.output=JSON.stringify({answers:J.answers}),Q.isError=!1;if($.pendingAsks.delete(Z),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var a7=E(()=>{t0();w$();n();w()});async function xQ($,Z,J,Q){let Y=$.pendingPermissions.get(Z);if(!Y)return G(`session "${$.sessionName}": stray permission ${Z}`),{ok:!1,message:"此权限请求已失效或已处理"};let H=$.proc;if(!H)return G(`session "${$.sessionName}": permission ${Z} has no active process`),{ok:!1,message:"后端进程已退出,权限决定未送达"};let V=J==="deny"?"deny":"allow";try{H.sendPermissionResponse(Z,V,J==="allow_always"?{updatedPermissions:Y.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,W=X?.toolByUseId.get(Y.toolUseId);if(X&&W){let z=Q1(W.name);if(J==="deny"){let K=`\uD83D\uDEAB 已拒绝 by ${Q||"匿名"}`,_=z?C0(W.i,$.taskBoard,{name:z,status:"❌"},K):q0(W.i,W.name,W.input,K,"❌");d(X.cardId,M.tool(W.i),_)}else{let K=J==="allow_always"?"始终允许":"已允许";W.resolvedNote=`✅ **${K}** by ${Q||"匿名"}`;let _=z?C0(W.i,$.taskBoard,{name:z,status:"⏳"},W.resolvedNote):q0(W.i,W.name,W.input,null,"⏳",W.resolvedNote);d(X.cardId,M.tool(W.i),_)}}if(G(`session "${$.sessionName}": permission decision request=${Z} tool_use_id=${Y.toolUseId} decision=${J}`),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working";return{ok:!0,message:J==="deny"?"已拒绝":J==="allow_always"?"已始终允许":"已允许"}}function NQ($,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 Q=Z.tool_use_id;if(!Q){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 Y=J.toolByUseId.get(Q);if(!Y){G(`session "${$.sessionName}": can_use_tool for unknown tool_use_id=${Q} — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"unknown tool_use_id"});return}if(Y.name==="AskUserQuestion"){let V=$.pendingAsks.get(Q);if(!V){G(`session "${$.sessionName}": AskUserQuestion ${Q} missing pendingAsk — deny`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no pending ask"});return}if(V.requestId=Z.request_id,$.pendingPermissions.set(Z.request_id,{toolUseId:Q}),V.currentIdx===void 0)o7($,Q);return}$.status="awaiting_permission",$.pendingPermissions.set(Z.request_id,{toolUseId:Q,permissionSuggestions:Z.permission_suggestions}),G(`session "${$.sessionName}": can_use_tool request=${Z.request_id} tool_use_id=${Q} tool=${Y.name}`);let H=J9(Y.i,Y.name,Y.input,Z.request_id);if(d(J.cardId,M.tool(Y.i),H),J.userOpenId&&J.messageId){let V=_0(Y.name,Y.input),X=s0(Y.name),W=V&&V.length>30?V.slice(0,30)+"…":V,z=W?`\uD83D\uDD10 等审批: ${X} · ${W}`:`\uD83D\uDD10 等审批: ${X}`;(async()=>{X$(J.cardId),await I4(J.cardId,{config:{summary:{content:z}}}),await a0(J.messageId,[J.userOpenId])})()}}var CQ=E(()=>{t0();w$();n();w();a7()});function bQ($,Z=wQ){return new Promise((J,Q)=>{let Y=setTimeout(()=>Q(Error(`timeout ${Z}ms`)),Z);$.then((H)=>{clearTimeout(Y),J(H)},(H)=>{clearTimeout(Y),Q(H)})})}function SQ($){return typeof $==="string"&&j_.includes($)?$:null}async function fQ(){let $=new R9;try{await bQ($.request("initialize",{clientInfo:{name:"lodestar-models",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}));let Z=await bQ($.request("model/list",{})),J=Array.isArray(Z?.data)?Z.data:[],Q=[];for(let Y of J){if(!Y||Y.hidden||!Y.id)continue;let H=(Array.isArray(Y.supportedReasoningEfforts)?Y.supportedReasoningEfforts:[]).map((X)=>SQ(X?.reasoningEffort)).filter((X)=>X!==null);if(!H.length)continue;let V=SQ(Y.defaultReasoningEffort)??H[0];Q.push({model:String(Y.id),display:typeof Y.displayName==="string"&&Y.displayName?String(Y.displayName):String(Y.id),efforts:H,defaultEffort:V})}return Q}finally{await $.close()}}async function vQ($,Z){let J=new URL($),Q=J.pathname.replace(/\/+$/,""),Y=`${J.protocol}//${J.host}${Q}/v1/models`,H=await fetch(Y,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(wQ)});if(!H.ok)throw Error(`HTTP ${H.status}`);let V=await H.json();return(Array.isArray(V?.data)?V.data:[]).filter((W)=>W&&(W.display_name||W.id)).map((W)=>{let z=String(W.display_name||W.id);return{model:z,display:z,efforts:i$,defaultEffort:"max"}})}var wQ=1e4,j_,i$;var u2=E(()=>{T9();j_=["none","minimal","low","medium","high","xhigh","max","ultra"];i$=["max","xhigh","high","medium","low"]});import{existsSync as B_}from"node:fs";import{homedir as L_}from"node:os";import{join as hQ}from"node:path";function C9($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function D_($){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(C9($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(C9($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt}}function P_($){if($.state!=="ok"||!$.buckets?.length)return null;let Z=[];for(let J of $.buckets){let Q=J.limitId===$.defaultLimitId?J.limitName??"默认配额":J.limitName??J.limitId;if(J.fiveHour)Z.push(C9(J.fiveHour,"fiveHour",`${Q} 5h`));if(J.weekly)Z.push(C9(J.weekly,"weekly",`${Q} 周`))}return Z.length?Z:null}function F_(){let $=process.env.CODEX_HOME||hQ(L_(),".codex");return B_(hQ($,"auth.json"))}var gQ=E(()=>{y$();A$();T9();u2();w();V0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=F_(),J=$.model?.trim()||void 0,Q=$.effort?.trim()||void 0,Y={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(!Y.enabled){Y.models=[],Y.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}Y.modelCatalogState={status:"loading",updatedAt:null};try{if(Y.models=await fQ(),Q)for(let H of Y.models)H.defaultEffort=Q;if(!J)Y.defaultModel=Y.models[0]?.model??"";Y.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){G(`codex-sub refreshModels MISS: ${H?.message??H}`),Y.models=[],Y.modelCatalogState={status:"failed",updatedAt:Date.now(),error:H?.message??String(H)}}},spawnEnv(H){let V=m0(H);return Object.assign(V,S.codex.env),V},resolveSpawnModel(H){return H},async readUsage(){let H=await O9(),V=D_(H),X=P_(H);if(X)V.windows=X;return V}};return Y}})});function U_($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function b9($,Z,J){try{let Q=await fetch(U_($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(A_)});if(Q.ok)return"exists";if(Q.status===400){let Y=await Q.text();return Y.includes("1214")||Y.includes("不存在")||Y.includes("not exist")?"not_found":"no_verdict"}return G(`model-existence: ${J} HTTP ${Q.status}, no verdict`),"no_verdict"}catch(Q){return G(`model-existence: ${J} MISS (${Q?.message??Q})`),"no_verdict"}}var A_=15000;var r7=E(()=>{w()});function IQ($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function M_($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function R_($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function O_($){let Z=(J)=>{let Q=J.match(/(\d+(?:\.\d+)?)/);return Q?Number(Q[1]):-1};return[...$].sort((J,Q)=>Z(Q)-Z(J))[0]??""}function T_($){let Z={};for(let J of($??"").split(",")){let Q=J.indexOf("=");if(Q<=0)continue;let Y=J.slice(0,Q).trim().toLowerCase(),H=J.slice(Q+1).trim();if((Y==="opus"||Y==="sonnet"||Y==="haiku")&&H)Z[Y]=H}return Z}function k_($){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(IQ($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(IQ($.weekly,"weekly","周额度"));if($.monthly)Z.push(M_($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var cQ=E(()=>{A$();y9();u2();U4();r7();w();V0({kind:"glm-coding-plan",configSectionId:"glm",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||"",Q=$.auth_token?.trim()||Z?.auth_token?.trim()||"",Y=!!(J&&Q)&&k9(J),H=$.model?.trim()||void 0,V=T_($.slots),X={id:"glm",kind:"glm-coding-plan",agent:"claude",display:$.display?.trim()||"GLM Coding Plan",enabled:Y,models:[],modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},defaultModel:H??"",async refreshModels(){if(!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let W=await vQ(J,Q),K=R_($.models).filter((_)=>!W.some((j)=>j.model.toLowerCase()===_.toLowerCase())).map((_)=>({model:_,display:_,efforts:i$,defaultEffort:"max"}));if(X.models=[...W,...K],!H)X.defaultModel=O_(X.models.map((_)=>_.model));for(let _ of X.models){let j=A4("glm",_.model);_.context1m=j!=null&&j>=1e6||void 0}X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(W){G(`glm refreshModels MISS: ${W?.message??W}`),X.models=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W?.message??String(W)}}},spawnEnv(W){let K={...m0(W)};if(K.ANTHROPIC_BASE_URL=J,K.ANTHROPIC_AUTH_TOKEN=Q,V.opus)K.ANTHROPIC_DEFAULT_OPUS_MODEL=V.opus;if(V.sonnet)K.ANTHROPIC_DEFAULT_SONNET_MODEL=V.sonnet;if(V.haiku)K.ANTHROPIC_DEFAULT_HAIKU_MODEL=V.haiku;return K},resolveSpawnModel(W){return F4("glm",W)},async verifyModel(W){return b9(J,{Authorization:`Bearer ${Q}`},W)},async readUsage(){return k_(await h7(J,Q))}};return X},setup:{commandSuffix:"glm",hint:($)=>`启用 ${$}:发送
144
+ `)}]});if(Z.push(...$.catalog.map((J)=>WK($.panelId,J))),Z.push(KK($)),$.presets.length)Z.push({tag:"hr"}),Z.push({tag:"markdown",content:`**自定义身份 · ${$.presets.length}**`}),Z.push(...$.presets.map((J)=>GK($.panelId,J)));return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 reviewers"},template:$.notice?.type==="error"?"red":"purple"},body:{elements:Z}}}function x7($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"选择评审角色"},template:"purple"},body:{elements:[{tag:"markdown",content:[`底层身份:**${s$($.identity.displayName)}**`,`模型:${Z1($.identity.model)}`,`effort:${Z1("max")}`].join(`
145
+ `)},...zK($.panelId,$.identity.id),_K($.panelId)]}}}function y7($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"删除全局身份"},template:"red"},body:{elements:[{tag:"markdown",content:`<font color='red'>确认删除 **${s$($.preset.name)}**?这会影响所有项目群。</font>`},{tag:"column_set",columns:[j0("取消","default",{kind:"consult_identity_back",panel_id:$.panelId}),j0("确认删除","danger",{kind:"consult_identity_delete_confirm",panel_id:$.panelId,preset_id:$.preset.id})]}]}}}function C7($){let Z=F9($.reviewers.length);return{schema:"2.0",config:{update_multi:!0,streaming_mode:$.status==="running",summary:{content:P9($)}},header:{title:{tag:"plain_text",content:`\uD83E\uDDE0 ${$.kind}`},template:$.status==="failed"?"red":$.status==="completed"?"green":"purple"},body:{elements:[{tag:"collapsible_panel",header:{title:{tag:"plain_text",content:`咨询目标 · ${jK($)}`}},expanded:!1,elements:[{tag:"markdown",content:[$.question?`**问题**
146
+ ${cJ($.question,YK,"问题")}`:"",$.instructions?`**要求**
147
+ ${cJ($.instructions,HK,"要求")}`:"",`fingerprint: ${Z1($.targetFingerprint.slice(0,16))}`,$.crossReview?"交叉复核:开启":"交叉复核:关闭"].filter(Boolean).join(`
148
+
149
+ `)}]},...$.reviewers.map((J)=>L9(J,Z)),D9($)]}}}function L9($,Z=mJ){let J=BK($),Q=[`**${s$(J)}**`];if($.output)Q.push("",LK(s($.output),Z));if($.error)Q.push("",`<font color='red'>${s($.error)}</font>`);if(!$.output&&!$.error)Q.push("","_等待结果…_");return Q.push("",`${Z1($.tokenSourceId)} · ${Z1($.model)} · ${Z1($.effort)}`),{tag:"collapsible_panel",element_id:A9($.identityId),header:{title:{tag:"plain_text",content:`${J} · ${DK($.identityName,48)}`}},expanded:$.status==="failed",elements:[{tag:"markdown",content:Q.join(`
150
+ `)}]}}function D9($){let Z=$.reviewers.filter((H)=>H.status==="completed").length,J=$.reviewers.filter((H)=>H.status==="failed").length,Q=$.reviewers.filter((H)=>H.status==="cancelled").length,Y=$.status==="completed"?"✅ 咨询完成":$.status==="failed"?"❌ 咨询失败":$.status==="cancelled"?"\uD83D\uDED1 咨询已取消":"⏳ 咨询中";return{tag:"markdown",element_id:M.consultRunFooter,content:`${Y} · 完成 ${Z}/${$.reviewers.length} · 失败 ${J} · 取消 ${Q}`}}function A9($){return`cr_${QK("sha256").update($).digest("hex").slice(0,16)}`}function F9($){let Z=Math.max(1,Math.floor($));return Math.min(mJ,Math.max(VK,Math.floor(XK/Z)))}function P9($){let Z=$.reviewers.filter((J)=>J.status==="completed").length;return`${$.status==="running"?"⏳":$.status==="completed"?"✅":$.status==="cancelled"?"\uD83D\uDED1":"❌"} ${$.kind} · ${Z}/${$.reviewers.length}`}function WK($,Z){let J=Z.status==="ready",Q=J?"ready":`${Z.status}: ${Z.reason??"MISS"}`;return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${s$(Z.displayName)}**
151
+ ${Z1(Z.model)} · max · ${s$(Q)}`}]},{tag:"column",width:"weighted",weight:1,elements:[J?uJ("添加","primary",{kind:"consult_identity_add",panel_id:$,identity_id:Z.id}):{tag:"markdown",content:"`MISS`"}]}]}}function GK($,Z){return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${s$(Z.name)}**
152
+ ${$1(Z.role)} · ${Z.enabled?"已启用":"已停用"}`}]},j0(Z.enabled?"停":"启","default",{kind:"consult_identity_toggle",panel_id:$,preset_id:Z.id}),j0("删","danger",{kind:"consult_identity_delete",panel_id:$,preset_id:Z.id})]}}function zK($,Z){let J=["general","correctness","architecture","security","testing","maintainability"],Q=[];for(let Y=0;Y<J.length;Y+=2){let H=J.slice(Y,Y+2);Q.push({tag:"column_set",columns:H.map((X)=>j0($1(X),X==="general"?"default":"primary",{kind:"consult_identity_role",panel_id:$,identity_id:Z,role:X}))})}return Q}function KK($){return{tag:"column_set",columns:[j0("上一页","default",{kind:"consult_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),j0("刷新","default",{kind:"consult_identity_page",panel_id:$.panelId,page:$.page}),j0("下一页","default",{kind:"consult_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function _K($){return{tag:"column_set",columns:[j0("返回","default",{kind:"consult_identity_back",panel_id:$})]}}function j0($,Z,J){return{tag:"column",width:"weighted",weight:1,elements:[uJ($,Z,J)]}}function uJ($,Z,J){return{tag:"button",text:{tag:"plain_text",content:$},type:Z,behaviors:[{type:"callback",value:J}]}}function qK($){return{tag:"markdown",content:`<font color='${$.type==="error"?"red":$.type==="success"?"green":"grey"}'>${s$($.content)}</font>`}}function Z1($){return"`"+$.replace(/`/g,"\\`")+"`"}function s$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function BK($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"running":return"⏳ 评审中";default:return"⏳ 排队中"}}function jK($){switch($.target.type){case"commit":return`commit ${$.target.sha}`;case"base_branch":return`${$.target.branch}...HEAD`;case"proposal":return"方案文本";case"uncommitted_changes":return"未提交变更";default:return"当前工作目录"}}function LK($,Z){if($.length<=Z)return $;let J="_卡片输出已截断,完整结果由 CLI 返回。_",Q=Math.max(0,Z-J.length-2);return`${$.slice(0,Q)}
153
+
154
+ ${J}`}function cJ($,Z,J){let Q=s($);if(Q.length<=Z)return Q;let Y=`_卡片${J}预览已截断;完整${J}仍原样交给 reviewer,并保存在 consult 结果文件中。_`,H=Math.max(0,Z-Y.length-2);return`${Q.slice(0,H)}
155
+
156
+ ${Y}`}function DK($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var YK=8000,HK=4000,XK=48000,mJ=7000,VK=512;var pJ=k(()=>{x$();j9()});function Q1($){return AK.has($)?$:null}function U9($){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 J1($){return String($?.subject??$?.content??"").trim()}function S7($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function iJ($){return`subj:${$}`}function lJ($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function MK($){let Z=J1($);if(!Z)return null;return{id:i1($)||iJ(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:S7($)??"pending"}}function b7($,Z,J,Q){if(Z==="TaskList"){let Y=U9(Q),H=Array.isArray(Y?.tasks)?Y.tasks:Array.isArray(Y)?Y:null;if(H===null)return $;let X=[];for(let V of H){let W=MK(V);if(W)X.push(W)}return X}if(Z==="TaskCreate"){let Y=Array.isArray(J?.tasks)?J.tasks:null;if(Y){let G=U9(Q),K=Array.isArray(G?.tasks)?G.tasks:Array.isArray(G)?G:null,_=$;return Y.forEach((B,j)=>{let L=J1(B);if(!L)return;let A=K?.[j],P=A&&i1(A)||lJ(Q??"");_=dJ(_,P,L,B)}),_}let H=U9(Q),X=H?.task??H,V=i1(X)||lJ(Q??""),W=J1(X)||J1(J);if(!W)return $;return dJ($,V,W,J)}if(Z==="TaskUpdate"){let Y=i1(J);if(!Y)return $;let H=S7(J);if(H==="deleted")return $.filter((V)=>V.id!==Y);let X=J1(J);if($.some((V)=>V.id===Y))return $.map((V)=>V.id===Y?{...V,...H?{status:H}:{},...X?{subject:X}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:V);return $}if(Z==="TaskGet"){let Y=U9(Q),H=Y?.task??Y,X=i1(H)||i1(J);if(!X)return $;let V=$.find((K)=>K.id===X),W=J1(H)||V?.subject||J1(J);if(!W)return $;let G={id:X,subject:W,description:typeof H?.description==="string"?H.description:V?.description,activeForm:typeof H?.activeForm==="string"?H.activeForm:V?.activeForm,status:S7(H)??V?.status??"pending"};return V?$.map((K)=>K.id===X?G:K):[...$,G]}return $}function dJ($,Z,J,Q){let Y=Z||iJ(J),H={...typeof Q?.activeForm==="string"&&Q.activeForm?{activeForm:Q.activeForm}:{},...typeof Q?.description==="string"&&Q.description?{description:Q.description}:{}};if($.some((X)=>X.id===Y))return $.map((X)=>X.id===Y?{...X,id:Y,subject:J,...H}:X);return[...$,{id:Y,subject:J,status:"pending",...H}]}function w7($){let Z=$.filter((H)=>H.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let H of Z){let X=PK[H.status];J.set(X,(J.get(X)??0)+1)}let Y=["进行中","待办","完成"].map((H)=>J.has(H)?`${H} ${J.get(H)}`:"").filter(Boolean).join(" · ");return`${Z.length} 项${Y?` · ${Y}`:""}`}function nJ($,Z){let J=$.filter((X)=>X.status!=="deleted"),Q=[`**待办**: ${J.length} 项`],Y=(X)=>{let V=parseInt(X,10);return Number.isNaN(V)?Number.MAX_SAFE_INTEGER:V},H=[...J].sort((X,V)=>{let W=Y(X.id)-Y(V.id);return W!==0?W:X.id.localeCompare(V.id)});for(let X of H.slice(0,12)){let V=UK[X.status],W=X.status==="in_progress"&&X.activeForm?X.activeForm:X.subject;Q.push(`- ${V} ${W||"(空)"}`)}if(H.length>12)Q.push(`- 还有 ${H.length-12} 项未显示`);if(Z)Q.push(""),Q.push(Z);return Q.join(`
157
+ `)}function y0($,Z,J,Q){let Y=FK[J.name],H=w7(Z),X=`${J.status} \uD83D\uDD27 ${Y}: ${H}`;return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:nJ(Z,Q)}]}}function Y1($){return{tag:"collapsible_panel",element_id:M.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${w7($)}`}},expanded:!0,elements:[{tag:"markdown",content:nJ($)}]}}var AK,FK,PK,UK;var oJ=k(()=>{x$();AK=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);FK={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},PK={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},UK={pending:"",in_progress:"\uD83D\uDD04",completed:"",deleted:"\uD83D\uDDD1️"}});var w$=k(()=>{x$();UJ();Q7();vJ();gJ();pJ();oJ();r8()});import{spawn as RK}from"node:child_process";class O9{proc;buf="";nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor(){this.proc=RK(V2(),["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)z(`usage[codex stderr]: ${J}`)});let $=(Z)=>{if(!this.alive)return;this.alive=!1;for(let[J,Q]of this.pending)clearTimeout(Q.timer),Q.reject(Error(`${Z.message}; pending ${Q.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(`
158
+ `))>=0){let J=this.buf.slice(0,Z).trim();if(this.buf=this.buf.slice(Z+1),!J)continue;let Q;try{Q=JSON.parse(J)}catch{continue}if(!Object.prototype.hasOwnProperty.call(Q,"id"))continue;let Y=this.pending.get(Q.id);if(!Y)continue;if(this.pending.delete(Q.id),clearTimeout(Y.timer),Q.error)Y.reject(Error(JSON.stringify(Q.error)));else Y.resolve(Q.result)}}request($,Z,J=m2){let Q=this.nextId++;return new Promise((Y,H)=>{if(!this.alive){H(Error(`codex app-server is not alive; cannot request ${$}`));return}let X=setTimeout(()=>{if(!this.pending.delete(Q))return;H(Error(`codex app-server ${$} timed out after ${J}ms`))},J);this.pending.set(Q,{resolve:Y,reject:H,method:$,timer:X});try{this.proc.stdin.write(JSON.stringify({id:Q,method:$,params:Z})+`
159
+ `,(V)=>{if(!V)return;let W=this.pending.get(Q);if(!W)return;this.pending.delete(Q),clearTimeout(W.timer),W.reject(Error(`codex app-server write failed for ${$}: ${V.message}`))})}catch(V){this.pending.delete(Q),clearTimeout(X),H(V instanceof Error?V:Error(String(V)))}})}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((Q)=>setTimeout(()=>Q(!1),$))]))return;if(!this.proc.kill("SIGKILL"))throw Error("codex app-server rejected SIGKILL");if(!await Promise.race([this.exitPromise.then(()=>!0),new Promise((Q)=>setTimeout(()=>Q(!1),$))]))throw Error(`codex app-server did not exit after SIGKILL (${$}ms)`)}}function M9($,Z){return new Promise((J,Q)=>{let Y=setTimeout(()=>Q(Error(`timeout after ${Z}ms`)),Z);$.then((H)=>{clearTimeout(Y),J(H)},(H)=>{clearTimeout(Y),Q(H)})})}function OK($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function R9($){if(!$)return null;return{percent:OK($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function TK($){let Z=R9($?.primary),J=R9($?.secondary),Q=(H)=>H?.durationMins!=null&&H.durationMins>0&&H.durationMins<=720,Y=(H)=>H?.durationMins!=null&&H.durationMins>720;if(Q(Z)&&Y(J))return{fiveHour:Z,weekly:J};if(Q(J)&&Y(Z))return{fiveHour:J,weekly:Z};if(Y(Z)&&!J)return{fiveHour:null,weekly:Z};if(Y(J)&&!Z)return{fiveHour:null,weekly:J};return{fiveHour:Z,weekly:J}}function EK($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Q=[];for(let[Y,H]of J){let{fiveHour:X,weekly:V}=TK(H);if(!X&&!V)continue;Q.push({limitId:Y,limitName:H?.limitName??null,fiveHour:X,weekly:V})}return{buckets:Q,defaultLimitId:$?.rateLimits?.limitId??void 0}}function NK($){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 rJ($){let Z=NK($),J=H1?.state==="ok"?H1.buckets??[]:[],Q=J.filter((Y)=>aJ(Y.fiveHour,R9($?.primary))&&aJ(Y.weekly,R9($?.secondary)));if(J.length>0&&Q.length===0)z(`usage: rate-limit notification matches NO known bucket — possible relabel or new bucket, will resolve on next read. (${Z})`);else if($?.limitId&&Q.length===1&&Q[0].limitId!==$.limitId)z(`usage: rate-limit notification labeled limitId=${$.limitId} but content matches bucket ${Q[0].limitId} (known codex parser fallback relabels; ignoring notification payload)`)}function aJ($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function kK(){let $=new O9;try{await M9($.request("initialize",{clientInfo:{name:"lodestar-usage",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}),m2);let J=(await M9($.request("account/read",{}),m2))?.account;if(!J)return{state:"no_credentials"};if(J.type!=="chatgpt")return{state:"auth_failed"};let Q=await M9($.request("account/rateLimits/read",{}),m2);return tJ(Q,J.planType)}catch(Z){return z(`usage: codex app-server usage failed: ${Z?.message??Z}`),{state:"network",reason:Z?.message??String(Z)}}finally{await $.close()}}function tJ($,Z){let{buckets:J,defaultLimitId:Q}=EK($),Y=J.find((H)=>H.limitId===Q)??J[0];if(!Y)return{state:"network",reason:"empty rate limit response"};return{state:"ok",subscriptionType:Z??Y.limitName??$?.rateLimits?.planType??"chatgpt",fiveHour:Y.fiveHour,weekly:Y.weekly,buckets:J,defaultLimitId:Y.limitId,fetchedAt:Date.now()}}function sJ(){return H1}async function T9(){if(n1)return n1;return n1=kK().then(($)=>{if(n1=null,$.state==="network")return H1??$;return H1=$,$}).catch(($)=>{return z(`usage: fetchUsage threw: ${$}`),n1=null,H1??{state:"network",reason:String($)}}),n1}function eJ($){return f7??=M9($("account/rateLimits/read",{}),m2).then((Z)=>{let J=tJ(Z);if(J.state==="ok")H1=J;else z(`usage: refresh from connection: ${J.state==="network"?J.reason:J.state}`);return J}).catch((Z)=>{return z(`usage: refresh from connection failed: ${Z?.message??Z}`),null}).finally(()=>{f7=null}),f7}var m2=1e4,H1=null,n1=null,f7=null;var E9=k(()=>{E1();w()});import{readFileSync as xK}from"node:fs";import{homedir as yK}from"node:os";import{join as QQ}from"node:path";function CK(){return process.env.CLAUDE_CONFIG_DIR||QQ(yK(),".claude")}function h7(){try{let $=xK(QQ(CK(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return z(`glm-usage: read settings.json env failed: ${$}`),{}}}function N9($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function SK($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function bK($){let Z=SK($);return Z&&N9($)?Z:null}function ZQ($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function JQ($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function wK($){let Z=Array.isArray($?.limits)?$.limits:[],J=Z.filter((K)=>K?.type==="TOKENS_LIMIT"),Q=J.find((K)=>K?.unit===3&&K?.number===5),Y=J.find((K)=>K?.unit===6&&K?.number===1),H=Z.find((K)=>K?.type==="TIME_LIMIT"),X=(K)=>K?{percent:ZQ(K.percentage),resetsAt:JQ(K.nextResetTime)}:null,V=X(Q),W=X(Y),G=H?{percent:ZQ(H.percentage),resetsAt:JQ(H.nextResetTime),...typeof H.currentValue==="number"?{used:H.currentValue}:{},...typeof H.usage==="number"?{total:H.usage}:{}}:null;return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:V,weekly:W,monthly:G,fetchedAt:Date.now()}}async function I7($,Z){let J=$&&Z?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:h7(),Q=J.ANTHROPIC_AUTH_TOKEN,Y=J.ANTHROPIC_BASE_URL||"";if(!Q)return{state:"no_credentials"};let H=bK(Y);if(!H)return{state:"not_glm",baseUrl:Y||void 0};let X=`${H}/api/monitor/usage/quota/limit`,V=new AbortController,W=setTimeout(()=>V.abort(),$Q);try{let G=await fetch(X,{headers:{Authorization:Q,"Content-Type":"application/json","Accept-Language":"en-US,en"},signal:V.signal});if(G.status===429)return{state:"rate_limited"};if(!G.ok)return{state:"network",reason:`HTTP ${G.status}`};let K=await G.json();if(K?.success===!1||typeof K?.code==="number"&&K.code!==200)return{state:"network",reason:K?.msg?String(K.msg):`code ${K?.code}`};let _=K?.data??K;return wK(_)}catch(G){let K=G?.name==="AbortError"?`timeout ${$Q}ms`:G?.message??String(G);return z(`glm-usage: quota/limit fetch failed: ${K}`),{state:"network",reason:K}}finally{clearTimeout(W)}}async function g7(){if(o1)return o1;return o1=I7().then(($)=>{if(o1=null,$.state==="network")return v7??$;return v7=$,$}).catch(($)=>{return z(`glm-usage: fetchGlmUsage threw: ${$}`),o1=null,v7??{state:"network",reason:String($)}}),o1}var $Q=1e4,v7=null,o1=null;var k9=k(()=>{w()});function YQ($){let Z=[];for(let J of $.matchAll(fK)){let Q=J[1]?.trim();if(Q)Z.push(Q)}return Z}function x9($,Z=process.platform){if(Z!=="win32")return $;let J=vK.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var fK,vK;var c7=k(()=>{fK=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;vK=/^\/([a-zA-Z])\//});function VQ($){if(HQ.test($))return{marker:"start",body:$.replace(HQ,"")};if(XQ.test($))return{marker:"end",body:$.replace(XQ,"")};return{marker:"none",body:$}}var HQ,XQ;var WQ=k(()=>{HQ=/^>{3,}[ \t]?/,XQ=/^<{3,}[ \t]?/});async function GQ($,Z,J,Q,Y){let{marker:H,body:X}=VQ(Z);if(H==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)u7($,"reopen");return $.multiMsgBuffer=[],m7($,X,J,Q,Y),!0}if(H==="end"){if($.multiMsgBuffer===null){if(X.trim()||J.length)return!1;return z(`session "${$.sessionName}": end marker without active multi-msg buffer, ignoring`),!0}m7($,X,J,Q,Y);let{multiMsgBuffer:V,multiMsgReactions:W}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await IK($,V,W),!0}if($.multiMsgBuffer!==null)return m7($,Z,J,Q,Y),!0;return!1}function m7($,Z,J,Q,Y){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Q,msgId:Y});if(Y)hK($,Y)}function hK($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await R$(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else A$(Z,J)})()}async function IK($,Z,J){for(let[X,V]of J)if(V)A$(X,V);let Q=Z.filter((X)=>X.text.trim()||X.files.length);if(Q.length===0){z(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await O($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Y=Q.map((X)=>{return(X.files.length?X.files.map((W)=>`[file: ${W}]`).join(" ")+`
160
+ `:"")+X.text}).join(`
161
+
162
+ `),H=Q[Q.length-1];z(`session "${$.sessionName}": multi-msg flush ${Q.length} segment(s) → 1 turn`),await $.onUserMessage(Y,[],H.userOpenId,H.msgId)}function u7($,Z){if($.multiMsgBuffer===null)return;let J=$.multiMsgBuffer.length;z(`session "${$.sessionName}": clear multi-msg buffer (${Z}): ${J} segment(s)`);for(let[Q,Y]of $.multiMsgReactions){if(Y)A$(Q,Y);R$(Q,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var zQ=k(()=>{n();w();WQ()});import{mkdtemp as cK,rm as mK,writeFile as uK}from"node:fs/promises";import{createRequire as pK}from"node:module";import{tmpdir as lK}from"node:os";import{join as KQ}from"node:path";function sK($){let Z=jQ.get($);if(Z)return Z;let{liteAdaptor:J}=V1("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Q}=V1("mathjax-full/js/handlers/html.js"),{mathjax:Y}=V1("mathjax-full/js/mathjax.js"),{TeX:H}=V1("mathjax-full/js/input/tex.js"),{AllPackages:X}=V1("mathjax-full/js/input/tex/AllPackages.js"),{SVG:V}=V1("mathjax-full/js/output/svg.js"),W=J({fontSize:$});Q(W);let G=Y.document("",{InputJax:new H({packages:X}),OutputJax:new V({fontCache:"none"})}),K={adaptor:W,doc:G};return jQ.set($,K),K}function LQ($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function eK($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function $_($,Z=d7,J=!0){try{let Q=Z*dK,{adaptor:Y,doc:H}=sK(Z),X=H.convert($,{display:J,em:Z,ex:Q,containerWidth:80*Z}),V=Y.outerHTML(X);if(/data-mjx-error=|mjx-merror/.test(V)){let n$=V.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(n$)}let W=V.indexOf("<svg"),G=V.lastIndexOf("</svg>");if(W<0||G<0)throw Error("MathJax returned no SVG");let K=V.slice(W,G+6),_=K.match(/^<svg\b[^>]*>/)?.[0];if(!_)throw Error("MathJax returned malformed SVG root");let B=LQ(_.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),j=LQ(_.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),L=_.match(/\bviewBox="([^"]+)"/)?.[1];if(!L)throw Error("MathJax SVG missing viewBox");let A=L.trim().split(/[\s,]+/).map(Number);if(A.length!==4||A.some((n$)=>!Number.isFinite(n$))||A[2]<=0||A[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[P,R,D,F]=A,N=/<text\b/.test(K)?rK:0,C=`${P} ${R} ${D+N} ${F}`,x=B*Q,m=N*(x/D),I=Math.max(1,Math.ceil(x+m)),f=Math.max(1,Math.ceil(j*Q)),T=iK-p7*2,E=Math.min(1,T/I),u=Math.max(1,Math.round(I*E)),p=Math.max(1,Math.round(f*E));if(E<1&&p<nK)throw Error(`formula would be unreadable after width cap (${u}x${p})`);let $$=u+p7*2,o=p+qQ*2,P0=K.slice(_.length,-6).replace(/currentColor/g,_Q).replace(/font-family="serif"/g,`font-family="${tK}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${$$}" height="${o}" viewBox="0 0 ${$$} ${o}" style="color:${_Q}">`,`<rect x="0" y="0" width="${$$}" height="${o}" rx="6" fill="${PQ}"/>`,`<svg x="${p7}" y="${qQ}" width="${u}" height="${p}" viewBox="${eK(C)}" preserveAspectRatio="xMidYMid meet">`,P0,"</svg>","</svg>"].join(""),width:$$,height:o}}catch(Q){return z(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Q}`),null}}function Z_($,Z=d7,J=!0){let Q=$_($,Z,J);if(!Q)return null;try{let{Resvg:Y}=V1("@resvg/resvg-js"),X=new Y(Q.svg,{background:PQ,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:BQ,sansSerifFamily:BQ}}).render().asPng(),V=new DataView(X.buffer,X.byteOffset,X.byteLength),W=V.getUint32(16),G=V.getUint32(20);if(W!==Q.width||G!==Q.height)throw Error(`PNG dimensions ${W}x${G} != SVG ${Q.width}x${Q.height}`);return{png:X,width:W,height:G}}catch(Y){return z(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Y}`),null}}function J_($){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 DQ($,Z){let J=[],Q=(K,_,B)=>{let j=K[0],L=_.trim();if(!L)return;J.push({start:Z+K.index,end:Z+K.index+j.length,tex:L,raw:j,display:B})},Y,H=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Y=H.exec($))!==null)Q(Y,Y[1]??Y[2]??"",!0);let X=/\\\(([\s\S]+?)\\\)/g;while((Y=X.exec($))!==null)Q(Y,Y[1]??"",!1);let V=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Y=V.exec($))!==null){let K=(Y[1]??"").trim();if(J_(K))Q(Y,K,!1)}J.sort((K,_)=>K.start-_.start||_.end-K.end);let W=[],G=-1;for(let K of J){if(K.start<G)continue;W.push(K),G=K.end}return W}function UQ($){let Z=w8($),J=[],Q=0;for(let Y of Z){if(Q<Y.start)J.push(...DQ($.slice(Q,Y.start),Q));Q=Math.max(Q,Y.end)}if(Q<$.length)J.push(...DQ($.slice(Q),Q));return J}function Q_($){let Z=$;if(Z=Z.replace(/\\text\{([^{}]*)\}/g,"$1"),Z=Z.replace(/\\left\s*/g,"").replace(/\\right\s*/g,""),Z=Z.replace(/\\([A-Za-z]+)\b/g,(J,Q)=>{if(AQ[Q])return AQ[Q];if(Q==="times")return"×";if(Q==="cdot")return"·";if(Q==="div")return"÷";if(Q==="pm")return"±";if(Q==="leq"||Q==="le")return"≤";if(Q==="geq"||Q==="ge")return"≥";if(Q==="neq"||Q==="ne")return"≠";if(Q==="approx")return"≈";if(Q==="sim")return"~";if(Q==="infty")return"∞";if(Q==="partial")return"∂";if(Q==="nabla")return"∇";if(Q==="sqrt")return"√";if(Q==="to")return"→";return J}),/\\/.test(Z))return null;if(Z=Z.replace(/([_^])\{([^{}]+)\}/g,(J,Q,Y)=>Y.length===1?`${Q}${Y}`:`${Q}(${Y})`),Z=Z.replace(/√\{([^{}]+)\}/g,"√($1)"),/[{}]/.test(Z))return null;return Z}function V_($){let Z=FQ.get($);if(Z!==void 0)return Z;return Z=H_++,FQ.set($,Z),Z}function W_($,Z){return`${aK}\x00${V_(Z)}\x00${$}`}function G_($){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 z_($,Z){let J=W_($,Z),Q=X1.get(J);if(Q)return Q;let Y=l7.get(J);if(Y)return Y;let H=(async()=>{let X=Z_($,d7,!0);if(!X)return null;let V=null;try{V=await cK(KQ(lK(),"lodestar-math-"));let W=KQ(V,`formula-${G_($)}.png`);await uK(W,X.png);let G=await Z(W,{tex:$,width:X.width,height:X.height});if(!G)return z(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let K={key:G,width:X.width,height:X.height};if(X1.has(J))X1.delete(J);X1.set(J,K);while(X1.size>X_){let _=X1.keys().next().value;if(typeof _!=="string")break;X1.delete(_)}return K}catch(W){return z(`math-render: upload failed for ${$.slice(0,80)}…: ${W}`),null}finally{if(V)try{await mK(V,{recursive:!0,force:!0})}catch(W){z(`math-render: temp cleanup failed for ${V}: ${W}`)}}})();l7.set(J,H);try{return await H}finally{l7.delete(J)}}function K_($,Z,J){let Q=$.width<=oK;return{type:"image",tex:Z.tex,index:J,element:{tag:"img",img_key:$.key,alt:{tag:"plain_text",content:Z.tex.replace(/\s+/g," ").slice(0,80)},scale_type:Q?"crop_center":"fit_horizontal",...Q?{size:`${$.width}px ${$.height}px`}:{},preview:!1}}}async function MQ($,Z={}){let J=UQ($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Q=Z.uploader??Y_,Y=await Promise.all(J.map(async(K)=>{if(!K.display){let _=Q_(K.tex);if(_!==null)return{unicode:_,uploaded:null}}return{unicode:null,uploaded:await z_(K.tex,Q)}})),H=[],X="",V=0,W=0,G=()=>{if(!X)return;if(X.trim())H.push({type:"markdown",text:X});X=""};for(let K=0;K<J.length;K++){let _=J[K],B=Y[K];if(X+=$.slice(V,_.start),B.unicode!==null){X+=B.unicode,V=_.end;continue}let j=B.uploaded;if(!j){X+=_.raw,V=_.end;continue}G(),H.push(K_(j,_,W++)),V=_.end}if(X+=$.slice(V),G(),!H.length)H.push({type:"markdown",text:$});return{blocks:H,formulaCount:J.length,renderedImageCount:W}}function i7($){return UQ($).length>0}var V1,dK=0.5,d7=22,_Q="#1F2329",PQ="#F7F8FA",p7=12,qQ=8,iK=720,nK=14,oK=278,aK="v4-native-cjk-tail-pad",rK=1100,BQ,tK="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",jQ,AQ,Y_=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (n(),e));return Z($)},FQ,H_=1,X1,l7,X_=512;var RQ=k(()=>{w();V1=pK(import.meta.url),BQ=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",jQ=new Map;AQ={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:"Ω"};FQ=new WeakMap,X1=new Map,l7=new Map});import{isAbsolute as q_}from"node:path";function B$($){if($?.planLiveInserted)return M.planLive;return $?.taskLiveInserted?M.taskBoardLive:M.footer}function B_($){return $==="ImageGeneration"||$==="imageGeneration"}function j_($,Z,J){if(J||!B_($))return null;let Q=x9(Z.trim());return q_(Q)?Q:null}function L_($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function OQ($,Z,J){return $==="read"?u1(Z,J):m1(Z,J)}function TQ($,Z,J,Q){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Y=L_(J);if(Y&&$.currentTurn.openBatchI!==null){let W=$.currentTurn.openBatchI,G=$.currentTurn.toolBatches.get(W);if(G&&G.kind===Y){let K=G.items.length;G.items.push({toolUseId:Z,input:Q,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:W,name:J,input:Q,batchSlot:K});let _=Y==="read"?u1(W,G.items):m1(W,G.items);i($.currentTurn.cardId,M.tool(W),_),y9($.currentTurn,J,Q);return}}if(!Y)$.currentTurn.openBatchI=null;let H=Q1(J);if(H){let W=$.currentTurn;if(H==="TaskCreate"&&!W.taskBoardResetThisTurn)$.taskBoard=[],W.taskBoardResetThisTurn=!0;if(!W.taskLiveInserted)W.taskLiveInserted=!0,W$(W.cardId,Y1($.taskBoard),{type:"insert_before",targetElementId:M.footer});else i(W.cardId,M.taskBoardLive,Y1($.taskBoard));let G=H==="TaskCreate";if(G)W.taskUpdateI=null;else W.taskCreateI=null;let K=(G?W.taskCreateI:W.taskUpdateI)===null;if(K)if(G)W.taskCreateI=W.toolCount++;else W.taskUpdateI=W.toolCount++;let _=G?W.taskCreateI:W.taskUpdateI;W.toolByUseId.set(Z,{i:_,name:J,input:Q});let B=y0(_,$.taskBoard,{name:H,status:"⏳"});K?W$(W.cardId,B,{type:"insert_before",targetElementId:B$(W)}):i(W.cardId,M.tool(_),B),y9(W,J,Q);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let X=$.currentTurn.toolCount++;if(Y){$.currentTurn.openBatchI=X;let W=[{toolUseId:Z,input:Q,output:null,isError:!1}];$.currentTurn.toolBatches.set(X,{kind:Y,items:W}),$.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q,batchSlot:0});let G=Y==="read"?u1(X,W):m1(X,W);W$($.currentTurn.cardId,G,{type:"insert_before",targetElementId:B$($.currentTurn)}),y9($.currentTurn,J,Q);return}if($.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q}),J==="AskUserQuestion"){let W=Array.isArray(Q?.questions)?Q.questions:[],G=W.length>0?0:void 0,K=new Map;$.pendingAsks.set(Z,{questions:W,i:X,answers:{},answered:K,currentIdx:G});let _=w2(X,Z,W,"\uD83E\uDD14",{currentIdx:G,answered:K});if(W$($.currentTurn.cardId,_,{type:"insert_before",targetElementId:B$($.currentTurn)}),$.currentTurn.userOpenId&&$.currentTurn.messageId){let B=$.currentTurn,j=W[0]?.question?.trim()??"",L=j.length>40?j.slice(0,40)+"…":j,A=W.length>1?`❓ 待回答 ${W.length} 题${L?`: ${L}`:""}`:L?`❓ ${L}`:"❓ 等你回答问题";(async()=>{V$(B.cardId),await g4(B.cardId,{config:{summary:{content:A}}}),await a0(B.messageId,[B.userOpenId])})()}return}let V=q0(X,J,Q,null,"⏳");W$($.currentTurn.cardId,V,{type:"insert_before",targetElementId:B$($.currentTurn)}),y9($.currentTurn,J,Q)}function y9($,Z,J){if(!$)return;let Q=_0(Z,J),Y=Q.length>80?Q.slice(0,80)+"…":Q,H=s0(Z),X=Y?`\uD83D\uDD27 ${H}: ${Y}`:`\uD83D\uDD27 ${H}`;z0($.cardId,X)}function EQ($,Z,J,Q){if(!$.currentTurn)return;let Y=$.currentTurn.toolByUseId.get(Z);if(!Y)return;let H=typeof J==="string"?J:Array.isArray(J)?J.map((G)=>G?.text??JSON.stringify(G)).join(`
163
+ `):JSON.stringify(J);Y.output=H,Y.isError=Q;let X=j_(Y.name,H,Q);if(X)$.sendOutboundPath(X,Y.name);if(Y.name==="AskUserQuestion"){C9($);return}if(Y.batchSlot!=null){let G=$.currentTurn.toolBatches.get(Y.i);if(G){let K=G.items[Y.batchSlot];if(K)K.output=H,K.isError=Q;let _=OQ(G.kind,Y.i,G.items);i($.currentTurn.cardId,M.tool(Y.i),_)}C9($);return}let V=Q1(Y.name);if(V){D_($,Y,V,Y.input,H,Q,Y.resolvedNote);return}let W=q0(Y.i,Y.name,Y.input,H,Q?"❌":"✅",Y.resolvedNote);i($.currentTurn.cardId,M.tool(Y.i),W),C9($)}function D_($,Z,J,Q,Y,H,X){if(!$.currentTurn)return;if(!H)$.taskBoard=b7($.taskBoard,J,Q,Y);let V=y0(Z.i,$.taskBoard,{name:J,status:H?"❌":"✅"},X);if(i($.currentTurn.cardId,M.tool(Z.i),V),$.currentTurn.taskLiveInserted)i($.currentTurn.cardId,M.taskBoardLive,Y1($.taskBoard));C9($)}function C9($){let Z=$.currentTurn;if(!Z)return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function n7($,Z,J,Q,Y){let H=$.currentTurn;if(!H)return;for(let[X,V]of Q){if(H.toolByUseId.has(X))continue;let W=V.batchSlot??null,G=V.input,K,_;if(W!=null){let R=Y.get(V.i)?.items[W];if(!R)continue;G=R.input,K=R.output,_=R.isError}else K=V.output??null,_=V.isError??!1;let B=K!=null,j=I1(Z,M.tool(V.i));if(B&&!j)continue;if(W!=null){let R=Y.get(V.i)?.kind;if(!R)continue;let D=H.toolCount++,F={toolUseId:X,input:G,output:K,isError:_};H.toolBatches.set(D,{kind:R,items:[F]}),H.toolByUseId.set(X,{...V,i:D,batchSlot:0}),W$(J,OQ(R,D,[F]),{type:"insert_before",targetElementId:B$(H)});continue}let L=Q1(V.name);if(L){let R=L==="TaskCreate";if(R)H.taskUpdateI=null;else H.taskCreateI=null;let D=(R?H.taskCreateI:H.taskUpdateI)===null;if(D)if(R)H.taskCreateI=H.toolCount++;else H.taskUpdateI=H.toolCount++;let F=R?H.taskCreateI:H.taskUpdateI;H.toolByUseId.set(X,{...V,i:F});let N=!B?"⏳":_?"❌":"✅",C=y0(F,$.taskBoard,{name:L,status:N},V.resolvedNote);D?W$(J,C,{type:"insert_before",targetElementId:B$(H)}):i(J,M.tool(F),C);continue}let A=H.toolCount++;H.toolByUseId.set(X,{...V,i:A});let P=!B?"⏳":_?"❌":"✅";W$(J,q0(A,V.name,V.input,K,P,V.resolvedNote),{type:"insert_before",targetElementId:B$(H)})}}var NQ=k(()=>{c7();t0();w$();n()});function kQ($){return $.pendingAsks.size>0}async function xQ($,Z,J,Q){let Y=$.pendingAsks.entries().next();if(Y.done){z(`session "${$.sessionName}": onAskMessageAnswer with no pending — falling back to onUserMessage`),await $.onUserMessage(Z,[],J,Q);return}let[H,X]=Y.value;if(X.currentIdx===void 0){if(X.requestId){z(`session "${$.sessionName}": pending ask ${H} awaiting finalize — ignoring message`);return}z(`session "${$.sessionName}": pending ask ${H} orphaned (no can_use_tool) — dropping zombie, reprocessing as user message`),$.pendingAsks.delete(H),await $.onUserMessage(Z,[],J,Q);return}if(await o7($,H,X.currentIdx,Z,J)&&Q)R$(Q,"CheckMark")}async function yQ($,Z,J,Q,Y){let H=$.pendingAsks.get(Z);if(!H)return z(`session "${$.sessionName}": stray ask answer for ${Z}`),!1;if(J!==H.currentIdx)return z(`session "${$.sessionName}": stale ask click q=${J} current=${H.currentIdx}`),!1;return CQ($,Z,{optionIdx:Q,user:Y})}async function o7($,Z,J,Q,Y){let H=$.pendingAsks.get(Z);if(!H)return z(`session "${$.sessionName}": stray ask custom for ${Z}`),!1;let X=(Q??"").trim();if(!X)return z(`session "${$.sessionName}": empty custom answer, ignoring`),!1;if(J!==H.currentIdx)return z(`session "${$.sessionName}": stale ask custom q=${J} current=${H.currentIdx}`),!1;return CQ($,Z,{customText:X,user:Y})}function CQ($,Z,J){let Q=$.pendingAsks.get(Z);if(!Q||Q.currentIdx===void 0)return!1;let Y=Q.currentIdx,H=Q.questions[Y];if(!H)return z(`session "${$.sessionName}": advanceAsk currentIdx=${Y} out of range`),!1;let X;if(J.customText!==void 0)X=J.customText;else if(J.optionIdx!==void 0){let _=H.options?.[J.optionIdx];if(!_)return z(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;X=_.label}else return z(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Q.answers[H.question]=X,Q.answered.set(Y,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let V=Q.questions.length,W=void 0;for(let _=Y+1;_<V;_++)if(!Q.answered.has(_)){W=_;break}Q.currentIdx=W;let G=$.currentTurn,K=G?.toolByUseId.get(Z);if(G&&K){let _=w2(K.i,Z,Q.questions,W===void 0?"✅":"\uD83E\uDD14",{currentIdx:W,answered:Q.answered});i(G.cardId,M.tool(K.i),_)}if(W===void 0)if(Q.requestId)a7($,Z);else z(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`);return!0}function a7($,Z){let J=$.pendingAsks.get(Z);if(!J||!J.requestId)return;let Q=$.currentTurn?.toolByUseId.get(Z),Y=Q?.input??{};if($.proc?.sendPermissionResponse(J.requestId,"allow",{updatedInput:{...Y,answers:J.answers}}),$.pendingPermissions.delete(J.requestId),Q)Q.output=JSON.stringify({answers:J.answers}),Q.isError=!1;if($.pendingAsks.delete(Z),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var r7=k(()=>{t0();w$();n();w()});async function SQ($,Z,J,Q){let Y=$.pendingPermissions.get(Z);if(!Y)return z(`session "${$.sessionName}": stray permission ${Z}`),{ok:!1,message:"此权限请求已失效或已处理"};let H=$.proc;if(!H)return z(`session "${$.sessionName}": permission ${Z} has no active process`),{ok:!1,message:"后端进程已退出,权限决定未送达"};let X=J==="deny"?"deny":"allow";try{H.sendPermissionResponse(Z,X,J==="allow_always"?{updatedPermissions:Y.permissionSuggestions}:void 0)}catch(G){return z(`session "${$.sessionName}": permission response ${Z} failed: ${G}`),{ok:!1,message:`权限决定发送失败: ${G instanceof Error?G.message:G}`}}$.pendingPermissions.delete(Z);let V=$.currentTurn,W=V?.toolByUseId.get(Y.toolUseId);if(V&&W){let G=Q1(W.name);if(J==="deny"){let K=`\uD83D\uDEAB 已拒绝 by ${Q||"匿名"}`,_=G?y0(W.i,$.taskBoard,{name:G,status:"❌"},K):q0(W.i,W.name,W.input,K,"❌");i(V.cardId,M.tool(W.i),_)}else{let K=J==="allow_always"?"始终允许":"已允许";W.resolvedNote=`✅ **${K}** by ${Q||"匿名"}`;let _=G?y0(W.i,$.taskBoard,{name:G,status:"⏳"},W.resolvedNote):q0(W.i,W.name,W.input,null,"⏳",W.resolvedNote);i(V.cardId,M.tool(W.i),_)}}if(z(`session "${$.sessionName}": permission decision request=${Z} tool_use_id=${Y.toolUseId} decision=${J}`),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working";return{ok:!0,message:J==="deny"?"已拒绝":J==="allow_always"?"已始终允许":"已允许"}}function bQ($,Z){let J=$.currentTurn;if(!J){z(`session "${$.sessionName}": can_use_tool with no current turn — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no active turn"});return}let Q=Z.tool_use_id;if(!Q){z(`session "${$.sessionName}": can_use_tool without tool_use_id — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no tool_use_id"});return}let Y=J.toolByUseId.get(Q);if(!Y){z(`session "${$.sessionName}": can_use_tool for unknown tool_use_id=${Q} — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"unknown tool_use_id"});return}if(Y.name==="AskUserQuestion"){let X=$.pendingAsks.get(Q);if(!X){z(`session "${$.sessionName}": AskUserQuestion ${Q} missing pendingAsk — deny`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no pending ask"});return}if(X.requestId=Z.request_id,$.pendingPermissions.set(Z.request_id,{toolUseId:Q}),X.currentIdx===void 0)a7($,Q);return}$.status="awaiting_permission",$.pendingPermissions.set(Z.request_id,{toolUseId:Q,permissionSuggestions:Z.permission_suggestions}),z(`session "${$.sessionName}": can_use_tool request=${Z.request_id} tool_use_id=${Q} tool=${Y.name}`);let H=J9(Y.i,Y.name,Y.input,Z.request_id);if(i(J.cardId,M.tool(Y.i),H),J.userOpenId&&J.messageId){let X=_0(Y.name,Y.input),V=s0(Y.name),W=X&&X.length>30?X.slice(0,30)+"…":X,G=W?`\uD83D\uDD10 等审批: ${V} · ${W}`:`\uD83D\uDD10 等审批: ${V}`;(async()=>{V$(J.cardId),await g4(J.cardId,{config:{summary:{content:G}}}),await a0(J.messageId,[J.userOpenId])})()}}var wQ=k(()=>{t0();w$();n();w();r7()});function fQ($,Z=hQ){return new Promise((J,Q)=>{let Y=setTimeout(()=>Q(Error(`timeout ${Z}ms`)),Z);$.then((H)=>{clearTimeout(Y),J(H)},(H)=>{clearTimeout(Y),Q(H)})})}function vQ($){return typeof $==="string"&&U_.includes($)?$:null}async function IQ(){let $=new O9;try{await fQ($.request("initialize",{clientInfo:{name:"lodestar-models",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}));let Z=await fQ($.request("model/list",{})),J=Array.isArray(Z?.data)?Z.data:[],Q=[];for(let Y of J){if(!Y||Y.hidden||!Y.id)continue;let H=(Array.isArray(Y.supportedReasoningEfforts)?Y.supportedReasoningEfforts:[]).map((V)=>vQ(V?.reasoningEffort)).filter((V)=>V!==null);if(!H.length)continue;let X=vQ(Y.defaultReasoningEffort)??H[0];Q.push({model:String(Y.id),display:typeof Y.displayName==="string"&&Y.displayName?String(Y.displayName):String(Y.id),efforts:H,defaultEffort:X})}return Q}finally{await $.close()}}async function gQ($,Z){let J=new URL($),Q=J.pathname.replace(/\/+$/,""),Y=`${J.protocol}//${J.host}${Q}/v1/models`,H=await fetch(Y,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(hQ)});if(!H.ok)throw Error(`HTTP ${H.status}`);let X=await H.json();return(Array.isArray(X?.data)?X.data:[]).filter((W)=>W&&(W.display_name||W.id)).map((W)=>{let G=String(W.display_name||W.id);return{model:G,display:G,efforts:d$,defaultEffort:"max"}})}var hQ=1e4,U_,d$;var u2=k(()=>{E9();U_=["none","minimal","low","medium","high","xhigh","max","ultra"];d$=["max","xhigh","high","medium","low"]});import{existsSync as M_}from"node:fs";import{homedir as R_}from"node:os";import{join as cQ}from"node:path";function S9($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function O_($){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(S9($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(S9($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt}}function T_($){if($.state!=="ok"||!$.buckets?.length)return null;let Z=[];for(let J of $.buckets){let Q=J.limitId===$.defaultLimitId?J.limitName??"默认配额":J.limitName??J.limitId;if(J.fiveHour)Z.push(S9(J.fiveHour,"fiveHour",`${Q} 5h`));if(J.weekly)Z.push(S9(J.weekly,"weekly",`${Q} 周`))}return Z.length?Z:null}function E_(){let $=process.env.CODEX_HOME||cQ(R_(),".codex");return M_(cQ($,"auth.json"))}var mQ=k(()=>{N$();P$();E9();u2();w();X0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=E_(),J=$.model?.trim()||void 0,Q=$.effort?.trim()||void 0,Y={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(!Y.enabled){Y.models=[],Y.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}Y.modelCatalogState={status:"loading",updatedAt:null};try{if(Y.models=await IQ(),Q)for(let H of Y.models)H.defaultEffort=Q;if(!J)Y.defaultModel=Y.models[0]?.model??"";Y.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){z(`codex-sub refreshModels MISS: ${H?.message??H}`),Y.models=[],Y.modelCatalogState={status:"failed",updatedAt:Date.now(),error:H?.message??String(H)}}},spawnEnv(H){let X=m0(H);return Object.assign(X,b.codex.env),X},resolveSpawnModel(H){return H},async readUsage(){let H=await T9(),X=O_(H),V=T_(H);if(V)X.windows=V;return X}};return Y}})});function k_($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function b9($,Z,J){try{let Q=await fetch(k_($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(N_)});if(Q.ok)return"exists";if(Q.status===400){let Y=await Q.text();return Y.includes("1214")||Y.includes("不存在")||Y.includes("not exist")?"not_found":"no_verdict"}return z(`model-existence: ${J} HTTP ${Q.status}, no verdict`),"no_verdict"}catch(Q){return z(`model-existence: ${J} MISS (${Q?.message??Q})`),"no_verdict"}}var N_=15000;var t7=k(()=>{w()});function uQ($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function x_($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function y_($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function C_($){let Z=(J)=>{let Q=J.match(/(\d+(?:\.\d+)?)/);return Q?Number(Q[1]):-1};return[...$].sort((J,Q)=>Z(Q)-Z(J))[0]??""}function S_($){let Z={};for(let J of($??"").split(",")){let Q=J.indexOf("=");if(Q<=0)continue;let Y=J.slice(0,Q).trim().toLowerCase(),H=J.slice(Q+1).trim();if((Y==="opus"||Y==="sonnet"||Y==="haiku")&&H)Z[Y]=H}return Z}function b_($){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(uQ($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(uQ($.weekly,"weekly","周额度"));if($.monthly)Z.push(x_($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var pQ=k(()=>{P$();k9();u2();U4();t7();w();X0({kind:"glm-coding-plan",configSectionId:"glm",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||"",Q=$.auth_token?.trim()||Z?.auth_token?.trim()||"",Y=!!(J&&Q)&&N9(J),H=$.model?.trim()||void 0,X=S_($.slots),V={id:"glm",kind:"glm-coding-plan",agent:"claude",display:$.display?.trim()||"GLM Coding Plan",enabled:Y,models:[],modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},defaultModel:H??"",async refreshModels(){if(!V.enabled){V.models=[],V.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}V.modelCatalogState={status:"loading",updatedAt:null};try{let W=await gQ(J,Q),K=y_($.models).filter((_)=>!W.some((B)=>B.model.toLowerCase()===_.toLowerCase())).map((_)=>({model:_,display:_,efforts:d$,defaultEffort:"max"}));if(V.models=[...W,...K],!H)V.defaultModel=C_(V.models.map((_)=>_.model));for(let _ of V.models){let B=P4("glm",_.model);_.context1m=B!=null&&B>=1e6||void 0}V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(W){z(`glm refreshModels MISS: ${W?.message??W}`),V.models=[],V.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W?.message??String(W)}}},spawnEnv(W){let K={...m0(W)};if(K.ANTHROPIC_BASE_URL=J,K.ANTHROPIC_AUTH_TOKEN=Q,X.opus)K.ANTHROPIC_DEFAULT_OPUS_MODEL=X.opus;if(X.sonnet)K.ANTHROPIC_DEFAULT_SONNET_MODEL=X.sonnet;if(X.haiku)K.ANTHROPIC_DEFAULT_HAIKU_MODEL=X.haiku;return K},resolveSpawnModel(W){return F4("glm",W)},async verifyModel(W){return b9(J,{Authorization:`Bearer ${Q}`},W)},async readUsage(){return b_(await I7(J,Q))}};return V},setup:{commandSuffix:"glm",hint:($)=>`启用 ${$}:发送
162
164
  \`\`\`
163
165
  glm-setup <base_url> <token>
164
- \`\`\``,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(!k9(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var mQ;var uQ=E(()=>{A$();u2();mQ=[{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"}];V0({kind:"claude-native",build:($)=>{let Z={id:"claude-native",kind:"claude-native",agent:"claude",display:"Claude",enabled:!1,models:mQ,modelCatalogState:{status:"ready",updatedAt:Date.now()},defaultModel:"opus",settingSources:["user","project","local"],async refreshModels(){Z.models=mQ,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 x_($){let Z=(J)=>{let Q=J.match(/(\d+(?:\.\d+)?)/);return Q?Number(Q[1]):-1};return[...$].sort((J,Q)=>Z(Q)-Z(J))[0]??""}function N_($){let Z={};for(let J of($??"").split(",")){let Q=J.indexOf("=");if(Q<=0)continue;let Y=J.slice(0,Q).trim().toLowerCase(),H=J.slice(Q+1).trim();if((Y==="opus"||Y==="sonnet"||Y==="haiku")&&H)Z[Y]=H}return Z}function C_($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function b_($,Z){let J=new URL($).origin,Q=await fetch(`${J}/models`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(1e4)});if(!Q.ok)throw Error(`HTTP ${Q.status}`);let Y=await Q.json();return(Array.isArray(Y?.data)?Y.data:[]).filter((V)=>V&&typeof V.id==="string"&&V.id).map((V)=>({model:V.id,display:V.id,efforts:i$,defaultEffort:"high"}))}async function w_($,Z){let J;try{J=new URL($).origin}catch{return{state:"network",windows:[],reason:"bad base_url"}}try{let Q=await fetch(`${J}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(S_)});if(!Q.ok)return{state:"network",windows:[],reason:`HTTP ${Q.status}`};let Y=await Q.json(),V=(Array.isArray(Y?.balance_infos)?Y.balance_infos:[])[0],X=typeof V?.currency==="string"?V.currency:"",W=X==="CNY"?"¥":X==="USD"?"$":X?`${X} `:"",z=V?.total_balance;if(typeof z!=="string"&&typeof z!=="number")return{state:"ok",windows:[],planLabel:"余额 —(无明细)"};let K=Y?.is_available!==!1;return{state:"ok",windows:[],planLabel:K?`剩余 ${W}${z}`:`⚠️ 余额不足 ${W}${z}`}}catch(Q){return G(`deepseek readUsage MISS: ${Q?.message??Q}`),{state:"network",windows:[],reason:Q?.message??String(Q)}}}var y_="https://api.deepseek.com/anthropic",S_=1e4;var pQ=E(()=>{A$();u2();U4();r7();w();V0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||y_,Q=$.api_key?.trim()||Z?.api_key?.trim()||"",Y=!!Q,H=$.model?.trim()||void 0,V=N_($.slots),X={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Y,models:[],modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},defaultModel:H??"",async refreshModels(){if(!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let W=await b_(J,Q),K=E_($.models).filter((_)=>!W.some((j)=>j.model.toLowerCase()===_.toLowerCase())).map((_)=>({model:_,display:_,efforts:i$,defaultEffort:"high"}));if(X.models=[...W,...K],!H)X.defaultModel=x_(X.models.map((_)=>_.model));for(let _ of X.models){let j=A4("deepseek",_.model);_.context1m=j!=null&&j>=1e6||void 0}X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(W){G(`deepseek refreshModels MISS: ${W?.message??W}`),X.models=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W?.message??String(W)}}},spawnEnv(W){let K={...m0(W)};if(K.ANTHROPIC_BASE_URL=J,K.ANTHROPIC_API_KEY=Q,V.opus)K.ANTHROPIC_DEFAULT_OPUS_MODEL=V.opus;if(V.sonnet)K.ANTHROPIC_DEFAULT_SONNET_MODEL=V.sonnet;if(V.haiku)K.ANTHROPIC_DEFAULT_HAIKU_MODEL=V.haiku;return K},resolveSpawnModel(W){return F4("deepseek",W)},async verifyModel(W){return b9(J,{"x-api-key":Q},W)},async readUsage(){if(!Q)return{state:"no_credentials",windows:[]};return w_(J,Q)}};return X},setup:{commandSuffix:"deepseek",hint:($)=>`启用 ${$}:发送
166
+ \`\`\``,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(!N9(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var lQ;var dQ=k(()=>{P$();u2();lQ=[{model:"fable",display:"Fable",efforts:d$,defaultEffort:"max"},{model:"opus",display:"Opus",efforts:d$,defaultEffort:"high"},{model:"sonnet",display:"Sonnet",efforts:d$,defaultEffort:"medium"},{model:"haiku",display:"Haiku",efforts:d$,defaultEffort:"medium"}];X0({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 f_($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function v_($){let Z=(J)=>{let Q=J.match(/(\d+(?:\.\d+)?)/);return Q?Number(Q[1]):-1};return[...$].sort((J,Q)=>Z(Q)-Z(J))[0]??""}function h_($){let Z={};for(let J of($??"").split(",")){let Q=J.indexOf("=");if(Q<=0)continue;let Y=J.slice(0,Q).trim().toLowerCase(),H=J.slice(Q+1).trim();if((Y==="opus"||Y==="sonnet"||Y==="haiku")&&H)Z[Y]=H}return Z}function I_($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function g_($,Z){let J=new URL($).origin,Q=await fetch(`${J}/models`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(1e4)});if(!Q.ok)throw Error(`HTTP ${Q.status}`);let Y=await Q.json();return(Array.isArray(Y?.data)?Y.data:[]).filter((X)=>X&&typeof X.id==="string"&&X.id).map((X)=>({model:X.id,display:X.id,efforts:d$,defaultEffort:"high"}))}async function m_($,Z){let J;try{J=new URL($).origin}catch{return{state:"network",windows:[],reason:"bad base_url"}}try{let Q=await fetch(`${J}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(c_)});if(!Q.ok)return{state:"network",windows:[],reason:`HTTP ${Q.status}`};let Y=await Q.json(),X=(Array.isArray(Y?.balance_infos)?Y.balance_infos:[])[0],V=typeof X?.currency==="string"?X.currency:"",W=V==="CNY"?"¥":V==="USD"?"$":V?`${V} `:"",G=X?.total_balance;if(typeof G!=="string"&&typeof G!=="number")return{state:"ok",windows:[],planLabel:"余额 —(无明细)"};let K=Y?.is_available!==!1;return{state:"ok",windows:[],planLabel:K?`剩余 ${W}${G}`:`⚠️ 余额不足 ${W}${G}`}}catch(Q){return z(`deepseek readUsage MISS: ${Q?.message??Q}`),{state:"network",windows:[],reason:Q?.message??String(Q)}}}var w_="https://api.deepseek.com/anthropic",c_=1e4;var iQ=k(()=>{P$();u2();U4();t7();w();X0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||w_,Q=$.api_key?.trim()||Z?.api_key?.trim()||"",Y=!!Q,H=$.model?.trim()||void 0,X=h_($.slots),V={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Y,models:[],modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},defaultModel:H??"",async refreshModels(){if(!V.enabled){V.models=[],V.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}V.modelCatalogState={status:"loading",updatedAt:null};try{let W=await g_(J,Q),K=f_($.models).filter((_)=>!W.some((B)=>B.model.toLowerCase()===_.toLowerCase())).map((_)=>({model:_,display:_,efforts:d$,defaultEffort:"high"}));if(V.models=[...W,...K],!H)V.defaultModel=v_(V.models.map((_)=>_.model));for(let _ of V.models){let B=P4("deepseek",_.model);_.context1m=B!=null&&B>=1e6||void 0}V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(W){z(`deepseek refreshModels MISS: ${W?.message??W}`),V.models=[],V.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W?.message??String(W)}}},spawnEnv(W){let K={...m0(W)};if(K.ANTHROPIC_BASE_URL=J,K.ANTHROPIC_API_KEY=Q,X.opus)K.ANTHROPIC_DEFAULT_OPUS_MODEL=X.opus;if(X.sonnet)K.ANTHROPIC_DEFAULT_SONNET_MODEL=X.sonnet;if(X.haiku)K.ANTHROPIC_DEFAULT_HAIKU_MODEL=X.haiku;return K},resolveSpawnModel(W){return F4("deepseek",W)},async verifyModel(W){return b9(J,{"x-api-key":Q},W)},async readUsage(){if(!Q)return{state:"no_credentials",windows:[]};return m_(J,Q)}};return V},setup:{commandSuffix:"deepseek",hint:($)=>`启用 ${$}:发送
165
167
  \`\`\`
166
168
  deepseek-setup <api_key>
167
169
  \`\`\`
168
- 默认官方 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,Q=Z.length>=2?Z[1]:Z[0];return{config:{agent:"claude",...J?{base_url:J}:{},api_key:Q}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!C_(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});var iQ={};F1(iQ,{tokenSourceSpawnRevision:()=>lQ,buildTokenSourcesFromConfig:()=>t7});import{createHash as f_}from"node:crypto";function t7(){s6();let $=v7(),Z=N1().map((H)=>{let V=H.configSectionId?(S.token_sources??{})[H.configSectionId]??{}:{},X=H.detect?.fromSettingsEnv($)??null,W=H.build(V,X);return W.spawnRevision=lQ(H.kind,V,X),W}),J=Z.find((H)=>H.kind==="claude-native");if(J){let H=Z.some((V)=>V.agent==="claude"&&V.enabled&&V.kind!=="claude-native");J.enabled=!H,J.modelCatalogState={status:J.enabled?"ready":"disabled",updatedAt:Date.now()}}for(let H of Z)r6(H);let Y=Z.find((H)=>H.enabled&&S.token_sources?.[H.id]?.default===!0)??Z.find((H)=>H.enabled);if(Y)t6(Y.id);return Z.length}function lQ($,Z,J){let Q=(Y)=>({agent:Y?.agent,auth:Y?.auth,base_url:Y?.base_url,auth_token:Y?.auth_token,api_key:Y?.api_key,bin:Y?.bin,model:Y?.model,effort:Y?.effort,slots:Y?.slots});return f_("sha256").update(JSON.stringify({kind:$,configured:Q(Z),detected:Q(J)})).digest("hex")}var s7=E(()=>{y$();A$();y9();gQ();cQ();uQ();pQ()});import{readFileSync as v_}from"node:fs";function h_($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function g_($,Z){let J=[`[token_source.${$}]`],Q=(Y,H)=>{if(H&&H.length)J.push(`${Y} = "${h_(H)}"`)};if(Q("agent",Z.agent),Q("display",Z.display),Q("auth",Z.auth),Q("base_url",Z.base_url),Q("auth_token",Z.auth_token),Q("api_key",Z.api_key),Q("bin",Z.bin),Q("model",Z.model),Q("effort",Z.effort),Q("models",Z.models),Q("slots",Z.slots),Q("usage",Z.usage),Z.default)J.push('default = "true"');return J.join(`
169
- `)}function I_(){Y3(),t7(),p0()}function S9($,Z){let J=v_(L$,"utf8"),Q=`[token_source.${$}]`,Y=J.split(`
170
- `),H=!1,V={},X=[];for(let _ of Y){let j=_.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(j)H=j===Q;if(H){let B=_.match(/^\s*([A-Za-z_]+)\s*=\s*"([^"]*)"/);if(B)V[B[1]]=B[2]}else X.push(_)}let W={...V},z={...Z};for(let _ of Object.keys(z))if(z[_])W[_]=z[_];let K=W;while(X.length&&X[X.length-1]==="")X.pop();J0(L$,X.join(`
170
+ 默认官方 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,Q=Z.length>=2?Z[1]:Z[0];return{config:{agent:"claude",...J?{base_url:J}:{},api_key:Q}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!I_(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});var oQ={};F1(oQ,{tokenSourceSpawnRevision:()=>nQ,buildTokenSourcesFromConfig:()=>s7});import{createHash as u_}from"node:crypto";function s7(){e8();let $=h7(),Z=y1().map((H)=>{let X=H.configSectionId?(b.token_sources??{})[H.configSectionId]??{}:{},V=H.detect?.fromSettingsEnv($)??null,W=H.build(X,V);return W.spawnRevision=nQ(H.kind,X,V),W}),J=Z.find((H)=>H.kind==="claude-native");if(J){let H=Z.some((X)=>X.agent==="claude"&&X.enabled&&X.kind!=="claude-native");J.enabled=!H,J.modelCatalogState={status:J.enabled?"ready":"disabled",updatedAt:Date.now()}}for(let H of Z)t8(H);let Y=Z.find((H)=>H.enabled&&b.token_sources?.[H.id]?.default===!0)??Z.find((H)=>H.enabled);if(Y)s8(Y.id);return Z.length}function nQ($,Z,J){let Q=(Y)=>({agent:Y?.agent,auth:Y?.auth,base_url:Y?.base_url,auth_token:Y?.auth_token,api_key:Y?.api_key,bin:Y?.bin,model:Y?.model,effort:Y?.effort,slots:Y?.slots});return u_("sha256").update(JSON.stringify({kind:$,configured:Q(Z),detected:Q(J)})).digest("hex")}var e7=k(()=>{N$();P$();k9();mQ();pQ();dQ();iQ()});import{readFileSync as p_}from"node:fs";function l_($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function d_($,Z){let J=[`[token_source.${$}]`],Q=(Y,H)=>{if(H&&H.length)J.push(`${Y} = "${l_(H)}"`)};if(Q("agent",Z.agent),Q("display",Z.display),Q("auth",Z.auth),Q("base_url",Z.base_url),Q("auth_token",Z.auth_token),Q("api_key",Z.api_key),Q("bin",Z.bin),Q("model",Z.model),Q("effort",Z.effort),Q("models",Z.models),Q("slots",Z.slots),Q("usage",Z.usage),Z.default)J.push('default = "true"');return J.join(`
171
+ `)}function i_(){H5(),s7(),p0()}function w9($,Z){let J=p_(L$,"utf8"),Q=`[token_source.${$}]`,Y=J.split(`
172
+ `),H=!1,X={},V=[];for(let _ of Y){let B=_.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(B)H=B===Q;if(H){let j=_.match(/^\s*([A-Za-z_]+)\s*=\s*"([^"]*)"/);if(j)X[j[1]]=j[2]}else V.push(_)}let W={...X},G={...Z};for(let _ of Object.keys(G))if(G[_])W[_]=G[_];let K=W;while(V.length&&V[V.length-1]==="")V.pop();J0(L$,V.join(`
171
173
  `)+`
172
174
 
173
- `+g_($,K)+`
174
- `),I_()}var e7=E(()=>{D$();y$();s7();A$();h$()});var $5={};F1($5,{runTokenSourceSetup:()=>m_,onTokenSourceEnable:()=>c_});async function c_($,Z){let J=Z$(Z);if(!J){await O($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled){await O($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Q=N1().find((Y)=>Y.setup?.commandSuffix===Z||Y.configSectionId===Z);if(Q?.setup)await O($.chatId,Q.setup.hint(J.display));else if(J.kind==="codex-subscription")await O($.chatId,`${J.display} 需要 ChatGPT 登录:在服务器执行 \`codex login\`,完成后按当前服务管理方式重启 daemon,或重发 \`model\` 刷新。`);else if(J.kind==="claude-native")await O($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function m_($,Z,J){let Q=N1().find((H)=>H.setup?.commandSuffix===Z);if(!Q?.setup||!Q.configSectionId){await O($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let Y=Q.setup.parseArgs(J);if("error"in Y){await O($.chatId,Y.error);return}try{S9(Q.configSectionId,Y.config),await p0();let H=Z$(Q.configSectionId);await O($.chatId,`✅ ${H?.display??Z} 已启用。发 \`model\` 重新选择。`)}catch(H){await O($.chatId,`❌ 启用失败: ${H?.message??H}`)}}var Z5=E(()=>{n();A$();e7()});async function dQ($,Z,J=""){let Q=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(Q)return await $.runWorktreeCommand((Q[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(/^(?:reviewers|reviewer)$/i))return await $.showConsultIdentityPanel(J),!0;let Y=Z.trim().match(/^(\w+)-setup\s+([\s\S]+)$/i);if(Y){let{runTokenSourceSetup:V}=await Promise.resolve().then(() => (Z5(),$5));return await V($,Y[1].trim(),Y[2].trim()),!0}let H=u_.get(Z.trim().toLowerCase());if(!H)return!1;switch(H){case"model":return await $.showModelPanel(),!0;case"compact":return await $.runCompactCommand(),!0;case"hi":{let X=!$.isRunning(),W=$.backendLabel(),z=X?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${W}`)):null,K=$.withModel(`\uD83D\uDE80 启动 ${W}`);if(!(X?await $.start({announce:!z,onStatus:(j)=>{K=j,$.setStatusCard(z,j)}}):!0))return await $.closeStatusCard(z,K.startsWith("❌")?K:"❌ 启动失败"),!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 $.cancelConsultRuns("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 O($.chatId,"⚪ 当前没有正在执行的 turn");return!0}G(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let V=new Set;for(let[X,W]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(W)P$(X,W);R$(X,"CrossMark"),V.add(X)}for(let X of $.pendingMidTurnMsgs)if(X.msgId&&!V.has(X.msgId))R$(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(),W=$.backendLabel($.proc?.provider??$.currentProvider()),z=X?`\uD83D\uDED1 停止 ${W}`:"⚪ session 当前未运行",K=await $.openStatusCard("kill",z,X?"red":"grey"),_=null,j=X?`✅ ${W} 已终止`:`⚪ ${W} 未运行`;try{await $.stop("已终止",{announce:!K,onStatus:(B)=>{$.setStatusCard(K,B)}})}catch(B){_=B,j=$.isRunning()?`❌ ${W} 未确认终止: ${U(B)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${W} 停止收尾失败: ${U(B)}`}finally{try{await $.closeStatusCard(K,j)}catch(B){G(`session "${$.sessionName}": kill status card close failed: ${U(B)}`),await N($.chatId,`${j}
175
- ⚠️ kill 状态卡片终态写入失败: ${U(B)}`)}}if(_&&!K)await N($.chatId,j)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let X=$.lastSessionId?z$($.lastSessionId):"",W=$.backendLabel($.proc?.provider??$.currentProvider()),z=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${W}`):X?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${X}`):$.withModel(`\uD83D\uDD01 启动 ${W}`),K=await $.openStatusCard("restart",z),_=z,j=await $.restart(!0,{announce:!K,onStatus:(L)=>{_=L,$.setStatusCard(K,L)}}),B=j?_.startsWith("✅")?_:$.withWorktreeInstructionNotice(X?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):_.startsWith("❌")?_:"❌ 重启失败";await $.closeStatusCard(K,j?$.withModel(B):B)}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 O($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let X=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),W="\uD83E\uDDF9 清空并启动新会话",z=await $.restart(!1,{announce:!X,onStatus:(K)=>{W=K,$.setStatusCard(X,K)}});await $.closeStatusCard(X,z?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):W.startsWith("❌")?W:"❌ 清空失败")}return!0}}var u_;var nQ=E(()=>{n();w();u_=new Map([["hi","hi"],["stop","stop"],["st","stop"],["kill","kill"],["kl","kill"],["restart","restart"],["rs","restart"],["clear","clear"],["cl","clear"],["compact","compact"],["cm","compact"],["model","model"],["md","model"]])});function d_($,Z){let J=!1,Q=null,Y=()=>{},H=()=>{},V=$.sessionId,X=()=>{if(Q)clearTimeout(Q),Q=null;$.off("context_compacted",K),$.off("exit",_),$.off("error",j)},W=(L)=>{if(J)return;J=!0,X(),Y(L)},z=(L)=>{if(J)return;J=!0,X(),H(L)},K=(L)=>{if(L.phase==="start")return;if(L.threadId&&V&&L.threadId!==V)return;W(L)},_=()=>z(Error("codex app-server exited before context compaction completed")),j=(L)=>z(L instanceof Error?L:Error(String(L))),B=new Promise((L,P)=>{Y=L,H=P});return $.on("context_compacted",K),$.once("exit",_),$.once("error",j),{promise:B,cancel(){if(J)return;J=!0,X()}}}function n_($,Z){let J=[],Q=new Set,Y=(X,W)=>{let z=W.threadId??Z;if(z&&X.threadId&&X.threadId!==z)return!1;if(W.turnId)return X.turnId===W.turnId;return!0},H=(X)=>{for(let W=J.length-1;W>=0;W--){let z=J[W];if(z&&Y(z,X))return z}return null},V=(X)=>{if(Z&&X.threadId&&X.threadId!==Z)return;let W={usage:X.usage,contextWindow:X.contextWindow,threadId:X.threadId,turnId:X.turnId};J.push(W);for(let z of[...Q])if(Y(W,z.notice))z.finish(W)};return $.on("token_usage",V),{waitFor(X,W){let z=H(X);if(z)return Promise.resolve(z);return new Promise((K)=>{let _=null,j={notice:X,finish:(B)=>{if(_)clearTimeout(_);Q.delete(j),K(B)}};_=setTimeout(()=>j.finish(null),W),Q.add(j)})},cancel(){$.off("token_usage",V);for(let X of[...Q])X.finish(null)}}}function o_($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=c4($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=m4($.contextWindow);return` · \uD83E\uDDE0 ${pZ(Z,J)} (${u4(Z,J)})`}async function oQ($){$.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 O($.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 O($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let z=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(z)await $.closeStatusCard(z,"⏳ 上下文压缩已在进行中");else await O($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Q=J.sessionId?z$(J.sessionId):"",Y=$.withModel(Q?`\uD83E\uDDE0 压缩上下文 thread=${Q}`:"\uD83E\uDDE0 压缩上下文…"),H=await $.openStatusCard("compact",Y,"orange"),V=async(z)=>{if(H)await $.closeStatusCard(H,z);else await O($.chatId,z)},X=d_(J,l_),W=n_(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(H,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(H,$.withModel("⏳ 等待压缩完成事件"));let z=await X.promise,K=await W.waitFor(z,i_),_=z.threadId?` thread=${z$(z.threadId)}`:"";await V($.withModel(`✅ 上下文已压缩${_}${o_(K)}`))}catch(z){if(X.cancel(),z instanceof G2)await V($.withModel(`ⓘ ${z.message}`));else await V(`❌ 上下文压缩失败: ${U(z)}`)}finally{W.cancel(),$.manualContextCompactionPending=!1}}var l_=600000,i_=1500;var aQ=E(()=>{c0();n()});import{randomUUID as r_}from"node:crypto";function t_($){let Z=$.currentTokenSource(),J=$.currentModelLabel();return u0().filter((Q)=>Q.enabled||Q.kind!=="claude-native").map((Q)=>({provider:Q.agent,sourceId:Q.id,display:Q.display,enabled:Q.enabled,modelCount:Q.models.length,selected:Z?.id===Q.id}))}function rQ($,Z){let J=$.currentModelLabel(),Q=$.currentEffortLabel(),Y=$.currentTokenSource()?.id===Z.id;return Z.models.map((H)=>{let V=Y&&J===H.model;return{provider:Z.agent,sourceId:Z.id,model:H.model,displayName:H.display,description:Z.display,enabled:!0,isDefault:!1,selected:V,efforts:H.efforts.map((X)=>({effort:X,description:"",isDefault:X===H.defaultEffort,selected:V&&Q===X}))}})}async function tQ($){p0();let Z=r_(),J=t_($);if($.modelPanels.set(Z,{models:[]}),!await c($.chatId,_7({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J})))$.modelPanels.delete(Z),await N($.chatId,"❌ 模型面板发送失败")}async function sQ($,Z,J=""){let Q=Z.trim(),Y=Z$(Q);if(!Y)return{ok:!1,message:`未知账号: ${Q}`};if(!Y.enabled)return{ok:!1,message:`${Y.display} 未配置,请先点「启用」`};let H=J.trim(),V=rQ($,Y);return $.modelPanels.set(H,{models:V}),{ok:!0,message:"",card:q7({sessionName:$.sessionName,panelId:H,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),models:V})}}async function eQ($,Z,J,Q=""){let Y=Z$(Z.trim());if(!Y)return{ok:!1,message:`未知账号: ${Z}`};if(!Y.enabled)return{ok:!1,message:`${Y.display} 未配置`};if(Y.agent!=="claude"||!Y.verifyModel)return{ok:!1,message:`${Y.display} 不支持手动补录模型`};let H=J.trim();if(!H)return{ok:!1,message:"补录面板缺少 panel_id,请重新发送 model"};return $.modelCustomPrompt={sourceId:Y.id,panelId:H,cardMessageId:Q},{ok:!0,message:"等待模型名",card:B7($.sessionName,Y.display,H)}}async function $Y($,Z,J){let Q=$.modelCustomPrompt;if(!Q)return!1;$.modelCustomPrompt=null;let Y=Z.trim(),H=Z$(Q.sourceId),V=async(P)=>{if(!Q.cardMessageId)return!1;let A="",R=!1,D=!1;try{if(A=await r$(Q.cardMessageId),c$(A,1),R=await U$(A,M.modelPanel,P,{notifyCardFailure:!1}),!R)throw Error("model panel replace rejected");if(D=await q$(A,{config:{streaming_mode:!1}}),!D)throw Error("model panel streaming-off rejected")}catch(F){G(`model-custom: card update MISS (${F?.message??F})`)}finally{if(A){if(!D)try{D=await q$(A,{config:{streaming_mode:!1}})}catch(F){G(`model-custom: streaming-off retry MISS (${F?.message??F})`)}if(R&&D)try{await b$(A)}catch(F){G(`model-custom: card dispose MISS (${F?.message??F})`)}else G(`model-custom: retain card state after checked MISS mutation=${R} streamingOff=${D} card=${A.slice(0,12)}`)}}return R&&D},X=async(P,A)=>{if(await V(P))return!0;let D=`⚠️ 模型补录结果未能写回原卡。${A}
176
- 请重新发送 model 打开面板。`;if(!await N($.chatId,D))G(`model-custom: visible fallback send MISS (${A})`);return!1},W=(P)=>X(K9(!1,Y,P),`❌ ${Y?`模型 ${Y}`:"模型名"} 未加入:${P}。`);if(!H||!H.enabled||!H.verifyModel)return await W("账号不可用"),!0;if(!Y)return await W("模型名为空"),!0;if(H.models.some((P)=>P.model.toLowerCase()===Y.toLowerCase()))return await X(K9(!1,Y,"已在列表中"),`ℹ️ 模型 ${Y} 已在列表中,未重复加入。`),!0;let z=await H.verifyModel(Y);if(z==="not_found")return await W("端点确认不存在"),!0;if(z==="no_verdict")return await W("无法校验(端点无响应或凭据问题)"),!0;let K=[...s_(H.id),Y].join(",");S9(H.id,{models:K}),G(`model-custom: ${H.id} 补录 ${Y} by ${J}(端点校验通过,已持久化)`);let _=Z$(H.id)??H;try{await N6(_.refreshModels(),15000,"refreshModels")}catch(P){G(`model-custom: refresh after 补录 MISS (${P?.message??P})`)}let j=_.models.some((P)=>P.model===Y)?_:H,B=rQ($,j),L=B.find((P)=>P.model===Y);if(!L)return await W("模型已验证,但刷新后的模型列表未返回该项"),!0;return $.modelPanels.set(Q.panelId,{models:B}),await X(_9({sessionName:$.sessionName,panelId:Q.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:L}),`✅ 模型 ${Y} 已补录成功。`),!0}function s_($){return(S.token_sources[$]?.models??"").split(",").map((J)=>J.trim()).filter(Boolean)}async function ZY($,Z=""){let J=Z.trim(),Q=$.modelCustomPrompt;if(!J||!Q||Q.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:G9($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:G9($.sessionName)}}function e_($,Z){return Z?.provider==="claude"||Z?.provider==="codex"?Z.provider:E1($)}function $q($,Z){if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${H0(Z)} 时使用。`}async function JY($,Z,J="",Q="",Y=null){let H=Z.trim();if(!H)return await O($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let V=e_(H,Y),X=$.modelPanels.get(J.trim())?.models.find((W)=>W.model===H&&(W.provider??"codex")===V);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:j7({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:X})}}async function QY($,Z,J,Q="",Y="",H=""){let V=Z.trim(),X=J.trim();if(!V)return{ok:!1,message:"模型为空"};let W=Q.trim(),z=$.modelPanels.get(W),K=H==="claude"||H==="codex"?H:z?.models.find((D)=>D.model===V)?.provider??E1(V);if(K==="claude"){if(!o$(X))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!E$(X))return{ok:!1,message:"Codex reasoning effort 无效"};let _=X,j=z?.models.find((D)=>D.model===V&&(D.provider??"codex")===K);if(!j||!j.efforts.some((D)=>D.effort===_))return{ok:!1,message:`${H0(K)} · ${V}/${_} 不在选项中`};let B=!!j.sourceId&&$.currentTokenSource()?.id!==j.sourceId;if($.currentProvider()===K&&!B&&$.currentModelLabel()===V&&$.currentEffortLabel()===_)return $.modelPanels.delete(W),{ok:!0,message:`当前已是 ${H0(K)} · ${V} / ${_}`,card:z9({sessionName:$.sessionName,provider:K,model:V,effort:_,scope:"当前已是此设置,无需变更。"})};if($.proc?.isAlive()&&$.proc.provider!==K&&($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0))return{ok:!1,message:`当前 ${$.backendLabel($.proc.provider)} turn 正在执行或排队;请等结束或 stop 后再切换到 ${H0(K)}`};let A=$.currentModelLabel()!==V||B,R=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if(K==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&A&&R)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===K&&!B){let F=j.sourceId?Z$(j.sourceId)?.resolveSpawnModel(V)??V:V;await N6($.proc.setModelSettings(F,_),20000,"thread/settings/update")}await $.applyModelSelectionUnlocked(K,V,_,j.sourceId);let D=$q($,K);return $.modelPanels.delete(W),{ok:!0,message:`已选择 ${H0(K)} · ${V} / ${_}`,card:z9({sessionName:$.sessionName,provider:K,model:V,effort:_,scope:D})}}catch(D){let F=`模型切换失败: ${U(D)}`;return G(`session "${$.sessionName}": set model settings failed: ${U(D)}`),await O($.chatId,`❌ ${F}`),{ok:!1,message:F}}}var YY=E(()=>{y$();A$();e7();k1();c0();w$();t0();n();w()});import{createHash as Jq,randomUUID as Qq}from"node:crypto";import{existsSync as Yq,readFileSync as Hq}from"node:fs";function Xq($,Z){return`catalog:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function D0(){return Wq(u0(),O$.presets,L0)}function Wq($,Z=[],J=null){let Q=[],Y=[];for(let X of $)zq(X,Q,Y);let H=new Map(Q.map((X)=>[X.id,X]));for(let X of Z)Q.push(Kq(X,H.get(X.baseIdentityId)));return{catalogGeneration:Jq("sha256").update(JSON.stringify({identities:Q,sourceFailures:Y,presetFailure:J})).digest("hex").slice(0,16),identities:Q,sourceFailures:Y,...J?{presetFailure:J}:{}}}function f9(){return O$.presets.map(w9)}function VY($,Z,J="max"){if(L0)throw Error(`consult identity store is unavailable: ${L0}`);if(!i1.includes(Z))throw Error(`unsupported consult role: ${Z}`);let Q=D0().identities.find((X)=>X.origin==="catalog"&&X.id===$);if(!Q)throw Error(`base consult identity not found: ${$}`);if(O$.presets.some((X)=>X.baseIdentityId===$&&X.role===Z&&(X.effort??"max")===J))throw Error(`consult identity preset already exists: ${$1(Z)} · ${Q.modelDisplay}`);let Y=new Date().toISOString(),H={id:`preset:${Qq()}`,name:`${$1(Z)} · ${Q.modelDisplay}`,baseIdentityId:$,role:Z,effort:J,enabled:!0,createdAt:Y,updatedAt:Y},V={version:1,presets:[...O$.presets,H]};return J5(V),O$=V,w9(H)}function XY($){if(L0)throw Error(`consult identity store is unavailable: ${L0}`);let Z=O$.presets.findIndex((H)=>H.id===$);if(Z<0)throw Error(`consult identity preset not found: ${$}`);let J=w9(O$.presets[Z]);J.enabled=!J.enabled,J.updatedAt=new Date().toISOString();let Y={version:1,presets:O$.presets.map((H,V)=>V===Z?J:H)};return J5(Y),O$=Y,w9(J)}function WY($){if(L0)throw Error(`consult identity store is unavailable: ${L0}`);let Z=O$.presets.filter((Q)=>Q.id!==$);if(Z.length===O$.presets.length)throw Error(`consult identity preset not found: ${$}`);let J={version:1,presets:Z};J5(J),O$=J}function zq($,Z,J){let Q=$.modelCatalogState?.status??(!$.enabled?"disabled":$.models.length>0?"ready":"idle");if(!$.enabled)J.push({tokenSourceId:$.id,display:$.display,status:"disabled",reason:"账号未启用"});else if(Q==="loading"||Q==="idle")J.push({tokenSourceId:$.id,display:$.display,status:"loading",reason:"模型目录正在刷新"});else if(Q==="failed")J.push({tokenSourceId:$.id,display:$.display,status:"failed",reason:$.modelCatalogState?.error??"模型目录刷新失败"});else if($.models.length===0)J.push({tokenSourceId:$.id,display:$.display,status:"models_miss",reason:"模型目录为空"});for(let Y of $.models)Z.push(Gq($,Y,Q))}function Gq($,Z,J){let Q="ready",Y;if(!$.enabled)Q="source_disabled",Y="所属 Token Source 未启用";else if(J==="loading"||J==="idle")Q="catalog_loading",Y="模型目录正在刷新";else if(J==="failed")Q="catalog_failed",Y=$.modelCatalogState?.error??"模型目录刷新失败";else if(!Z.efforts.includes("max"))Q="effort_unsupported",Y="该模型不支持 max effort";return{id:Xq($.id,Z.model),displayName:`${$.display} · ${Z.display}`,tokenSourceId:$.id,tokenSourceDisplay:$.display,provider:$.agent,model:Z.model,modelDisplay:Z.display,effort:"max",supportedEfforts:[...Z.efforts],sourceDefault:HY($.defaultModel)===HY(Z.model),origin:"catalog",status:Q,...Y?{reason:Y}:{},role:"general",instructions:c2("general"),spawnRevision:$.spawnRevision}}function HY($){return $.replace(/\[1m\]$/i,"").toLowerCase()}function Kq($,Z){if(!Z)return{id:$.id,displayName:$.name,tokenSourceId:"",tokenSourceDisplay:"MISS",provider:"codex",model:"",modelDisplay:"MISS",effort:$.effort??"max",supportedEfforts:[],sourceDefault:!1,origin:"preset",status:"base_missing",reason:"底层模型身份已不存在",role:$.role,instructions:[c2($.role),$.instructions].filter(Boolean).join(`
175
+ `+d_($,K)+`
176
+ `),i_()}var $3=k(()=>{D$();N$();e7();P$();h$()});var Z3={};F1(Z3,{runTokenSourceSetup:()=>o_,onTokenSourceEnable:()=>n_});async function n_($,Z){let J=Z$(Z);if(!J){await O($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled){await O($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Q=y1().find((Y)=>Y.setup?.commandSuffix===Z||Y.configSectionId===Z);if(Q?.setup)await O($.chatId,Q.setup.hint(J.display));else if(J.kind==="codex-subscription")await O($.chatId,`${J.display} 需要 ChatGPT 登录:在服务器执行 \`codex login\`,完成后按当前服务管理方式重启 daemon,或重发 \`model\` 刷新。`);else if(J.kind==="claude-native")await O($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function o_($,Z,J){let Q=y1().find((H)=>H.setup?.commandSuffix===Z);if(!Q?.setup||!Q.configSectionId){await O($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let Y=Q.setup.parseArgs(J);if("error"in Y){await O($.chatId,Y.error);return}try{w9(Q.configSectionId,Y.config),await p0();let H=Z$(Q.configSectionId);await O($.chatId,`✅ ${H?.display??Z} 已启用。发 \`model\` 重新选择。`)}catch(H){await O($.chatId,`❌ 启用失败: ${H?.message??H}`)}}var J3=k(()=>{n();P$();$3()});async function aQ($,Z,J=""){let Q=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(Q)return await $.runWorktreeCommand((Q[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(/^(?:reviewers|reviewer)$/i))return await $.showConsultIdentityPanel(J),!0;let Y=Z.trim().match(/^(\w+)-setup\s+([\s\S]+)$/i);if(Y){let{runTokenSourceSetup:X}=await Promise.resolve().then(() => (J3(),Z3));return await X($,Y[1].trim(),Y[2].trim()),!0}let H=a_.get(Z.trim().toLowerCase());if(!H)return!1;switch(H){case"model":return await $.showModelPanel(),!0;case"compact":return await $.runCompactCommand(),!0;case"hi":{let V=!$.isRunning(),W=$.backendLabel(),G=V?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${W}`)):null,K=$.withModel(`\uD83D\uDE80 启动 ${W}`);if(!(V?await $.start({announce:!G,onStatus:(B)=>{K=B,$.setStatusCard(G,B)}}):!0))return await $.closeStatusCard(G,K.startsWith("❌")?K:"❌ 启动失败"),!0;if(G)return await $.replaceStatusCardWithConsole(G,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(V)await $.closeStatusCard(G,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":if(await $.cancelConsultRuns("stop command"),$.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){let V=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(V)await $.closeStatusCard(V,"⚪ 无正在执行的 turn");else await O($.chatId,"⚪ 当前没有正在执行的 turn");return!0}z(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let X=new Set;for(let[V,W]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(W)A$(V,W);R$(V,"CrossMark"),X.add(V)}for(let V of $.pendingMidTurnMsgs)if(V.msgId&&!X.has(V.msgId))R$(V.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 V=$.isRunning(),W=$.backendLabel($.proc?.provider??$.currentProvider()),G=V?`\uD83D\uDED1 停止 ${W}`:"⚪ session 当前未运行",K=await $.openStatusCard("kill",G,V?"red":"grey"),_=null,B=V?`✅ ${W} 已终止`:`⚪ ${W} 未运行`;try{await $.stop("已终止",{announce:!K,onStatus:(j)=>{$.setStatusCard(K,j)}})}catch(j){_=j,B=$.isRunning()?`❌ ${W} 未确认终止: ${U(j)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${W} 停止收尾失败: ${U(j)}`}finally{try{await $.closeStatusCard(K,B)}catch(j){z(`session "${$.sessionName}": kill status card close failed: ${U(j)}`),await y($.chatId,`${B}
177
+ ⚠️ kill 状态卡片终态写入失败: ${U(j)}`)}}if(_&&!K)await y($.chatId,B)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let V=$.lastSessionId?G$($.lastSessionId):"",W=$.backendLabel($.proc?.provider??$.currentProvider()),G=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${W}`):V?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${V}`):$.withModel(`\uD83D\uDD01 启动 ${W}`),K=await $.openStatusCard("restart",G),_=G,B=await $.restart(!0,{announce:!K,onStatus:(L)=>{_=L,$.setStatusCard(K,L)}}),j=B?_.startsWith("✅")?_:$.withWorktreeInstructionNotice(V?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):_.startsWith("❌")?_:"❌ 重启失败";await $.closeStatusCard(K,B?$.withModel(j):j)}return!0;case"clear":if(!$.isRunning()){$.status="stopped",$.opts.onLifecycleChange?.();let V=await $.openStatusCard("clear","⚪ session 当前未运行","grey");if(V)await $.closeStatusCard(V,`⚪ ${$.backendLabel()} 未运行,clear 无效`);else await O($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let V=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),W="\uD83E\uDDF9 清空并启动新会话",G=await $.restart(!1,{announce:!V,onStatus:(K)=>{W=K,$.setStatusCard(V,K)}});await $.closeStatusCard(V,G?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):W.startsWith("❌")?W:"❌ 清空失败")}return!0}}var a_;var rQ=k(()=>{n();w();a_=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 e_($,Z){let J=!1,Q=null,Y=()=>{},H=()=>{},X=$.sessionId,V=()=>{if(Q)clearTimeout(Q),Q=null;$.off("context_compacted",K),$.off("exit",_),$.off("error",B)},W=(L)=>{if(J)return;J=!0,V(),Y(L)},G=(L)=>{if(J)return;J=!0,V(),H(L)},K=(L)=>{if(L.phase==="start")return;if(L.threadId&&X&&L.threadId!==X)return;W(L)},_=()=>G(Error("codex app-server exited before context compaction completed")),B=(L)=>G(L instanceof Error?L:Error(String(L))),j=new Promise((L,A)=>{Y=L,H=A});return $.on("context_compacted",K),$.once("exit",_),$.once("error",B),{promise:j,cancel(){if(J)return;J=!0,V()}}}function $q($,Z){let J=[],Q=new Set,Y=(V,W)=>{let G=W.threadId??Z;if(G&&V.threadId&&V.threadId!==G)return!1;if(W.turnId)return V.turnId===W.turnId;return!0},H=(V)=>{for(let W=J.length-1;W>=0;W--){let G=J[W];if(G&&Y(G,V))return G}return null},X=(V)=>{if(Z&&V.threadId&&V.threadId!==Z)return;let W={usage:V.usage,contextWindow:V.contextWindow,threadId:V.threadId,turnId:V.turnId};J.push(W);for(let G of[...Q])if(Y(W,G.notice))G.finish(W)};return $.on("token_usage",X),{waitFor(V,W){let G=H(V);if(G)return Promise.resolve(G);return new Promise((K)=>{let _=null,B={notice:V,finish:(j)=>{if(_)clearTimeout(_);Q.delete(B),K(j)}};_=setTimeout(()=>B.finish(null),W),Q.add(B)})},cancel(){$.off("token_usage",X);for(let V of[...Q])V.finish(null)}}}function Zq($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=c4($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=m4($.contextWindow);return` · \uD83E\uDDE0 ${lZ(Z,J)} (${u4(Z,J)})`}async function tQ($){$.clearStaleIdleQueueState("compact");let Z=!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0&&!$.openingTurn;if(!$.isRunning()||!$.proc){$.status="stopped",$.opts.onLifecycleChange?.();let G=await $.openStatusCard("compact","⚪ session 当前未运行","grey");if(G)await $.closeStatusCard(G,"⚪ 后端未运行,compact 无效");else await O($.chatId,`⚪ session "${$.sessionName}" 当前未运行,compact 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return}if(!Z){let G=await $.openStatusCard("compact","⚠️ 当前 turn 正在执行","grey");if(G)await $.closeStatusCard(G,"⚠️ 先 stop 当前 turn,再 compact");else await O($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let G=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(G)await $.closeStatusCard(G,"⏳ 上下文压缩已在进行中");else await O($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Q=J.sessionId?G$(J.sessionId):"",Y=$.withModel(Q?`\uD83E\uDDE0 压缩上下文 thread=${Q}`:"\uD83E\uDDE0 压缩上下文…"),H=await $.openStatusCard("compact",Y,"orange"),X=async(G)=>{if(H)await $.closeStatusCard(H,G);else await O($.chatId,G)},V=e_(J,t_),W=$q(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(H,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(H,$.withModel("⏳ 等待压缩完成事件"));let G=await V.promise,K=await W.waitFor(G,s_),_=G.threadId?` thread=${G$(G.threadId)}`:"";await X($.withModel(`✅ 上下文已压缩${_}${Zq(K)}`))}catch(G){if(V.cancel(),G instanceof z2)await X($.withModel(`ⓘ ${G.message}`));else await X(`❌ 上下文压缩失败: ${U(G)}`)}finally{W.cancel(),$.manualContextCompactionPending=!1}}var t_=600000,s_=1500;var sQ=k(()=>{c0();n()});import{randomUUID as Qq}from"node:crypto";function Yq($){let Z=$.currentTokenSource(),J=$.currentModelLabel();return u0().filter((Q)=>Q.enabled||Q.kind!=="claude-native").map((Q)=>({provider:Q.agent,sourceId:Q.id,display:Q.display,enabled:Q.enabled,modelCount:Q.models.length,selected:Z?.id===Q.id}))}function eQ($,Z){let J=$.currentModelLabel(),Q=$.currentEffortLabel(),Y=$.currentTokenSource()?.id===Z.id;return Z.models.map((H)=>{let X=Y&&J===H.model;return{provider:Z.agent,sourceId:Z.id,model:H.model,displayName:H.display,description:Z.display,enabled:!0,isDefault:!1,selected:X,efforts:H.efforts.map((V)=>({effort:V,description:"",isDefault:V===H.defaultEffort,selected:X&&Q===V}))}})}async function $Y($){p0();let Z=Qq(),J=Yq($);if($.modelPanels.set(Z,{models:[]}),!await c($.chatId,q7({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J})))$.modelPanels.delete(Z),await y($.chatId,"❌ 模型面板发送失败")}async function ZY($,Z,J=""){let Q=Z.trim(),Y=Z$(Q);if(!Y)return{ok:!1,message:`未知账号: ${Q}`};if(!Y.enabled)return{ok:!1,message:`${Y.display} 未配置,请先点「启用」`};let H=J.trim(),X=eQ($,Y);return $.modelPanels.set(H,{models:X}),{ok:!0,message:"",card:B7({sessionName:$.sessionName,panelId:H,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),models:X})}}async function JY($,Z,J,Q=""){let Y=Z$(Z.trim());if(!Y)return{ok:!1,message:`未知账号: ${Z}`};if(!Y.enabled)return{ok:!1,message:`${Y.display} 未配置`};if(Y.agent!=="claude"||!Y.verifyModel)return{ok:!1,message:`${Y.display} 不支持手动补录模型`};let H=J.trim();if(!H)return{ok:!1,message:"补录面板缺少 panel_id,请重新发送 model"};return $.modelCustomPrompt={sourceId:Y.id,panelId:H,cardMessageId:Q},{ok:!0,message:"等待模型名",card:L7($.sessionName,Y.display,H)}}async function QY($,Z,J){let Q=$.modelCustomPrompt;if(!Q)return!1;$.modelCustomPrompt=null;let Y=Z.trim(),H=Z$(Q.sourceId),X=async(A)=>{if(!Q.cardMessageId)return!1;let P="",R=!1,D=!1;try{if(P=await r$(Q.cardMessageId),c$(P,1),R=await U$(P,M.modelPanel,A,{notifyCardFailure:!1}),!R)throw Error("model panel replace rejected");if(D=await q$(P,{config:{streaming_mode:!1}}),!D)throw Error("model panel streaming-off rejected")}catch(F){z(`model-custom: card update MISS (${F?.message??F})`)}finally{if(P){if(!D)try{D=await q$(P,{config:{streaming_mode:!1}})}catch(F){z(`model-custom: streaming-off retry MISS (${F?.message??F})`)}if(R&&D)try{await S$(P)}catch(F){z(`model-custom: card dispose MISS (${F?.message??F})`)}else z(`model-custom: retain card state after checked MISS mutation=${R} streamingOff=${D} card=${P.slice(0,12)}`)}}return R&&D},V=async(A,P)=>{if(await X(A))return!0;let D=`⚠️ 模型补录结果未能写回原卡。${P}
178
+ 请重新发送 model 打开面板。`;if(!await y($.chatId,D))z(`model-custom: visible fallback send MISS (${P})`);return!1},W=(A)=>V(K9(!1,Y,A),`❌ ${Y?`模型 ${Y}`:"模型名"} 未加入:${A}。`);if(!H||!H.enabled||!H.verifyModel)return await W("账号不可用"),!0;if(!Y)return await W("模型名为空"),!0;if(H.models.some((A)=>A.model.toLowerCase()===Y.toLowerCase()))return await V(K9(!1,Y,"已在列表中"),`ℹ️ 模型 ${Y} 已在列表中,未重复加入。`),!0;let G=await H.verifyModel(Y);if(G==="not_found")return await W("端点确认不存在"),!0;if(G==="no_verdict")return await W("无法校验(端点无响应或凭据问题)"),!0;let K=[...Hq(H.id),Y].join(",");w9(H.id,{models:K}),z(`model-custom: ${H.id} 补录 ${Y} by ${J}(端点校验通过,已持久化)`);let _=Z$(H.id)??H;try{await C8(_.refreshModels(),15000,"refreshModels")}catch(A){z(`model-custom: refresh after 补录 MISS (${A?.message??A})`)}let B=_.models.some((A)=>A.model===Y)?_:H,j=eQ($,B),L=j.find((A)=>A.model===Y);if(!L)return await W("模型已验证,但刷新后的模型列表未返回该项"),!0;return $.modelPanels.set(Q.panelId,{models:j}),await V(_9({sessionName:$.sessionName,panelId:Q.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:L}),`✅ 模型 ${Y} 已补录成功。`),!0}function Hq($){return(b.token_sources[$]?.models??"").split(",").map((J)=>J.trim()).filter(Boolean)}async function YY($,Z=""){let J=Z.trim(),Q=$.modelCustomPrompt;if(!J||!Q||Q.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:z9($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:z9($.sessionName)}}function Xq($,Z){return Z?.provider==="claude"||Z?.provider==="codex"?Z.provider:k1($)}function Vq($,Z){if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${H0(Z)} 时使用。`}async function HY($,Z,J="",Q="",Y=null){let H=Z.trim();if(!H)return await O($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let X=Xq(H,Y),V=$.modelPanels.get(J.trim())?.models.find((W)=>W.model===H&&(W.provider??"codex")===X);if(!V)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if(V.enabled===!1)return{ok:!1,message:`${V.displayName} 未配置,请先点「启用」`};if(V.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};return{ok:!0,message:"",card:j7({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:V})}}async function XY($,Z,J,Q="",Y="",H=""){let X=Z.trim(),V=J.trim();if(!X)return{ok:!1,message:"模型为空"};let W=Q.trim(),G=$.modelPanels.get(W),K=H==="claude"||H==="codex"?H:G?.models.find((D)=>D.model===X)?.provider??k1(X);if(K==="claude"){if(!o$(V))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!k$(V))return{ok:!1,message:"Codex reasoning effort 无效"};let _=V,B=G?.models.find((D)=>D.model===X&&(D.provider??"codex")===K);if(!B||!B.efforts.some((D)=>D.effort===_))return{ok:!1,message:`${H0(K)} · ${X}/${_} 不在选项中`};let j=!!B.sourceId&&$.currentTokenSource()?.id!==B.sourceId;if($.currentProvider()===K&&!j&&$.currentModelLabel()===X&&$.currentEffortLabel()===_)return $.modelPanels.delete(W),{ok:!0,message:`当前已是 ${H0(K)} · ${X} / ${_}`,card:G9({sessionName:$.sessionName,provider:K,model:X,effort:_,scope:"当前已是此设置,无需变更。"})};if($.proc?.isAlive()&&$.proc.provider!==K&&($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0))return{ok:!1,message:`当前 ${$.backendLabel($.proc.provider)} turn 正在执行或排队;请等结束或 stop 后再切换到 ${H0(K)}`};let P=$.currentModelLabel()!==X||j,R=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if(K==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&P&&R)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===K&&!j){let F=B.sourceId?Z$(B.sourceId)?.resolveSpawnModel(X)??X:X;await C8($.proc.setModelSettings(F,_),20000,"thread/settings/update")}await $.applyModelSelectionUnlocked(K,X,_,B.sourceId);let D=Vq($,K);return $.modelPanels.delete(W),{ok:!0,message:`已选择 ${H0(K)} · ${X} / ${_}`,card:G9({sessionName:$.sessionName,provider:K,model:X,effort:_,scope:D})}}catch(D){let F=`模型切换失败: ${U(D)}`;return z(`session "${$.sessionName}": set model settings failed: ${U(D)}`),await O($.chatId,`❌ ${F}`),{ok:!1,message:F}}}var VY=k(()=>{N$();P$();$3();E1();c0();w$();t0();n();w()});import{createHash as Gq,randomUUID as zq}from"node:crypto";import{existsSync as Kq,readFileSync as _q}from"node:fs";function Bq($,Z){return`catalog:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function D0(){return jq(u0(),O$.presets,L0)}function jq($,Z=[],J=null){let Q=[],Y=[];for(let V of $)Lq(V,Q,Y);let H=new Map(Q.map((V)=>[V.id,V]));for(let V of Z)Q.push(Aq(V,H.get(V.baseIdentityId)));return{catalogGeneration:Gq("sha256").update(JSON.stringify({identities:Q,sourceFailures:Y,presetFailure:J})).digest("hex").slice(0,16),identities:Q,sourceFailures:Y,...J?{presetFailure:J}:{}}}function v9(){return O$.presets.map(f9)}function GY($,Z,J="max"){if(L0)throw Error(`consult identity store is unavailable: ${L0}`);if(!d1.includes(Z))throw Error(`unsupported consult role: ${Z}`);let Q=D0().identities.find((V)=>V.origin==="catalog"&&V.id===$);if(!Q)throw Error(`base consult identity not found: ${$}`);if(O$.presets.some((V)=>V.baseIdentityId===$&&V.role===Z&&(V.effort??"max")===J))throw Error(`consult identity preset already exists: ${$1(Z)} · ${Q.modelDisplay}`);let Y=new Date().toISOString(),H={id:`preset:${zq()}`,name:`${$1(Z)} · ${Q.modelDisplay}`,baseIdentityId:$,role:Z,effort:J,enabled:!0,createdAt:Y,updatedAt:Y},X={version:1,presets:[...O$.presets,H]};return Q3(X),O$=X,f9(H)}function zY($){if(L0)throw Error(`consult identity store is unavailable: ${L0}`);let Z=O$.presets.findIndex((H)=>H.id===$);if(Z<0)throw Error(`consult identity preset not found: ${$}`);let J=f9(O$.presets[Z]);J.enabled=!J.enabled,J.updatedAt=new Date().toISOString();let Y={version:1,presets:O$.presets.map((H,X)=>X===Z?J:H)};return Q3(Y),O$=Y,f9(J)}function KY($){if(L0)throw Error(`consult identity store is unavailable: ${L0}`);let Z=O$.presets.filter((Q)=>Q.id!==$);if(Z.length===O$.presets.length)throw Error(`consult identity preset not found: ${$}`);let J={version:1,presets:Z};Q3(J),O$=J}function Lq($,Z,J){let Q=$.modelCatalogState?.status??(!$.enabled?"disabled":$.models.length>0?"ready":"idle");if(!$.enabled)J.push({tokenSourceId:$.id,display:$.display,status:"disabled",reason:"账号未启用"});else if(Q==="loading"||Q==="idle")J.push({tokenSourceId:$.id,display:$.display,status:"loading",reason:"模型目录正在刷新"});else if(Q==="failed")J.push({tokenSourceId:$.id,display:$.display,status:"failed",reason:$.modelCatalogState?.error??"模型目录刷新失败"});else if($.models.length===0)J.push({tokenSourceId:$.id,display:$.display,status:"models_miss",reason:"模型目录为空"});for(let Y of $.models)Z.push(Dq($,Y,Q))}function Dq($,Z,J){let Q="ready",Y;if(!$.enabled)Q="source_disabled",Y="所属 Token Source 未启用";else if(J==="loading"||J==="idle")Q="catalog_loading",Y="模型目录正在刷新";else if(J==="failed")Q="catalog_failed",Y=$.modelCatalogState?.error??"模型目录刷新失败";else if(!Z.efforts.includes("max"))Q="effort_unsupported",Y="该模型不支持 max effort";return{id:Bq($.id,Z.model),displayName:`${$.display} · ${Z.display}`,tokenSourceId:$.id,tokenSourceDisplay:$.display,provider:$.agent,model:Z.model,modelDisplay:Z.display,effort:"max",supportedEfforts:[...Z.efforts],sourceDefault:WY($.defaultModel)===WY(Z.model),origin:"catalog",status:Q,...Y?{reason:Y}:{},role:"general",instructions:c2("general"),spawnRevision:$.spawnRevision}}function WY($){return $.replace(/\[1m\]$/i,"").toLowerCase()}function Aq($,Z){if(!Z)return{id:$.id,displayName:$.name,tokenSourceId:"",tokenSourceDisplay:"MISS",provider:"codex",model:"",modelDisplay:"MISS",effort:$.effort??"max",supportedEfforts:[],sourceDefault:!1,origin:"preset",status:"base_missing",reason:"底层模型身份已不存在",role:$.role,instructions:[c2($.role),$.instructions].filter(Boolean).join(`
177
179
  `),baseIdentityId:$.baseIdentityId};let J=$.effort??"max",Q=Z.status,Y=Z.reason;if(!$.enabled)Q="preset_disabled",Y="全局身份已停用";else if(!Z.supportedEfforts.includes(J))Q="effort_unsupported",Y=`该模型不支持 ${J} effort`;return{...Z,id:$.id,displayName:$.name,effort:J,origin:"preset",status:Q,...Y?{reason:Y}:{},role:$.role,instructions:[c2($.role),$.instructions].filter(Boolean).join(`
178
- `),baseIdentityId:$.baseIdentityId}}function _q(){if(!Yq(t2))return;try{let $=JSON.parse(Hq(t2,"utf8"));if(!$||$.version!==1||!Array.isArray($.presets))throw Error("invalid version or presets array");let Z=[];for(let J of $.presets){if(!J||typeof J!=="object")throw Error("invalid preset entry");if(typeof J.id!=="string"||!J.id.startsWith("preset:"))throw Error("invalid preset id");if(typeof J.name!=="string"||!J.name.trim())throw Error(`invalid preset name: ${J.id}`);if(typeof J.baseIdentityId!=="string"||!J.baseIdentityId)throw Error(`invalid base identity: ${J.id}`);if(!i1.includes(J.role))throw Error(`invalid role: ${J.id}`);Z.push({id:J.id,name:J.name,baseIdentityId:J.baseIdentityId,role:J.role,instructions:typeof J.instructions==="string"?J.instructions:void 0,effort:J.effort===void 0?void 0:typeof J.effort==="string"&&Vq.has(J.effort)?J.effort:(()=>{throw Error(`invalid effort: ${J.id}`)})(),enabled:J.enabled!==!1,createdAt:typeof J.createdAt==="string"?J.createdAt:new Date(0).toISOString(),updatedAt:typeof J.updatedAt==="string"?J.updatedAt:new Date(0).toISOString()})}O$={version:1,presets:Z}}catch($){L0=$ instanceof Error?$.message:String($),G(`consult identities: load failed: ${L0}`)}}function J5($){V$(t2,$)}function w9($){return JSON.parse(JSON.stringify($))}var O$,L0=null,Vq;var v9=E(()=>{D$();w();A$();h$();B9();B9();O$={version:1,presets:[]},Vq=new Set(["none","minimal","low","medium","high","xhigh","max","ultra"]);_q()});import{randomUUID as qq}from"node:crypto";async function zY($,Z){if(!Z.trim()){await N($.chatId,"❌ 无法确认操作者身份,未打开全局 reviewers 面板");return}DY();let J=`reviewers_${qq()}`;if(a1.set(J,{ownerOpenId:Z,page:0,createdAt:Date.now()}),!await c($.chatId,p2(J)))await N($.chatId,"❌ reviewers 面板发送失败")}function GY($,Z,J){let Q=z1($,J),Y=D0().identities.find((H)=>H.origin==="catalog"&&H.id===Z);if(!Y)return b0($,"底层模型身份已失效");if(Y.status!=="ready")return b0($,Y.reason??`身份不可用: ${Y.status}`);return Q.createdAt=Date.now(),{ok:!0,message:"请选择评审角色",card:E7({panelId:$,identity:Y})}}function KY($,Z,J,Q){if(z1($,Q),!i1.includes(J))return b0($,"无效评审角色");try{let Y=VY(Z,J,"max");return Q5($,`已创建全局身份:${Y.name}`)}catch(Y){return b0($,Y instanceof Error?Y.message:String(Y))}}function _Y($,Z,J){z1($,J);try{let Q=XY(Z);return Q5($,`${Q.name}已${Q.enabled?"启用":"停用"}`)}catch(Q){return b0($,Q instanceof Error?Q.message:String(Q))}}function qY($,Z,J){z1($,J);let Q=f9().find((Y)=>Y.id===Z);if(!Q)return b0($,"全局身份已不存在");return{ok:!0,message:"请确认删除",card:x7({panelId:$,preset:Q})}}function jY($,Z,J){z1($,J);try{return WY(Z),Q5($,"全局身份已删除")}catch(Q){return b0($,Q instanceof Error?Q.message:String(Q))}}function BY($,Z,J){let Q=z1($,J),Y=Bq(),H=Number(Z);if(!Number.isInteger(H))return b0($,"无效页码");return Q.page=Math.max(0,Math.min(Y-1,H)),Q.createdAt=Date.now(),{ok:!0,message:"已更新",card:p2($)}}function LY($,Z){return z1($,Z),{ok:!0,message:"已返回",card:p2($)}}function Q5($,Z){return{ok:!0,message:Z,card:p2($,{type:"success",content:`✅ ${Z}`})}}function b0($,Z){return{ok:!1,message:Z,card:a1.has($)?p2($,{type:"error",content:`❌ ${Z}`}):N0({title:"reviewers",message:Z,ok:!1})}}function p2($,Z){let J=a1.get($);if(!J)throw Error("评审身份面板已过期");let Q=D0(),Y=Q.identities.filter((W)=>W.origin==="catalog"),H=f9(),V=Math.max(1,Math.ceil(Y.length/W1),Math.ceil(H.length/W1));J.page=Math.min(J.page,V-1);let X=J.page*W1;return y7({panelId:$,page:J.page,totalPages:V,catalog:Y.slice(X,X+W1),presets:H.slice(X,X+W1),failures:Q.sourceFailures,presetFailure:Q.presetFailure,notice:Z})}function Bq(){let $=D0().identities.filter((Z)=>Z.origin==="catalog").length;return Math.max(1,Math.ceil($/W1),Math.ceil(f9().length/W1))}function z1($,Z){DY();let J=a1.get($);if(!J)throw Error("评审身份面板已过期,请重新发送 reviewers");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可修改全局身份");return J}function DY(){let $=Date.now()-jq;for(let[Z,J]of a1)if(J.createdAt<$)a1.delete(Z)}var W1=8,jq=1800000,a1;var PY=E(()=>{w$();n();v9();a1=new Map});var V5={};F1(V5,{withTasklistLifecycleLock:()=>c9,tasklistNameForProject:()=>I9,reconcileTasklistDeletions:()=>Aq,listTasklistBindings:()=>Fq,isTasklistAlreadyDeletedError:()=>FY,getTasklistBinding:()=>P0,enableTasklist:()=>Y5,deleteTasklistRemoteIdempotently:()=>AY,deleteTasklist:()=>H5});import{existsSync as Dq,readFileSync as Pq}from"node:fs";function I9($){return`${$}[lodestar]`}function P0($){let Z=e$.get($);return Z?G1(Z):null}function Fq(){return[...e$.values()].map(G1)}async function c9($,Z){let J=h9.get($)??Promise.resolve(),Q,Y=new Promise((V)=>{Q=V}),H=J.catch(()=>{}).then(()=>Y);h9.set($,H),await J.catch(()=>{});try{return await Z()}finally{if(Q(),h9.get($)===H)h9.delete($)}}function FY($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function AY($,Z=K8){try{return await Z($),"deleted"}catch(J){if(FY(J))return"already_deleted";throw J}}async function Y5($,Z){return await c9($,async()=>{let J=P0($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Q=I9($);if(Q.length>100)throw Error(`tasklist name is too long (${Q.length}/100): ${Q}`);let Y=await z8(Z),H=await G8(Q,Y),V={guid:H.guid,name:H.name,url:H.url,projectName:$,ownerOpenId:Y,createdAt:H.createdAt};return g9($,V),G1(V)})}async function H5($,Z){return await c9($,async()=>{let J=P0($);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},g9($,J);return await UY($,Z)})}async function UY($,Z){let J=P0($);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,g9($,J);try{if(await AY(Z)==="already_deleted")G(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Y=new Map(e$);return Y.delete($),MY(Y),e$.delete($),G1(J)}catch(Q){let Y=P0($);if(Y?.guid===Z&&Y.deleting)Y.deleting.lastError=Q instanceof Error?Q.message:String(Q),g9($,Y);throw Q}}async function Aq(){let $=[...e$.entries()].filter(([,J])=>!!J.deleting).map(([J,Q])=>({projectName:J,guid:Q.guid})),Z=[];for(let J of $)try{await c9(J.projectName,()=>UY(J.projectName,J.guid)),G(`tasklist: reconciled pending deletion for ${J.projectName}`)}catch(Q){Z.push(`${J.projectName}: ${Q instanceof Error?Q.message:String(Q)}`)}if(Z.length)throw Error(`tasklist deletion reconcile failed: ${Z.join("; ")}`)}function Uq(){if(!Dq(r2))return;try{let $=JSON.parse(Pq(r2,"utf8"));if(!$||typeof $!=="object")return;for(let[Z,J]of Object.entries($)){if(!J||typeof J!=="object")continue;let Q=J;if(typeof Q.guid!=="string"||!Q.guid||typeof Q.name!=="string"||!Q.name)continue;let Y={guid:Q.guid,name:Q.name,url:typeof Q.url==="string"?Q.url:"",projectName:Z,ownerOpenId:typeof Q.ownerOpenId==="string"?Q.ownerOpenId:"",createdAt:typeof Q.createdAt==="string"?Q.createdAt:void 0,deleting:Mq(Q.deleting)};e$.set(Z,Y)}G(`tasklist: loaded ${e$.size} project bindings`)}catch($){G(`tasklist: load map failed: ${$}`)}}function Mq($){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 g9($,Z){let J=new Map(e$);J.set($,G1(Z)),MY(J),e$.set($,G1(Z))}function MY($=e$){let Z={};for(let[J,Q]of $)Z[J]=G1(Q);V$(r2,Z)}function G1($){return JSON.parse(JSON.stringify($))}var e$,h9;var X5=E(()=>{D$();n();w();h$();e$=new Map,h9=new Map;Uq()});function S0($,Z,J=!1){let Q=$.worktreeProjectName();return k7({projectName:Q,tasklistName:I9(Q),binding:P0(Q),notice:Z,confirmDelete:J})}async function RY($){if(!await c($.chatId,S0($)))await N($.chatId,"❌ task 面板发送失败")}async function OY($){let Z=$.worktreeProjectName();try{let J=P0(Z),Q=await Y5(Z,$.chatId),Y=J?"已启用":`已启用 ${Q.name}`;return{ok:!0,message:Y,card:S0($,{type:"success",content:`✅ ${Y}`})}}catch(J){let Q=`启用失败: ${U(J)}`;return G(`session "${$.sessionName}": tasklist enable failed: ${U(J)}`),{ok:!1,message:Q,card:S0($,{type:"error",content:`❌ ${Q}`})}}}function TY($,Z){let J=$.worktreeProjectName(),Q=P0(J),Y=Z.trim();if(!Q)return{ok:!1,message:"未启用",card:S0($,{type:"error",content:"❌ 未启用"})};if(Q.guid!==Y)return{ok:!1,message:"清单绑定已变化",card:S0($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:S0($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function kY($,Z){let J=$.worktreeProjectName(),Q=Z.trim();try{let H=`已删除 ${(await H5(J,Q)).name}`;return{ok:!0,message:H,card:S0($,{type:"success",content:`✅ ${H}`})}}catch(Y){let H=`删除失败: ${U(Y)}`;return G(`session "${$.sessionName}": tasklist delete failed: ${U(Y)}`),{ok:!1,message:H,card:S0($,{type:"error",content:`❌ ${H}`})}}}var yY=E(()=>{w$();n();w();X5()});var EY,xY,NY,CY;var bY=E(()=>{EY=["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。","- 在回复任意位置,独占一行写 `[[send: /abs/path]]` 即可把该文件作为单独一条消息送出。只在用户主动要文件、或你要交付最终产物时才发。"],xY=["- 判断是否该发文件:导出附件/数据集、用户明确要文件或下载物时,应先写到本机绝对路径,再用独占一行的 `[[send: /abs/path]]` 发给用户;短总结、普通说明、无需留存的正文答复不要为了发文件而发文件。","- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会根据工具返回的本机图片路径自动发给用户。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"],NY=[...EY,"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",...xY].join(`
179
- `),CY=[...EY,"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问;不要输出 Codex 专属的 host-marker 文本协议。",...xY].join(`
180
- `)});import{execFileSync as Oq}from"node:child_process";import{existsSync as K1,readdirSync as Tq,readFileSync as kq,realpathSync as W5,statSync as yq}from"node:fs";import{dirname as Eq,join as wY,resolve as u9}from"node:path";async function p9($,Z){let J=W5($),Q=process.platform==="win32"?J.toLowerCase():J,Y=m9.get(Q)??Promise.resolve(),H,V=new Promise((W)=>{H=W}),X=Y.catch(()=>{}).then(()=>V);m9.set(Q,X),await Y.catch(()=>{});try{return await Z()}finally{if(H(),m9.get(Q)===X)m9.delete(Q)}}function _1($){let Z=$.trim();if(!xq.test(Z))return null;return Z}function fY($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function t1($,Z){return`${$}[${Z}]`}function vY($){return`${r1}${$}`}function s1($,Z,J){return wY(Eq($),t1(Z,J))}function hY($,Z,J){let Q=Nq($,Z,J);if(!Q)return null;let Y=kq(Q.path,"utf8").trim();if(!Y)return null;return{path:Q.path,content:Y,slug:Q.slug}}function gY($,Z){G5($);let J=B$($,["for-each-ref","--format=%(refname:short)",`refs/heads/${r1}`]).split(`
181
- `).map((H)=>H.trim()).filter(Boolean).filter((H)=>H.startsWith(r1)),Q=K5($),Y=[];for(let H of J){let V=H.slice(r1.length);if(!_1(V))continue;let X=t1(Z,V),W=s1($,Z,V),z=Q.get(H)??null,K=z??W,_=!!z&&K1(z),j=uY($,H,_),B={slug:V,chatName:X,branch:H,state:j,expectedPath:W,worktreePath:_?z:null,mounted:_,dirtyCount:null,statusLine:null,error:null};if(z&&K1(z))try{let P=B$(z,["status","--porcelain=v1","--branch"]).split(`
182
- `).filter(Boolean);B.statusLine=P[0]?.startsWith("## ")?P[0].slice(3):null,B.dirtyCount=P.filter((A)=>!A.startsWith("## ")).length}catch(L){B.error=_5(L)}Y.push(B)}return Y.sort((H,V)=>H.slug.localeCompare(V.slug))}function IY($,Z,J){let Q=_1(J);if(!Q)throw Error(`invalid worktree name "${J}"`);G5($);let Y=vY(Q),H=t1(Z,Q),V=s1($,Z,Q),X=wq($,Y),W=K5($).get(Y)??null,z=X&&!W&&uY($,Y,!1)==="merged"?B$($,["rev-parse","HEAD"]).trim():null;if(W){if(u9(W)!==u9(V))throw Error(`branch ${Y} is already mounted at ${W}`);return mY(V,Y),{slug:Q,chatName:H,branch:Y,worktreePath:V,createdBranch:!1,createdWorktree:!1}}if(K1(V)){if(!yq(V).isDirectory())throw Error(`${V} exists but is not a directory`);if(!X)throw Error(`${V} already exists while branch ${Y} does not`)}if(X){if(B$($,["worktree","add",V,Y]),z)B$(V,["rebase",z]);return{slug:Q,chatName:H,branch:Y,worktreePath:V,createdBranch:!1,createdWorktree:!0}}return B$($,["worktree","add","-b",Y,V,"HEAD"]),{slug:Q,chatName:H,branch:Y,worktreePath:V,createdBranch:!0,createdWorktree:!0}}function cY($,Z,J){let Q=z5($,Z,J);if(!K1(Q.worktreePath))return Q;return B$($,["worktree","remove",Q.worktreePath]),{...Q,removedWorktree:!0}}function z5($,Z,J){let Q=_1(J);if(!Q)throw Error(`invalid worktree name "${J}"`);G5($);let Y=vY(Q),H=t1(Z,Q),V=s1($,Z,Q),W=K5($).get(Y)??null??V;if(!K1(W))return{slug:Q,chatName:H,branch:Y,worktreePath:W,removedWorktree:!1};mY(W,Y);let z=B$(W,["status","--porcelain=v1"]).split(`
183
- `).filter(Boolean);if(z.length>0){let K=z.slice(0,8).join(`
180
+ `),baseIdentityId:$.baseIdentityId}}function Fq(){if(!Kq(t2))return;try{let $=JSON.parse(_q(t2,"utf8"));if(!$||$.version!==1||!Array.isArray($.presets))throw Error("invalid version or presets array");let Z=[];for(let J of $.presets){if(!J||typeof J!=="object")throw Error("invalid preset entry");if(typeof J.id!=="string"||!J.id.startsWith("preset:"))throw Error("invalid preset id");if(typeof J.name!=="string"||!J.name.trim())throw Error(`invalid preset name: ${J.id}`);if(typeof J.baseIdentityId!=="string"||!J.baseIdentityId)throw Error(`invalid base identity: ${J.id}`);if(!d1.includes(J.role))throw Error(`invalid role: ${J.id}`);Z.push({id:J.id,name:J.name,baseIdentityId:J.baseIdentityId,role:J.role,instructions:typeof J.instructions==="string"?J.instructions:void 0,effort:J.effort===void 0?void 0:typeof J.effort==="string"&&qq.has(J.effort)?J.effort:(()=>{throw Error(`invalid effort: ${J.id}`)})(),enabled:J.enabled!==!1,createdAt:typeof J.createdAt==="string"?J.createdAt:new Date(0).toISOString(),updatedAt:typeof J.updatedAt==="string"?J.updatedAt:new Date(0).toISOString()})}O$={version:1,presets:Z}}catch($){L0=$ instanceof Error?$.message:String($),z(`consult identities: load failed: ${L0}`)}}function Q3($){X$(t2,$)}function f9($){return JSON.parse(JSON.stringify($))}var O$,L0=null,qq;var h9=k(()=>{D$();w();P$();h$();j9();j9();O$={version:1,presets:[]},qq=new Set(["none","minimal","low","medium","high","xhigh","max","ultra"]);Fq()});import{randomUUID as Pq}from"node:crypto";async function _Y($,Z){if(!Z.trim()){await y($.chatId,"❌ 无法确认操作者身份,未打开全局 reviewers 面板");return}PY();let J=`reviewers_${Pq()}`;if(a1.set(J,{ownerOpenId:Z,page:0,createdAt:Date.now()}),!await c($.chatId,p2(J)))await y($.chatId,"❌ reviewers 面板发送失败")}function qY($,Z,J){let Q=G1($,J),Y=D0().identities.find((H)=>H.origin==="catalog"&&H.id===Z);if(!Y)return C0($,"底层模型身份已失效");if(Y.status!=="ready")return C0($,Y.reason??`身份不可用: ${Y.status}`);return Q.createdAt=Date.now(),{ok:!0,message:"请选择评审角色",card:x7({panelId:$,identity:Y})}}function BY($,Z,J,Q){if(G1($,Q),!d1.includes(J))return C0($,"无效评审角色");try{let Y=GY(Z,J,"max");return Y3($,`已创建全局身份:${Y.name}`)}catch(Y){return C0($,Y instanceof Error?Y.message:String(Y))}}function jY($,Z,J){G1($,J);try{let Q=zY(Z);return Y3($,`${Q.name}已${Q.enabled?"启用":"停用"}`)}catch(Q){return C0($,Q instanceof Error?Q.message:String(Q))}}function LY($,Z,J){G1($,J);let Q=v9().find((Y)=>Y.id===Z);if(!Q)return C0($,"全局身份已不存在");return{ok:!0,message:"请确认删除",card:y7({panelId:$,preset:Q})}}function DY($,Z,J){G1($,J);try{return KY(Z),Y3($,"全局身份已删除")}catch(Q){return C0($,Q instanceof Error?Q.message:String(Q))}}function AY($,Z,J){let Q=G1($,J),Y=Mq(),H=Number(Z);if(!Number.isInteger(H))return C0($,"无效页码");return Q.page=Math.max(0,Math.min(Y-1,H)),Q.createdAt=Date.now(),{ok:!0,message:"已更新",card:p2($)}}function FY($,Z){return G1($,Z),{ok:!0,message:"已返回",card:p2($)}}function Y3($,Z){return{ok:!0,message:Z,card:p2($,{type:"success",content:`✅ ${Z}`})}}function C0($,Z){return{ok:!1,message:Z,card:a1.has($)?p2($,{type:"error",content:`❌ ${Z}`}):x0({title:"reviewers",message:Z,ok:!1})}}function p2($,Z){let J=a1.get($);if(!J)throw Error("评审身份面板已过期");let Q=D0(),Y=Q.identities.filter((W)=>W.origin==="catalog"),H=v9(),X=Math.max(1,Math.ceil(Y.length/W1),Math.ceil(H.length/W1));J.page=Math.min(J.page,X-1);let V=J.page*W1;return k7({panelId:$,page:J.page,totalPages:X,catalog:Y.slice(V,V+W1),presets:H.slice(V,V+W1),failures:Q.sourceFailures,presetFailure:Q.presetFailure,notice:Z})}function Mq(){let $=D0().identities.filter((Z)=>Z.origin==="catalog").length;return Math.max(1,Math.ceil($/W1),Math.ceil(v9().length/W1))}function G1($,Z){PY();let J=a1.get($);if(!J)throw Error("评审身份面板已过期,请重新发送 reviewers");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可修改全局身份");return J}function PY(){let $=Date.now()-Uq;for(let[Z,J]of a1)if(J.createdAt<$)a1.delete(Z)}var W1=8,Uq=1800000,a1;var UY=k(()=>{w$();n();h9();a1=new Map});var V3={};F1(V3,{withTasklistLifecycleLock:()=>m9,tasklistNameForProject:()=>c9,reconcileTasklistDeletions:()=>Nq,listTasklistBindings:()=>Eq,isTasklistAlreadyDeletedError:()=>MY,getTasklistBinding:()=>A0,enableTasklist:()=>H3,deleteTasklistRemoteIdempotently:()=>RY,deleteTasklist:()=>X3});import{existsSync as Oq,readFileSync as Tq}from"node:fs";function c9($){return`${$}[lodestar]`}function A0($){let Z=e$.get($);return Z?z1(Z):null}function Eq(){return[...e$.values()].map(z1)}async function m9($,Z){let J=I9.get($)??Promise.resolve(),Q,Y=new Promise((X)=>{Q=X}),H=J.catch(()=>{}).then(()=>Y);I9.set($,H),await J.catch(()=>{});try{return await Z()}finally{if(Q(),I9.get($)===H)I9.delete($)}}function MY($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function RY($,Z=_6){try{return await Z($),"deleted"}catch(J){if(MY(J))return"already_deleted";throw J}}async function H3($,Z){return await m9($,async()=>{let J=A0($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Q=c9($);if(Q.length>100)throw Error(`tasklist name is too long (${Q.length}/100): ${Q}`);let Y=await z6(Z),H=await K6(Q,Y),X={guid:H.guid,name:H.name,url:H.url,projectName:$,ownerOpenId:Y,createdAt:H.createdAt};return g9($,X),z1(X)})}async function X3($,Z){return await m9($,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},g9($,J);return await OY($,Z)})}async function OY($,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,g9($,J);try{if(await RY(Z)==="already_deleted")z(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Y=new Map(e$);return Y.delete($),TY(Y),e$.delete($),z1(J)}catch(Q){let Y=A0($);if(Y?.guid===Z&&Y.deleting)Y.deleting.lastError=Q instanceof Error?Q.message:String(Q),g9($,Y);throw Q}}async function Nq(){let $=[...e$.entries()].filter(([,J])=>!!J.deleting).map(([J,Q])=>({projectName:J,guid:Q.guid})),Z=[];for(let J of $)try{await m9(J.projectName,()=>OY(J.projectName,J.guid)),z(`tasklist: reconciled pending deletion for ${J.projectName}`)}catch(Q){Z.push(`${J.projectName}: ${Q instanceof Error?Q.message:String(Q)}`)}if(Z.length)throw Error(`tasklist deletion reconcile failed: ${Z.join("; ")}`)}function kq(){if(!Oq(r2))return;try{let $=JSON.parse(Tq(r2,"utf8"));if(!$||typeof $!=="object")return;for(let[Z,J]of Object.entries($)){if(!J||typeof J!=="object")continue;let Q=J;if(typeof Q.guid!=="string"||!Q.guid||typeof Q.name!=="string"||!Q.name)continue;let Y={guid:Q.guid,name:Q.name,url:typeof Q.url==="string"?Q.url:"",projectName:Z,ownerOpenId:typeof Q.ownerOpenId==="string"?Q.ownerOpenId:"",createdAt:typeof Q.createdAt==="string"?Q.createdAt:void 0,deleting:xq(Q.deleting)};e$.set(Z,Y)}z(`tasklist: loaded ${e$.size} project bindings`)}catch($){z(`tasklist: load map failed: ${$}`)}}function xq($){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 g9($,Z){let J=new Map(e$);J.set($,z1(Z)),TY(J),e$.set($,z1(Z))}function TY($=e$){let Z={};for(let[J,Q]of $)Z[J]=z1(Q);X$(r2,Z)}function z1($){return JSON.parse(JSON.stringify($))}var e$,I9;var W3=k(()=>{D$();n();w();h$();e$=new Map,I9=new Map;kq()});function S0($,Z,J=!1){let Q=$.worktreeProjectName();return N7({projectName:Q,tasklistName:c9(Q),binding:A0(Q),notice:Z,confirmDelete:J})}async function EY($){if(!await c($.chatId,S0($)))await y($.chatId,"❌ task 面板发送失败")}async function NY($){let Z=$.worktreeProjectName();try{let J=A0(Z),Q=await H3(Z,$.chatId),Y=J?"已启用":`已启用 ${Q.name}`;return{ok:!0,message:Y,card:S0($,{type:"success",content:`✅ ${Y}`})}}catch(J){let Q=`启用失败: ${U(J)}`;return z(`session "${$.sessionName}": tasklist enable failed: ${U(J)}`),{ok:!1,message:Q,card:S0($,{type:"error",content:`❌ ${Q}`})}}}function kY($,Z){let J=$.worktreeProjectName(),Q=A0(J),Y=Z.trim();if(!Q)return{ok:!1,message:"未启用",card:S0($,{type:"error",content:"❌ 未启用"})};if(Q.guid!==Y)return{ok:!1,message:"清单绑定已变化",card:S0($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:S0($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function xY($,Z){let J=$.worktreeProjectName(),Q=Z.trim();try{let H=`已删除 ${(await X3(J,Q)).name}`;return{ok:!0,message:H,card:S0($,{type:"success",content:`✅ ${H}`})}}catch(Y){let H=`删除失败: ${U(Y)}`;return z(`session "${$.sessionName}": tasklist delete failed: ${U(Y)}`),{ok:!1,message:H,card:S0($,{type:"error",content:`❌ ${H}`})}}}var yY=k(()=>{w$();n();w();W3()});var CY,SY,bY,wY;var fY=k(()=>{CY=["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。","- 在回复任意位置,独占一行写 `[[send: /abs/path]]` 即可把该文件作为单独一条消息送出。只在用户主动要文件、或你要交付最终产物时才发。"],SY=["- 判断是否该发文件:导出附件/数据集、用户明确要文件或下载物时,应先写到本机绝对路径,再用独占一行的 `[[send: /abs/path]]` 发给用户;短总结、普通说明、无需留存的正文答复不要为了发文件而发文件。","- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会根据工具返回的本机图片路径自动发给用户。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"],bY=[...CY,"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",...SY].join(`
181
+ `),wY=[...CY,"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问;不要输出 Codex 专属的 host-marker 文本协议。",...SY].join(`
182
+ `)});import{execFileSync as Cq}from"node:child_process";import{existsSync as K1,readdirSync as Sq,readFileSync as bq,realpathSync as G3,statSync as wq}from"node:fs";import{dirname as fq,join as hY,resolve as p9}from"node:path";async function l9($,Z){let J=G3($),Q=process.platform==="win32"?J.toLowerCase():J,Y=u9.get(Q)??Promise.resolve(),H,X=new Promise((W)=>{H=W}),V=Y.catch(()=>{}).then(()=>X);u9.set(Q,V),await Y.catch(()=>{});try{return await Z()}finally{if(H(),u9.get(Q)===V)u9.delete(Q)}}function _1($){let Z=$.trim();if(!vq.test(Z))return null;return Z}function IY($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function t1($,Z){return`${$}[${Z}]`}function gY($){return`${r1}${$}`}function s1($,Z,J){return hY(fq($),t1(Z,J))}function cY($,Z,J){let Q=hq($,Z,J);if(!Q)return null;let Y=bq(Q.path,"utf8").trim();if(!Y)return null;return{path:Q.path,content:Y,slug:Q.slug}}function mY($,Z){K3($);let J=j$($,["for-each-ref","--format=%(refname:short)",`refs/heads/${r1}`]).split(`
183
+ `).map((H)=>H.trim()).filter(Boolean).filter((H)=>H.startsWith(r1)),Q=_3($),Y=[];for(let H of J){let X=H.slice(r1.length);if(!_1(X))continue;let V=t1(Z,X),W=s1($,Z,X),G=Q.get(H)??null,K=G??W,_=!!G&&K1(G),B=dY($,H,_),j={slug:X,chatName:V,branch:H,state:B,expectedPath:W,worktreePath:_?G:null,mounted:_,dirtyCount:null,statusLine:null,error:null};if(G&&K1(G))try{let A=j$(G,["status","--porcelain=v1","--branch"]).split(`
184
+ `).filter(Boolean);j.statusLine=A[0]?.startsWith("## ")?A[0].slice(3):null,j.dirtyCount=A.filter((P)=>!P.startsWith("## ")).length}catch(L){j.error=q3(L)}Y.push(j)}return Y.sort((H,X)=>H.slug.localeCompare(X.slug))}function uY($,Z,J){let Q=_1(J);if(!Q)throw Error(`invalid worktree name "${J}"`);K3($);let Y=gY(Q),H=t1(Z,Q),X=s1($,Z,Q),V=mq($,Y),W=_3($).get(Y)??null,G=V&&!W&&dY($,Y,!1)==="merged"?j$($,["rev-parse","HEAD"]).trim():null;if(W){if(p9(W)!==p9(X))throw Error(`branch ${Y} is already mounted at ${W}`);return lY(X,Y),{slug:Q,chatName:H,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!1}}if(K1(X)){if(!wq(X).isDirectory())throw Error(`${X} exists but is not a directory`);if(!V)throw Error(`${X} already exists while branch ${Y} does not`)}if(V){if(j$($,["worktree","add",X,Y]),G)j$(X,["rebase",G]);return{slug:Q,chatName:H,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!0}}return j$($,["worktree","add","-b",Y,X,"HEAD"]),{slug:Q,chatName:H,branch:Y,worktreePath:X,createdBranch:!0,createdWorktree:!0}}function pY($,Z,J){let Q=z3($,Z,J);if(!K1(Q.worktreePath))return Q;return j$($,["worktree","remove",Q.worktreePath]),{...Q,removedWorktree:!0}}function z3($,Z,J){let Q=_1(J);if(!Q)throw Error(`invalid worktree name "${J}"`);K3($);let Y=gY(Q),H=t1(Z,Q),X=s1($,Z,Q),W=_3($).get(Y)??null??X;if(!K1(W))return{slug:Q,chatName:H,branch:Y,worktreePath:W,removedWorktree:!1};lY(W,Y);let G=j$(W,["status","--porcelain=v1"]).split(`
185
+ `).filter(Boolean);if(G.length>0){let K=G.slice(0,8).join(`
184
186
  `);throw Error(`worktree has uncommitted changes:
185
- ${K}`)}return{slug:Q,chatName:H,branch:Y,worktreePath:W,removedWorktree:!1}}function G5($){if(!K1($))throw Error(`project directory does not exist: ${$}`);let Z=B$($,["rev-parse","--show-toplevel"]).trim();if(W5(Z)!==W5($))throw Error(`${$} is not the git repository root (${Z})`)}function mY($,Z){let J=B$($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function Nq($,Z,J){let Q=Cq($);if(!Q?.startsWith(r1))return null;let Y=Q.slice(r1.length);if(!_1(Y))throw Error(`invalid worktree branch "${Q}"`);let H=s1(Z,J,Y);if(u9($)!==u9(H))return null;let V=Sq($,bq(Y));return V?{path:V,slug:Y}:null}function Cq($){if(!K1($))return null;try{return B$($,["branch","--show-current"]).trim()||null}catch(Z){if(fq(Z))return null;throw Z}}function bq($){return $.split("-",1)[0]??$}function Sq($,Z){let J=`agents.${Z}.md`,Q=Tq($).filter((Y)=>Y.toLowerCase()===J).sort();if(Q.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Q.join(", ")}`);return Q[0]?wY($,Q[0]):null}function wq($,Z){try{return B$($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function uY($,Z,J){let Q=B$($,["rev-parse",Z]).trim(),Y=B$($,["rev-parse","HEAD"]).trim();if(Q===Y)return J?"active":"merged";if(SY($,Z,"HEAD"))return"merged";if(SY($,"HEAD",Z))return"active";return"stale"}function SY($,Z,J){try{return B$($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function K5($){let Z=new Map,J=B$($,["worktree","list","--porcelain"]),Q="";for(let Y of J.split(`
186
- `)){if(Y.startsWith("worktree ")){Q=Y.slice(9);continue}if(Y.startsWith("branch refs/heads/")&&Q)Z.set(Y.slice(18),Q)}return Z}function B$($,Z){try{return Oq("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(_5(J))}}function _5($){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 fq($){return/not a git repository/i.test(_5($))}var r1="work/",xq,m9;var pY=E(()=>{xq=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,m9=new Map});function w0($){return fY(a$($.sessionName)??$.sessionName)}function e1($){return b4(w0($))}function iY($){let Z=a$($.sessionName)??$.sessionName,J=w0($),Q=b4(J);if(J===Z)return Q;let Y=Z.slice(J.length+1,-1);return s1(Q,J,Y)}function dY($){let Z=$.currentProvider()==="claude"?CY:NY,J=l9($);return J?`${Z}
187
- ${J}`:Z}function q5($){return l9($)?"已载入wt特殊约定":null}function nY($,Z){let J=q5($);return J?`${Z}
188
- ${J}`:Z}function l9($){let Z=w0($),J=hY($.workDir,e1($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
189
- `)}async function oY($,Z,J){if(!Z){await j5($);return}let Q=_1(Z);if(!Q){await O($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await O($.chatId,"❌ 找不到发起人,不能拉群。");return}let Y=w0($),H=e1($);try{await p9(H,async()=>{let V;try{V=IY(H,Y,Q)}catch(X){await O($.chatId,`❌ wt 失败: ${U(X)}`);return}try{let X=await S8(V.chatName,J),W=X.created?"已创建":X.joined?"已加入":"已在群内";if(!await c($.chatId,I2({slug:Q,branch:V.branch,status:W})))await N($.chatId,`❌ wt 卡片失败: ${Q}`);if(!await c(X.chatId,I2({slug:Q,branch:V.branch,status:"就绪",body:"开始吧。"})))await N(X.chatId,`❌ wt 卡片失败: ${Q}`)}catch(X){await O($.chatId,`❌ wt 已建,拉群失败: ${U(X)}`)}})}catch(V){await O($.chatId,`❌ wt 失败: ${U(V)}`)}}async function aY($,Z){let J=w0($),Q=e1($);return await p9(Q,async()=>{return await hq($,J,Q,Z)})}async function hq($,Z,J,Q){let Y=gY(J,Z),H=Y.filter((W)=>W.state==="merged"&&!W.mounted).length,V=Y.filter((W)=>W.state!=="merged"||W.mounted),X=await w4();return D7({projectName:Z,projectDir:J,hiddenMergedUnmountedCount:H,notice:Q,entries:V.map((W)=>{let z=X.get(W.chatName)??[],K=Q$.get(W.chatName),_=K&&z.includes(K)?K:z.length===1?z[0]:null;return{slug:W.slug,chatName:W.chatName,branch:W.branch,state:W.state,path:W.worktreePath??W.expectedPath,mounted:W.mounted,dirtyCount:W.dirtyCount,statusLine:W.statusLine,error:W.error,chatId:_,duplicateChatCount:z.length}})})}async function j5($){try{let Z=await aY($);if(!await c($.chatId,Z))await N($.chatId,"❌ wt 列表失败")}catch(Z){await O($.chatId,`❌ wt 列表失败: ${U(Z)}`)}}async function lY($,Z,J,Q){try{return{ok:Z,message:J,card:await aY($,{type:Q,content:J})}}catch(Y){let H=`列表刷新失败: ${U(Y)}`;return G(`session "${$.sessionName}": wt action panel refresh failed: ${U(Y)}`),{ok:!1,message:`${J}
190
- ${H}`,card:I2({slug:"wt",branch:"work/*",status:J,body:H,template:"red"})}}}async function rY($,Z){let J=_1(Z);if(!J)return lY($,!1,"❌ 名称无效","error");let Q=w0($),Y=e1($),H;try{H=await p9(Y,async()=>{let V=t1(Q,J);if($.hasRunningPeerSession(V))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${V} 群里 stop 或 kill。`,type:"error"};z5(Y,Q,J);let X=await f8(V),W=cY(Y,Q,J);return{ok:!0,message:[`✅ ${J} 已解散`,W.removedWorktree?"dir removed":"dir missing",X.disbanded?"group removed":"group missing",W.branch].join(`
191
- `),type:"success"}})}catch(V){H={ok:!1,message:`❌ 解散 ${J} 失败: ${U(V)}`,type:"error"}}return lY($,H.ok,H.message,H.type)}var tY=E(()=>{bY();w$();n();w();pY()});import{closeSync as Iq,openSync as cq,readSync as mq,readdirSync as uq,statSync as pq}from"node:fs";import{randomUUID as L5}from"node:crypto";import{join as lq}from"node:path";function d9($){return a$($.sessionName)??$.sessionName}function eY($){let Z=k8($,B5);return B5.add(Z),Z}function $H($){B5.delete($)}function $2($){let Z=sY.get($);if(!Z)Z=new Map,sY.set($,Z);let J=Date.now();for(let[Q,Y]of Z){let H=Y.status==="consumed"?nq:dq,V=Y.consumedAt??Y.createdAt;if(J-V>H)Z.delete(Q)}return Z}function aq($,Z){return $.provider===Z.provider&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function ZH($,Z,J,Q){let Y={id:L5(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:d9($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Q};return $2($).set(Y.id,Y),Y}function D5($,Z,J,Q,Y){let H=$2($).get(J);if(!H||H.mode!==Z)return{error:"这张选择卡已过期,请重新发送命令"};if(!Y||H.requesterOpenId!==Y)return{error:"只有打开这张选择卡的用户可以执行;请自行发送命令重新打开"};if(H.status!=="open")return{error:"这张选择卡已执行或正在处理,请勿重复点击"};if(H.provider!==$.selectedProvider||H.workDir!==$.workDir||H.sourceSessionId!==$.lastSessionId||!aq(H.routing,$.conversationRouting()))return{error:"这张卡对应的 provider、目录或源会话已经变化,请重新发送命令"};let V=H.choices.get(Q);if(!V)return{error:"无效的选择项,这张卡可能已过期"};return H.status="processing",{panel:H,choice:V}}function i9($){$.status="consumed",$.consumedAt=Date.now()}function rq($){return{kind:"fork",source:$.source,through:$}}function tq($){return v1($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function sq($){let Z=U2($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return G$(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function eq($){let Z=X8($),J;try{J=uq(Z)}catch(Y){if(Y?.code==="ENOENT")return[];throw Error(`读取 Claude 会话目录失败: ${Y?.message??Y}`)}let Q=[];for(let Y of J){if(!Y.endsWith(".jsonl"))continue;let H=lq(Z,Y),V;try{V=pq(H).mtimeMs}catch(X){throw Error(`读取 Claude 会话元数据失败 (${Y}): ${X?.message??X}`)}Q.push({provider:"claude",sessionId:Y.slice(0,-6),cwd:$,preview:Zj(H),ts:V})}return Q.sort((Y,H)=>H.ts-Y.ts)}function $j($){let Z=$.slice().sort((Y,H)=>H.ts-Y.ts),J=Date.now()-iq,Q=Z.filter((Y)=>Y.ts>=J).length;return Z.slice(0,Math.min(oq,Math.max(10,Q)))}function Zj($){let Z="",J=null;try{J=cq($,"r");let Y=Buffer.alloc(65536),H=mq(J,Y,0,65536,0);Z=Y.subarray(0,H).toString("utf8")}catch(Y){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Y?.message??Y}`)}finally{if(J!==null)Iq(J)}let Q="";for(let Y of Z.split(`
192
- `)){let H=Y.trim();if(!H)continue;let V;try{V=JSON.parse(H)}catch{continue}if(V.type==="queue-operation"&&V.operation==="enqueue"&&typeof V.content==="string"){let X=V.content.trim();if(X)return X.slice(0,80)}if(!Q&&V.type==="user"&&V.message){let X=Jj(V.message);if(X)Q=X}}return Q.slice(0,80)}function Jj($){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 JH($,Z,J){if(!J){await O($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Q=tq($),Y=sq($),H=new Map,V=[];for(let K=0;K<Q.length;K++){let _=Q[K];if(K===0&&Y===null)continue;let j=L5(),B=K===0?Y:rq(Q[K-1].checkpoint);H.set(j,{kind:Z,launch:B,branchBase:Y,seedAnchors:Q.slice(0,K),writes:Q.slice(K).flatMap((L)=>L.writes)}),V.push({choiceId:j,preview:_.preview,ts:_.ts})}V.reverse();let X=ZH($,Z,J,H),W=F7({projectName:d9($),panelId:X.id,mode:Z,entries:V}),z;try{z=await c($.chatId,W)}catch(K){throw $2($).delete(X.id),K}if(!z)$2($).delete(X.id),await N($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function QH($,Z){return JH($,"fork",Z)}function YH($,Z){return JH($,"back",Z)}async function HH($,Z){if(!Z){await O($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():eq($.workDir)}catch(W){await N($.chatId,`❌ 历史会话读取失败: ${W instanceof Error?W.message:W}`);return}let Q=new Map,Y=$j(J).map((W)=>{let z=L5();return Q.set(z,{kind:"resume",launch:{kind:"fork",source:{provider:W.provider,sessionId:W.sessionId,cwd:W.cwd}},sourcePreview:W.preview,sourceTs:W.ts,sourceStatus:W.status}),{choiceId:z,preview:W.preview,ts:W.ts}}),H=ZH($,"resume",Z,Q),V=A7({projectName:d9($),panelId:H.id,entries:Y}),X;try{X=await c($.chatId,V)}catch(W){throw $2($).delete(H.id),W}if(!X)$2($).delete(H.id),await N($.chatId,"❌ rs 历史列表发送失败")}async function VH($,Z){if(!Z){await O($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await O($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=eY(d9($));await O($.chatId,`\uD83D\uDE80 正在创建 ${J} · ${$.backendLabel()} 新会话。它与当前群共享工作目录;当前会话不受影响。`);let Q;try{Q=await $.opts.onCreateTempSession({chatName:J,userOpenId:Z,workDir:$.workDir,routing:$.conversationRouting(),launch:{kind:"fresh"},branchBase:{kind:"fresh"},seedAnchors:[]})}finally{$H(J)}if(!Q.ok){await O($.chatId,`❌ 建临时会话失败: ${Q.error??"未知"}`);return}await O($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function XH($){if(!a$($.sessionName)){await O($.chatId,"❌ bye 只能在带 *MMDD-HHMM 后缀的临时会话群里使用。");return}if(!$.opts.onDisbandTempSession){await O($.chatId,"❌ 解散能力未就绪(daemon 未注入回调)。");return}await O($.chatId,`\uD83D\uDC4B 正在停止会话并解散 ${$.sessionName}…`);let Z=await $.opts.onDisbandTempSession($.sessionName,$.chatId);if(!Z.ok)await O($.chatId,`❌ 解散失败: ${Z.error??"未知"}`)}async function WH($,Z,J,Q){let Y=D5($,"fork",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:H,choice:V}=Y;try{if(V.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let X=eY(H.baseName);G(`session-temp: fork ${$.sessionName} → ${X} (${V.launch.kind})`),await O($.chatId,`\uD83D\uDD31 正在分叉到 ${X}…`);let W;try{W=await $.opts.onCreateTempSession({chatName:X,userOpenId:Q,workDir:H.workDir,routing:H.routing,launch:V.launch,branchBase:V.branchBase,seedAnchors:V.seedAnchors})}finally{$H(X)}if(!W.ok)return{ok:!1,message:`分叉失败: ${W.error??"未知"}`};return{ok:!0,message:`已分叉到 ${X};原会话和磁盘文件未回滚`}}catch(X){return{ok:!1,message:`分叉失败: ${X instanceof Error?X.message:X}`}}finally{i9(H)}}async function zH($,Z,J,Q){let Y=D5($,"back",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:H,choice:V}=Y;try{if(V.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let X="";try{if(!await c($.chatId,U7({projectName:H.baseName,entries:V.writes})))X=";文件变更记录卡发送失败"}catch(K){X=`;文件变更记录卡发送失败: ${K instanceof Error?K.message:K}`}if(G(`session-temp: back ${$.sessionName} (${V.launch.kind}, writes=${V.writes.length})`),!await $.rollbackTo(V.launch,{anchors:V.seedAnchors,base:V.branchBase}))return{ok:!1,message:`回退失败;原会话绑定未改,请检查日志后重试${X}`};if(H.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${X}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${z$($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${X}`}}catch(X){return{ok:!1,message:`回退失败: ${X instanceof Error?X.message:X}`}}finally{i9(H)}}async function GH($,Z,J,Q){let Y=D5($,"resume",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:H,choice:V}=Y;if(V.kind!=="resume")throw i9(H),Error("resume panel contained a non-resume choice");let X=V.launch.source.sessionId,W=$.lastSessionId,z=(_,j)=>({projectName:H.baseName,provider:V.launch.source.provider,selectedPreview:V.sourcePreview,selectedTs:V.sourceTs,sourceSessionId:X,...V.sourceStatus?{sourceStatus:V.sourceStatus}:{},previousSessionId:W,newSessionId:_,bindingState:j}),K=(_,j,B,L=null)=>({ok:_,message:j,resumePresentation:z(L,B)});try{if($.isRunning())return K(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(V.sourceStatus==="active")return K(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(G(`session-temp: history fork ${$.sessionName} ← ${V.launch.source.provider} ${X}`),!await $.rollbackTo(V.launch,{anchors:[],base:V.launch,pendingLaunch:V.launch.source.provider==="claude"?{launch:V.launch,previousSessionId:W}:null}))return K(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(V.launch.source.provider==="claude")return K(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let j=$.lastSessionId;if(!j)return K(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(j===X||W&&j===W)return K(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",j);return K(!0,"已创建并接入独立分支;源会话未修改","changed",j)}catch(_){return K(!1,`历史分支创建失败: ${_ instanceof Error?_.message:_}`,"unknown")}finally{i9(H)}}var iq=86400000,dq=1800000,nq=3600000,oq=40,sY,B5;var KH=E(()=>{n();w$();w();O4();T1();sY=new WeakMap,B5=new Set});import{existsSync as _H}from"node:fs";import{randomBytes as Yj,timingSafeEqual as Hj}from"node:crypto";import{isAbsolute as Vj}from"node:path";function F5($,Z=new Set){if($ instanceof j4)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Q=F5(J,Z);if(Q)return Q}if($ instanceof Error&&$.cause!==void 0)return F5($.cause,Z);return null}function Xj($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function Wj($){return $.itemId||$.turnId||"__latest__"}function qH($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function zj($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function Gj($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function q1(){return S.runtime?.live_elapsed??"bucket"}function BH($,Z){return`${$} (${R0(Date.now()-Z,q1()).label})`}var Kj="Thinking...",_j="Writing...",qj="Working...",P5=1e4,n9=120000,jj=50,l2=5,Bj=256,o9=1e4,jH=250,j1;var LH=E(()=>{k1();a6();c0();y$();A$();u3();O4();t0();w$();n();w();D$();z7();T9();y9();I7();XQ();AQ();OQ();a7();CQ();nQ();aQ();YY();PY();yY();tY();KH();T1();j1=class j1{sessionName;chatId;opts;static all=new Set;proc=null;lifecycleTail=Promise.resolve();lifecycleSequence=0;procEpoch=0;stoppingProc=null;blockedProc=null;blockedProcReason=null;consultCapability=null;procSourceRevisions=new WeakMap;currentTurn=null;contextCompactionReceipts=new Map;contextCompactionOwnerIds=new WeakMap;contextCompactionOwnerSequence=0;lastManualContextCompactionCompletedAt=0;lastManualContextCompactionWasAnonymous=!1;backgroundTasks=[];pendingBgTasks=[];backgroundCard=null;settlingBackgroundCard=!1;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;j1.all.add(this);let Q=N8($);this.selectedProvider=Q?.provider??"claude",this.selectedModel=Q?.model??null,this.selectedEffort=Q?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Q);let Y=Z$(this.selectedTokenSourceId);if(Y){if(this.selectedProvider=Y.agent,Y.id==="glm"&&this.selectedModel==="claude:glm")this.selectedModel=Y.defaultModel,this.selectedEffort="max";if(Y.id==="claude-native"&&this.selectedModel&&!Y.models.some((V)=>V.model===this.selectedModel))this.selectedModel=Y.defaultModel}if(this.selectedModel)G(`session "${$}": restored selected provider=${this.selectedProvider} model=${this.selectedModel} effort=${this.selectedEffort??"unset"}`);if(this.lastSessionRef=o0($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)G(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let H=M2($);if(H)if(this.selectedProvider!=="claude")C$($,[],null,null),G(`session "${$}": cleared pending Claude fork after provider changed`);else{G$(H.launch,"claude",this.workDir);let V=this.lastSessionId===H.previousSessionId,X=this.lastSessionRef,W=!V&&X?.provider==="claude"&&X.cwd===this.workDir&&X.sessionId!==H.launch.source.sessionId&&X.sessionId!==H.previousSessionId;if(!V&&!W)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=H,G(`session "${$}": restored ${W?"materialized":"pending"} Claude fork source=${H.launch.source.sessionId}`)}}peerSnapshot(){return{name:this.sessionName,status:this.status,uptimeMs:this.startedAt?Date.now()-this.startedAt:void 0}}get workDir(){return iY(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 P4(J==="codex"?"codex":"claude")[0]?.id??null}currentTokenSource(){return Z$(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=Z$($.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=o0(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,x8(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,Q=new I0({workDir:this.workDir,launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J}),Y=null,H=null;try{Y=await Q.listConversations()}catch(X){H=X}let V=null;try{await Q.kill(2000)}catch(X){V=X}if(H&&V)throw AggregateError([H,V],`Codex history query and cleanup failed: ${U(H)}; ${U(V)}`);if(H)throw H;if(V)throw V;return Y??[]}async resolveLegacyResumeRef($){if($.cwd!==null)return $;if($.provider!==this.selectedProvider)throw Error(`legacy resume provider mismatch: ${$.provider} != ${this.selectedProvider}`);let Z;if($.provider==="claude"){let J=W8(this.workDir,$.sessionId);if(!_H(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${z$($.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 Q=J?.enabled?J:void 0,Y=new I0({workDir:this.workDir,launch:{kind:"fresh"},tokenSourceId:Q?.id??null,transformEnv:Q?(X)=>Q.spawnEnv(X):void 0}),H=null;try{Z=await Y.readConversationRef($.sessionId)}catch(X){H=X,Z=$}let V=null;try{await Y.kill(2000)}catch(X){V=X}if(H&&V)throw AggregateError([H,V],`Codex legacy resume lookup and cleanup failed: read=${U(H)}; cleanup=${U(V)}`);if(H)throw H;if(V)throw V}return G$({kind:"resume",source:Z},this.selectedProvider,this.workDir),A2(this.sessionName,Z),Z}hasRunningPeerSession($){return[...j1.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 E$(this.selectedEffort)?this.selectedEffort:W2}return W2}claudeEffortForSpawn(){return this.selectedProvider==="claude"&&o$(this.selectedEffort)?this.selectedEffort:O0}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"?O0:W2)}runtimeModelSelection(){let $=this.proc?.isAlive()?this.proc:null,Z=$?.provider??this.selectedProvider,J=!$||$.provider===this.selectedProvider,Q=($?.lastModel??(J?this.currentModelLabel():null))?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null,Y=$?.lastEffort??(J?this.currentEffortLabel():Z==="claude"?O0:W2);return{provider:Z,model:Q,effort:Y}}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"?`${H0($.provider)} · ${J}`:J}withModel($,Z){let J=this.modelEffortLabel(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return d($,M.footer,this.footerElement(Z))}footerElement($){return{tag:"markdown",element_id:M.footer,content:$.trim()||" "}}modelLine($){return this.modelEffortLabel($)}backendLabel($=this.selectedProvider){return H0($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(G$($.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.consultCapability=Yj(32).toString("base64url");let Z={LODESTAR_CONSULT_URL:Xj(S.notify.bind,S.notify.port),LODESTAR_CONSULT_CAPABILITY:this.consultCapability,LODESTAR_CONSULT_SESSION:this.sessionName},J=this.pendingConversationLaunch??this.pendingMaterializationLaunch()??($?{kind:"resume",source:$}:{kind:"fresh"});G$(J,this.selectedProvider,this.workDir);let Q=this.currentTokenSource();if(this.selectedTokenSourceId&&(!Q||!Q.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或在 model 面板选择其他账号`);let Y=Q?.enabled?Q:void 0,H=Y?(W)=>Y.spawnEnv(W):void 0,V=Y?Y.resolveSpawnModel(this.selectedModel??Y.defaultModel):this.modelForSpawn();if(this.selectedProvider==="claude"){HZ();let W=J.kind==="fresh"?void 0:J.source.sessionId,z=J.kind==="fork"?J.through:void 0;if(z&&(z.provider!=="claude"||z.kind!=="assistant-message"))throw Error(`Claude cannot fork from ${z.provider}/${z.kind} checkpoint`);let K=new D2({workDir:this.workDir,model:V,effort:this.claudeEffortForSpawn(),resumeSessionId:W,resumeSessionAt:z?.id,forkSession:J.kind==="fork",appendSystemPrompt:this.spawnDeveloperInstructions(),profile:C4(this.worktreeProjectName()),...Y?.settingSources?{settingSources:Y.settingSources}:{},...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:e2},tokenSourceId:Y?.id??null,transformEnv:H,hostEnv:Z});return this.procSourceRevisions.set(K,Y?.spawnRevision??null),K}let X=new I0({workDir:this.workDir,model:V,effort:this.effortForSpawn(),launch:J,appendSystemPrompt:this.spawnDeveloperInstructions(),tokenSourceId:Y?.id??null,transformEnv:H,hostEnv:Z});return this.procSourceRevisions.set(X,Y?.spawnRevision??null),X}async applyModelSelection($,Z,J,Q){await this.runLifecycle("apply-model-selection",()=>this.applyModelSelectionUnlocked($,Z,J,Q))}async applyModelSelectionUnlocked($,Z,J,Q){if(this.selectedProvider!==$)C$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=Q??this.selectedTokenSourceId;let H=Z$(this.selectedTokenSourceId);if(H)this.selectedModel=Z||null,this.selectedEffort=J??H.models.find((V)=>V.model===Z)?.defaultEffort??H.models[0]?.defaultEffort??null;else this.selectedModel=$==="codex"?null:Z,this.selectedEffort=$==="codex"?null:J;this.lastSessionRef=o0(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 Q=await this.settleProcResumableState(J),Y=null;try{await J.kill(1000)}catch(X){Y=X}Q=await this.settleProcResumableState(J);let H=this.finishProcStop(J,Y);this.opts.onLifecycleChange?.();let V=[...!H?[Y??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...Q?[Error(Q)]:[]];if(V.length===1)throw V[0];if(V.length>1)throw AggregateError(V,`idle process stop failed: ${V.map(U).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),Q=null;try{await Z.kill(1000)}catch(V){Q=V}J=await this.settleProcResumableState(Z);let Y=this.finishProcStop(Z,Q);this.opts.onLifecycleChange?.();let H=[...!Y?[Q??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...J?[Error(J)]:[]];if(H.length===1)throw H[0];if(H.length>1)throw AggregateError(H,`idle process stop failed: ${H.map(U).join("; ")}`);return!0}startFooterTimer($,Z,J=(Q)=>Q){let Q=Date.now(),Y=Z,H=!1,V=()=>{if(H)return;this.replaceFooterContent($,J(BH(Y,Q)))},X=null,W=()=>{if(H)return;let{nextDelayMs:z}=R0(Date.now()-Q,q1());X=setTimeout(()=>{V(),W()},Math.max(1,Math.ceil(z)))};return V(),W(),{setStatus(z){Y=z,V()},stop(){if(H=!0,X)clearTimeout(X)},elapsedSec(){return((Date.now()-Q)/1000).toFixed(1)}}}async openStatusCard($,Z,J="blue"){let Q=Date.now(),Y=G7({sessionName:this.sessionName,title:$,status:BH(Z,Q),template:J}),H=await c(this.chatId,Y);if(!H)return G(`session "${this.sessionName}": status card send failed title=${$}`),await N(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let V;try{V=await r$(H)}catch(X){return G(`session "${this.sessionName}": status card id_convert failed title=${$}: ${X}`),await N(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return c$(V,1),{cardId:V,title:$,timer:this.startFooterTimer(V,Z,(X)=>h2($,X))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Q=h2($.title,`${Z} (${J}s)`);await m$($.cardId);let Y=await U$($.cardId,M.footer,this.footerElement(Q));X$($.cardId);let H=await q$($.cardId,p$({durationSec:J,suffix:Z}));if(Y&&H)await b$($.cardId);else{let V=`footer=${Y?"ok":"MISS"}, settings=${H?"ok":"MISS"}`;G(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${V}`),await N(this.chatId,`⚠️ 状态卡片终态写入失败 (${V}):${Z}`)}}async runLifecycle($,Z){let J=this.lifecycleTail,Q;this.lifecycleTail=new Promise((H)=>{Q=H}),await J;let Y=++this.lifecycleSequence;G(`session "${this.sessionName}": lifecycle#${Y} ${$} begin`);try{return await Z()}finally{Q(),G(`session "${this.sessionName}": lifecycle#${Y} ${$} end`)}}async waitForLifecycleIdle(){await this.lifecycleTail}beginTurnOpen($=this.proc,Z=this.procEpoch,J=!1){let Q={token:++this.turnOpenSequence,proc:$,procEpoch:Z,sawResult:!1,terminalForcePush:!1,pendingCompactions:[],backendTurnStarted:J};return this.openingTurnOwner=Q,this.openingTurn=!0,Q}ownsTurnOpen($){return this.openingTurnOwner===$&&this.proc===$.proc&&this.procEpoch===$.procEpoch}releaseTurnOpen($){if(this.openingTurnOwner!==$)return;this.openingTurnOwner=null,this.openingTurn=!1}invalidateTurnOpen(){this.openingTurnOwner=null,this.openingTurn=!1}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.consultCapability=null,this.stoppingProc===$)this.stoppingProc=null;if(this.blockedProc===$)this.blockedProc=null,this.blockedProcReason=null;return this.procEpoch++,!0}beginProcStop($){this.stoppingProc=$,this.consultCapability=null}acceptsConsultCapability($){let Z=this.consultCapability;if(!Z||!$||!this.proc?.isAlive())return!1;let J=Buffer.from(Z),Q=Buffer.from($);return J.length===Q.length&&Hj(J,Q)}async cancelConsultRuns($="用户取消"){await this.opts.onCancelConsultRuns?.(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?U(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(Q){J=Q}return this.finishProcStop($,J)}async settleProcResumableState($){let Z=null,J=$.conversationMaterializationBarrier?.();if(J)try{await J}catch(H){Z=`Codex 会话落盘确认失败: ${U(H)}`}let Q=$.conversationMaterializationFailure?.();if(Q&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${U(Q)}`;let Y=this.persistResumableSessionId(!1,$,!1);return[Z,Y].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,Q=this.blockedProcessMessage();if(Q){if(this.status="stopped",J?.(`❌ ${Q}`),Z)await O(this.chatId,`❌ ${Q}。请重试 stop/restart,或等待旧进程退出。`);return!1}if(this.proc&&!this.proc.isAlive())this.detachProc(this.proc);if(this.isRunning()){if(this.proc?.provider===this.selectedProvider)return J?.(this.withModel(`✅ ${this.backendLabel()} 已运行`)),!0;if(await this.stopIdleMismatchedProcessUnlocked(),this.proc?.isAlive())return J?.(`⚠️ 当前 ${this.backendLabel(this.proc.provider)} turn 尚未结束,模型切换将在后续新 turn 生效`),!0}if(this.selectedProvider==="codex")J?.("\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 O(this.chatId,"❌ Codex 未登录 ChatGPT 账号。\n请在服务器上运行 `codex login` 后再试。");return!1}if(!_H(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await O(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{c8(this.workDir)}catch(K){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${K}`),Z)await O(this.chatId,`❌ 创建项目失败: ${K}`);return!1}}if(!$.freshConversationStateAlreadyReset&&!this.pendingConversationMaterialization)this.resetFreshConversationState();this.status="starting",J?.(this.withModel(`\uD83D\uDE80 启动 ${this.backendLabel()}`));let Y;try{Y=this.spawnAgent()}catch(K){let _=`${this.backendLabel()} 启动失败: ${U(K)}`;if(G(`session "${this.sessionName}": ${_}`),J?.(`❌ ${_}`),Z)await O(this.chatId,`❌ ${_}`);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}this.attachProc(Y);let H=this.backendLabel(),V=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(Y,jH):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${H} 启动`:`⏳ 等待 ${H} init`);let X,W=null;try{if(Y.sendInitialize(),this.selectedProvider==="codex")X=Y.initializationPromise?.()}catch(K){X=void 0,W=K}let z=W?{state:"error",error:W}:this.selectedProvider==="claude"?await V:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(X),()=>{G(`session "${this.sessionName}": codex init still pending after ${P5/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${H} init 确认`))});if(z.state==="error"||z.state==="exit"){let K=z.error?U(z.error):z.state;G(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${K}`);let j=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,B=`❌ ${H} 启动失败: ${K}${j}`;if(J?.(B),Z)await O(this.chatId,B);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(z.state==="timeout"){G(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${n9/1000}s)`);let _=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,j=`❌ ${H} 启动超时: ${n9/1000} 秒内初始化事务未完成${_}`;if(J?.(j),Z)await O(this.chatId,j);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Y||!Y.isAlive()){let K=`${H} 启动期间已退出`;if(G(`session "${this.sessionName}": ${K}`),J?.(`❌ ${K}`),Z)await O(this.chatId,`❌ ${K}`);return this.detachProc(Y),this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(Z){let K=this.modelLine();await O(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),K].filter(Boolean).join(`
193
- `))}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 Q=!1,Y=(X,W)=>{if(Q)return;Q=!0,clearTimeout(H),clearTimeout(V),J({state:X,error:W})},H=setTimeout(()=>{if(Q)return;try{Z?.()}catch(X){Y("error",X)}},P5),V=setTimeout(()=>{Y("timeout",Error(`codex init timed out after ${n9/1000}s`))},n9);$.then(()=>Y("init"),(X)=>Y("error",X))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Q=!1,Y=(z,K)=>{if(Q)return;Q=!0,clearTimeout(H),$.off("init",V),$.off("error",X),$.off("exit",W),J({state:z,error:K})},H=setTimeout(()=>Y("ready"),Z),V=()=>Y("init"),X=(z)=>Y("error",z),W=(z)=>Y("exit",z);$.once("init",V),$.once("error",X),$.once("exit",W)})}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,Q=Z.onStatus;if(await this.cancelConsultRuns($),!this.proc){if(this.status="stopped",this.opts.onLifecycleChange?.(),Q?.("⚪ session 当前未运行"),J)await O(this.chatId,`⚪ session "${this.sessionName}" 当前未运行`);return}let Y=this.proc,H=this.persistResumableSessionId(!1,Y,!1),V=null;if(Q?.(`\uD83D\uDED1 停止 ${this.backendLabel(this.proc.provider)}`),G(`session "${this.sessionName}": stop (${$})`),this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((A)=>{G(`session "${this.sessionName}": stop current main-card close failed: ${U(A)}`)});let X=this.waitForTurnCloses().catch((A)=>G(`session "${this.sessionName}": stop main-card close failed: ${U(A)}`));this.beginProcStop(Y),this.status="stopped";let W=[];try{this.opts.onLifecycleChange?.()}catch(A){W.push(A),G(`session "${this.sessionName}": stop intent lifecycle write failed: ${U(A)}`)}let z=Y.conversationMaterializationBarrier?.();if(z){try{await z}catch(A){V=`Codex 会话落盘确认失败: ${U(A)}`}H=this.persistResumableSessionId(!1,Y,!1)}this.clearMultiMsgBuffer("stop"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.bgResumePending=!1,this.discardOrphanAssistant(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1;let K=null;try{await Y.kill()}catch(A){K=A}let _=Y.conversationMaterializationFailure?.();if(_&&Y.isConversationResumable?.()!==!0)V=`Codex 会话落盘确认失败: ${U(_)}`;H=this.persistResumableSessionId(!1,Y,!1);let B=(await Promise.allSettled([this.resetBackgroundTasks(),X])).filter((A)=>A.status==="rejected").map((A)=>A.reason);for(let A of B)G(`session "${this.sessionName}": stop terminal cleanup failed: ${U(A)}`);let L=this.finishProcStop(Y,K);try{this.opts.onLifecycleChange?.()}catch(A){W.push(A),G(`session "${this.sessionName}": stop final lifecycle write failed: ${U(A)}`)}let P=[...K?[K]:[],...!L&&!K?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...B,...W,...H?[Error(H)]:[],...V&&Y.isConversationResumable?.()!==!0?[Error(V)]:[]];if(P.length===1)throw P[0];if(P.length>1)throw AggregateError(P,`stop failed: ${P.map(U).join("; ")}`);if(Q?.(`✅ ${$}`),J)await O(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 Q=Z.announce??!0,Y=Z.onStatus,H=this.status,V=null;if(!$&&!this.pendingConversationLaunch&&this.pendingConversationMaterialization)V=this.pendingConversationMaterialization,k0(this.sessionName,null),this.pendingConversationMaterialization=null;let X=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),W=this.lastSessionRef;if($&&!X&&W?.cwd===null)try{W=await this.resolveLegacyResumeRef(W),this.lastSessionRef=W,this.lastSessionId=W.sessionId}catch(T){let k=this.invalidateMissingCodexResume(W.sessionId,T,J),u=k?`❌ 旧会话不可恢复: ${U(T)};${k}`:`❌ 旧会话 cwd 校验失败: ${U(T)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?H:"stopped",Y?.(u),Q)await O(this.chatId,u);return!1}let z=W?.sessionId??null,K=X&&X.kind!=="fresh"?X.source.sessionId:z,_=K?z$(K):"",j=null,B=(T=this.proc)=>{if(!$||X||T?.provider!=="codex"||T.isConversationResumable?.()!==!0)return;j=this.persistResumableSessionId(!1,T,!1),W=this.lastSessionRef,z=W?.sessionId??null,K=z,_=K?z$(K):""},L=null;if(!Y&&Q&&$&&z){let T=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${_}`);if(L=await this.openStatusCard("restart",T),L)Y=(k)=>this.setStatusCard(L,k)}let P=Q&&!L,A=async(T)=>{if(L)await this.closeStatusCard(L,T)},R=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: ${U(T)}`)});let D=this.waitForTurnCloses().catch((T)=>G(`session "${this.sessionName}": restart main-card close failed: ${U(T)}`)),F=null,y=null;if(this.proc){let T=this.proc;Y?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(T.provider)}`),y=T,this.beginProcStop(T);let k=T.conversationMaterializationBarrier?.();if(k)try{await k}catch(p){j=`Codex 会话落盘确认失败: ${U(p)}`}if(B(T),$&&!X&&j&&!R&&T.isAlive()){if(this.stoppingProc===T)this.stoppingProc=null;this.status=H;let p=`❌ ${this.backendLabel(T.provider)} 恢复点尚未安全落盘,已保留当前进程: ${j}`;if(G(`session "${this.sessionName}": abort restart before kill: ${j}`),Y?.(p),P)await O(this.chatId,p);return await A(p),!1}try{await T.kill()}catch(p){F=p}let u=T.conversationMaterializationFailure?.();if(u&&T.isConversationResumable?.()!==!0)j=`Codex 会话落盘确认失败: ${U(u)}`;B(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(),D])).filter((T)=>T.status==="rejected").map((T)=>T.reason);for(let T of x)G(`session "${this.sessionName}": restart terminal cleanup failed: ${U(T)}`);let m=y?this.finishProcStop(y,F):!0,g=[...F?[`kill=${U(F)}`]:[],...!m&&!F?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...x.map((T)=>`cleanup=${U(T)}`),...j?[`resume=${j}`]:[]];if(g.length>0&&V)try{k0(this.sessionName,V),this.pendingConversationMaterialization=V}catch(T){g.push(`pendingRestore=${U(T)}`)}if(g.length>0){let T=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${g.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.(T),P)await O(this.chatId,T);return await A(T),!1}let f=X?.kind==="resume"||X?.kind==="fork";if($&&W||f){this.status="starting",this.usageTotalsSeedUnknown=!0,Y?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${_}`));let T;try{T=this.spawnAgent(W??void 0)}catch(F$){let n$=`❌ ${this.backendLabel()} 恢复失败: ${U(F$)}`;if(G(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${U(F$)}`),Y?.(n$),P)await O(this.chatId,n$);return this.status="stopped",this.opts.onLifecycleChange?.(),await A(n$),!1}this.attachProc(T);let k=this.backendLabel(),u=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(T,jH):null;Y?.(this.selectedProvider==="claude"?`⏳ 检查 ${k} 恢复启动`:`⏳ 等待 ${k} init 确认`);let p,$$=null;try{if(T.sendInitialize(),this.selectedProvider==="codex")p=T.initializationPromise?.()}catch(F$){p=void 0,$$=F$}let o=$$?{state:"error",error:$$}:this.selectedProvider==="claude"?await u:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(p),()=>{G(`session "${this.sessionName}": codex resume init still pending after ${P5/1000}s`),Y?.(this.withModel(`⏳ 仍在等待 ${k} init 确认 thread=${_}`))});if(o.state==="error"||o.state==="exit"||o.state==="timeout"){let F$=o.state==="error"?this.invalidateMissingCodexResume(K,o.error,J):null,n$=[o.error?U(o.error):o.state,F$].filter(Boolean).join(";");G(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${n$}`);let h5=await this.stopOwnedProc(T,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,Y6=o.state==="timeout"?`❌ ${k} 恢复超时${h5}`:`❌ ${k} 恢复失败: ${n$}${h5}`;if(Y?.(Y6),P)await O(this.chatId,Y6);return this.status="stopped",this.opts.onLifecycleChange?.(),await A(Y6),!1}if(this.proc!==T||!T.isAlive()){let F$=`❌ ${k} 恢复期间已退出`;if(G(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Y?.(F$),P)await O(this.chatId,F$);return this.detachProc(T),this.status="stopped",this.opts.onLifecycleChange?.(),await A(F$),!1}let A0=this.withModel(this.withWorktreeInstructionNotice(this.selectedProvider==="claude"&&o.state==="ready"?`✅ 已准备恢复上一会话 thread=${_}`:`✅ 已恢复上一会话 thread=${_}`));if(Y?.(A0),P)await O(this.chatId,A0);this.status="idle",this.startedAt=Date.now(),this.opts.onLifecycleChange?.();try{await A(A0)}catch(F$){G(`session "${this.sessionName}": restart succeeded but status-card close failed: ${U(F$)}`),await N(this.chatId,`⚠️ ${A0}
194
- 状态卡收尾失败: ${U(F$)}`)}return!0}else{if($&&!X){if(Y?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),P)await O(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{G$($,this.selectedProvider,this.workDir);let J=M2(this.sessionName),Q=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Q)k0(this.sessionName,Q),this.pendingConversationMaterialization=Q;this.pendingConversationLaunch=$;try{let Y=await this.startUnlocked(Z);if(!Y&&Q)k0(this.sessionName,J),this.pendingConversationMaterialization=J;return Y}catch(Y){if(!Q)throw Y;try{k0(this.sessionName,J),this.pendingConversationMaterialization=J}catch(H){throw AggregateError([Y,H],`fork start and pending-intent restore failed: ${U(Y)}; ${U(H)}`)}throw Y}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{G$($,this.selectedProvider,this.workDir);let Q=Z?{anchors:Z.anchors.slice(),base:Z.base,pendingLaunch:Z.pendingLaunch!==void 0?Z.pendingLaunch:this.selectedProvider==="claude"&&$.kind==="fork"?{launch:$,previousSessionId:this.lastSessionId}:null}:null,Y=this.proc,H=this.lastSessionId,V=this.lastSessionRef,X=v1(this.sessionName).slice(),W=U2(this.sessionName),z=M2(this.sessionName),K={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,j=()=>{if(_)this.lastSessionId=null,this.lastSessionRef=null,f1(this.sessionName,"codex");else if(this.lastSessionId=H,this.lastSessionRef=V,V)A2(this.sessionName,V);else f1(this.sessionName,this.selectedProvider);C$(this.sessionName,X,W,z),this.pendingConversationMaterialization=z,this.turnCounter=K.turnCounter,this.currentGoal=K.currentGoal,this.cumStats=K.cumStats,this.lastTurnDelta=K.lastTurnDelta,this.currentTurnUsageBaseline=K.currentTurnUsageBaseline,this.currentTurnUsageBaselineKnown=K.currentTurnUsageBaselineKnown,this.lastTurnUsage=K.lastTurnUsage,this.usageTotalsSeedUnknown=K.usageTotalsSeedUnknown},B=!1;if(Q?.pendingLaunch)C$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch),this.pendingConversationMaterialization=Q.pendingLaunch,B=!0;this.pendingConversationLaunch=$;let L=(P)=>{_=V?.provider==="codex"&&V.sessionId===P};try{let P;try{P=$.kind==="fresh"?await this.restartUnlocked(!1,J,L):await this.restartUnlocked(!0,J,L)}catch(A){let R=null,D=this.proc&&this.proc!==Y?this.proc:null;if(D)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(x){R=x}let F=!D||this.proc!==D&&!D.isAlive();if(!F&&!R)R=Error("replacement process stop was not confirmed");let y=null;if(F)try{j()}catch(x){y=x}let C=[A,...R?[R]:[],...y?[y]:[]];if(C.length===1)throw A;throw AggregateError(C,`rollback launch and cleanup failed: ${C.map(U).join("; ")}`)}if(!P)return j(),!1;if(Q)try{if(!B)C$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch);this.pendingConversationMaterialization=Q.pendingLaunch}catch(A){let R=null,D=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(x){R=x}let F=!D||this.proc!==D&&!D.isAlive();if(!F&&!R)R=Error("replacement process stop was not confirmed");let y=null;if(F)try{j()}catch(x){y=x}let C=[A,...R?[R]:[],...y?[y]:[]];if(C.length===1)throw A;throw AggregateError(C,`rollback branch commit failed: ${C.map(U).join("; ")}`)}return P}finally{this.pendingConversationLaunch=null}})}dispose(){j1.all.delete(this)}recordTurnAnchor($){let Z=this.proc;if(!Z?.sessionId||!$)return null;if($.provider!==Z.provider||$.source.sessionId!==Z.sessionId||$.source.cwd!==this.workDir){let Q=`拒绝了与当前会话不匹配的 checkpoint provider=${$.provider} source=${$.source.sessionId}`;return G(`session "${this.sessionName}": ${Q}`),this.lastTurnUserPreview="",Q}let J={checkpoint:$,preview:this.lastTurnUserPreview.slice(0,80),ts:Date.now(),writes:this.collectTurnWrites()};if(this.lastTurnUserPreview="",Z.provider==="codex"&&Z.isConversationResumable?.()!==!0){if(this.pendingCodexTurnAnchors.filter((Y)=>Y.proc===Z).length>=64)return 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 S4(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${U(Z)}`;return G(`session "${this.sessionName}": ${J}`),J}}flushPendingCodexTurnAnchors($){let Z=null,J=[];for(let Q of this.pendingCodexTurnAnchors){if(Q.proc!==$||Z){J.push(Q);continue}if(Z=this.appendTurnAnchor(Q.anchor),Z)J.push(Q)}return this.pendingCodexTurnAnchors=J,Z}discardPendingCodexTurnAnchors($,Z){if($.provider!=="codex")return;let J=this.pendingCodexTurnAnchors.length;this.pendingCodexTurnAnchors=this.pendingCodexTurnAnchors.filter((Y)=>Y.proc!==$);let Q=J-this.pendingCodexTurnAnchors.length;if(Q>0)G(`session "${this.sessionName}": dropped ${Q} unmaterialized Codex checkpoint(s): ${Z}`)}collectTurnWrites(){let $=this.currentTurn;if(!$)return[];let Z=[];for(let J of $.toolByUseId.values())Z.push(...O7(J.name,J.input));return Z}worktreeProjectName(){return w0(this)}worktreeProjectDir(){return e1(this)}spawnDeveloperInstructions(){return dY(this)}worktreeInstructionLoadedNotice(){return q5(this)}withWorktreeInstructionNotice($){return nY(this,$)}worktreeExtraInstruction(){return l9(this)}runWorktreeCommand($,Z){return oY(this,$,Z)}showWorktrees(){return j5(this)}showTasklistPanel(){return RY(this)}showConsultIdentityPanel($=""){return zY(this,$)}onConsultIdentityAdd($,Z,J){return GY($,Z,J)}onConsultIdentityRole($,Z,J,Q){return KY($,Z,J,Q)}onConsultIdentityToggle($,Z,J){return _Y($,Z,J)}onConsultIdentityDelete($,Z,J){return qY($,Z,J)}onConsultIdentityDeleteConfirm($,Z,J){return jY($,Z,J)}onConsultIdentityPage($,Z,J){return BY($,Z,J)}onConsultIdentityBack($,Z){return LY($,Z)}onTasklistEnable(){return OY(this)}onTasklistDeletePrompt($){return TY(this,$)}onTasklistDeleteConfirm($){return kY(this,$)}runCompactCommand(){return oQ(this)}showModelPanel(){return tQ(this)}onModelSelect($,Z="",J="",Q=null){return JY(this,$,Z,J,Q)}onModelEffortSelect($,Z,J="",Q="",Y=""){return this.runLifecycle("model-effort-select",()=>QY(this,$,Z,J,Q,Y))}onProviderSelect($,Z=""){return sQ(this,$,Z)}onModelPanelCancel($=""){return ZY(this,$)}onModelCustomPrompt($,Z,J=""){return eQ(this,$,Z,J)}consumeModelCustomMessage($,Z){return $Y(this,$,Z)}onWorktreeDisband($){return rY(this,$)}showForkList($=""){return QH(this,$)}showBackList($=""){return YH(this,$)}showResumeList($=""){return HH(this,$)}runBtwCommand($){return VH(this,$)}runByeCommand(){return XH(this)}onForkSelect($,Z,J=""){return WH(this,$,Z,J)}onBackSelect($,Z,J=""){return zH(this,$,Z,J)}onResumeSelect($,Z,J=""){return GH(this,$,Z,J)}runCommand($,Z=""){return dQ(this,$,Z)}async buildConsoleOpts($,Z){let J=await kJ(),Q=this.runtimeModelSelection();return{sessionName:this.sessionName,status:this.status,provider:Q.provider,model:Q.model??void 0,effort:Q.effort,worktreeInstructionNotice:this.worktreeInstructionLoadedNotice(),peers:[...j1.all].filter((Y)=>Y.isRunning()).map((Y)=>({...Y.peerSnapshot(),isCurrent:Y===this})),usage:$,glmUsage:Z,sysinfo:J}}async buildConsoleCard($){return K7(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0),J=Z.provider??this.currentProvider(),Q=this.currentTokenSource(),Y=Q&&Q.agent===J&&Q.enabled?Q:this.selectedTokenSourceId?void 0:P4(J)[0];if(Y)Z.unifiedUsage=await Y.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 g7();else Z.usage=await O9();if(!await U$($,M.consoleUsage,g2(Z),{notifyCardFailure:!1}))throw Error("console usage element replace rejected")}async mutateStaticCard($,Z,J){let Q=!0;try{await J()}catch(H){Q=!1,G(`session "${this.sessionName}": ${Z} mutation failed: ${U(H)}`)}let Y=!1;try{Y=await q$($,{config:{streaming_mode:!1}})}catch(H){G(`session "${this.sessionName}": ${Z} streaming-off failed: ${U(H)}`)}if(!Q||!Y)return G(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Q} streamingOff=${Y} card=${$.slice(0,12)}`),!1;try{await b$($)}catch(H){return G(`session "${this.sessionName}": ${Z} dispose failed: ${U(H)}`),!1}return Q}patchConsoleUsageLater($){this.mutateStaticCard($,"console usage",()=>this.patchConsoleUsage($))}async replaceStatusCardWithConsole($,Z){$.timer.stop();let J=$.timer.elapsedSec(),Q=await this.buildConsoleOpts(void 0);await m$($.cardId);let Y=await U$($.cardId,M.footer,X9(Q,M.footer)),H=await y0($.cardId,V9(Q),{type:"insert_after",targetElementId:M.footer}),V=await y0($.cardId,W9(Q.sysinfo),{type:"insert_after",targetElementId:M.consoleProjects}),X=await y0($.cardId,g2(Q),{type:"insert_after",targetElementId:M.consoleHost});if(!Y||!H||!V||!X){await N(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}X$($.cardId),await q$($.cardId,p$({durationSec:J,suffix:Z})),this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleCard(void 0),Z=await c(this.chatId,$);if(!Z)return;(async()=>{let J="";try{J=await r$(Z),c$(J,4)}catch(Q){G(`session "${this.sessionName}": console card conversion failed: ${U(Q)}`);return}await this.mutateStaticCard(J,"console usage",()=>this.patchConsoleUsage(J))})().catch((J)=>G(`session "${this.sessionName}": console async update rejected: ${U(J)}`))}interrupt(){if(!this.proc)return;G(`session "${this.sessionName}": interrupt`),this.proc.sendInterrupt()}async startColdUserTurn($,Z,J){if(!this.pendingConversationMaterialization)this.resetFreshConversationState();this.pendingTurnInputs.push($);let Q=this.beginTurnOpen();try{let H=await this.openTurnCard(Q,J,"user_message",{initialFooter:"Waiting...(0s)",startThinking:!1,directStart:!0});if(!H||this.currentTurn!==H)return;let V=this.startFooterTimer(H.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(K)=>this.withModel(K)),X=`\uD83D\uDE80 启动 ${this.backendLabel()}`,W=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(K)=>{X=K,V.setStatus(K)}});if(V.stop(),await m$(H.cardId),!W){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(H),z.sendUserText(Z,[]),this.pendingUserMessageCount++,this.status="working"}finally{this.releaseTurnOpen(Q)}}async onUserMessage($,Z=[],J="",Q=""){await this.runLifecycle("user-message",()=>this.onUserMessageUnlocked($,Z,J,Q))}async onUserMessageUnlocked($,Z,J,Q){let Y=this.blockedProcessMessage();if(Y){await O(this.chatId,`❌ ${Y}。请重试 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 H=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(" ")+`
195
- `:"")+$,W=(z)=>{this.pendingReactionIds.set(z,""),(async()=>{let K=await R$(z,"OneSecond");if(!K)return;if(this.pendingReactionIds.has(z))this.pendingReactionIds.set(z,K);else if(this.currentBatchReactionIds.has(z))this.currentBatchReactionIds.set(z,K);else P$(z,K)})().catch((K)=>{G(`session "${this.sessionName}": reaction tracking failed: ${U(K)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Q}),Q)W(Q);return}await this.startColdUserTurn($,X,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Q}),Q)W(Q);return}if(!this.openingTurn&&this.initCount>=1){let z=this.proc,K=this.procEpoch,_=this.beginTurnOpen(z,K);try{this.pendingTurnInputs.push($);let j=await this.openTurnCard(_,J,"user_message");if(!j||this.currentTurn!==j)return;if(this.proc!==z||this.procEpoch!==K||!z.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(z.provider)} 已退出`);return}z.sendUserText(X,[]),this.pendingUserMessageCount++,this.status="working"}finally{this.releaseTurnOpen(_)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Q}),Q)W(Q);return}if(this.pendingTurnInputs.push($),this.proc.sendUserText(X,[]),this.pendingUserMessageCount++,H&&Q)W(Q)}hasPendingAsk(){return TQ(this)}onMultiMessageInbound($,Z,J,Q){return VQ(this,$,Z,J,Q)}clearMultiMsgBuffer($){m7(this,$)}onAskMessageAnswer($,Z,J){return kQ(this,$,Z,J)}onAskAnswer($,Z,J,Q){return yQ(this,$,Z,J,Q)}onAskCustomAnswer($,Z,J,Q){return n7(this,$,Z,J,Q)}onPermissionDecision($,Z,J){return xQ(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=o0(this.sessionName,"codex");if(f1(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 Q=F5(Z);if(!Q||!["thread/read","thread/resume","thread/fork"].includes(Q.method)||Q.serverCode!==-32600||Q.serverMessage!==`no rollout found for thread id ${$}`)return null;let Y=o0(this.sessionName,"codex");if(!Y||Y.sessionId!==$)return null;try{f1(this.sessionName,"codex")}catch(V){let X=`已确认恢复点无 rollout,但作废失败: ${U(V)}`;return G(`session "${this.sessionName}": ${X} thread=${$}`),X}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let H=`已作废无 rollout 的恢复点 thread=${z$($)}`;return G(`session "${this.sessionName}": ${H} fullThread=${$}`),H}persistResumableSessionId($=!1,Z=this.proc,J=!0){let Q=Z?.provider==="claude"?this.pendingConversationMaterialization:null,Y=Z?.sessionId;if(!Z)return null;if(Z.provider==="codex"&&Z.isConversationResumable?.()!==!0)return null;if(!Y){if(!Q)return null;let 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 H={provider:Z.provider,sessionId:Y,cwd:this.workDir};if(Q&&(Y===Q.launch.source.sessionId||Q.previousSessionId!==null&&Y===Q.previousSessionId)){let X=Error(`Claude fork did not materialize an independent session id (${Y})`);if(G(`session "${this.sessionName}": ${X.message}`),$)throw X;return X.message}try{A2(this.sessionName,H)}catch(X){let W=`会话恢复点持久化失败: ${U(X)}`,z=this.resumePersistenceError!==W;if(this.resumePersistenceError=W,Z.provider===this.selectedProvider)this.lastSessionRef=H,this.lastSessionId=Y;if(G(`session "${this.sessionName}": ${W}`),$)throw X;if(z&&J)N(this.chatId,`⚠️ ${W};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return W}if(Z.provider===this.selectedProvider)this.lastSessionRef=H,this.lastSessionId=Y;let V=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(V){let X=this.resumePersistenceError!==V;if(this.resumePersistenceError=V,$)throw Error(V);if(X&&J)N(this.chatId,`⚠️ ${V}`);return V}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 k0(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Q=`Claude 待生成分支标记清除失败: ${U(J)}`;return G(`session "${this.sessionName}": ${Q}`),Q}}bgStore(){return{active:this.backgroundTasks,pending:this.pendingBgTasks}}applyBgStore($){this.backgroundTasks=$.active,this.pendingBgTasks=$.pending}onMainThreadAdvance(){if(this.pendingBgTasks.length===0)return;this.applyBgStore(u6(this.bgStore())),this.onBackgroundTaskChanged()}bgTaskOwns($){return this.backgroundTasks.some((Z)=>Z.toolUseId===$)||this.pendingBgTasks.some((Z)=>Z.toolUseId===$)}onBackgroundTaskChanged(){if(!M0(this.backgroundTasks)){if(this.backgroundCard)this.settleBackgroundCard().catch((Z)=>{G(`session "${this.sessionName}": background settle failed: ${U(Z)}`)});return}if(!this.backgroundCard&&!this.openingBackground){this.openBackgroundCard().catch((Z)=>{G(`session "${this.sessionName}": background open failed: ${U(Z)}`)});return}this.scheduleBackgroundRefresh()}async openBackgroundCard(){let $=this.beginBackgroundOpen();if(!$)return;let Z=this.backgroundTasks.slice();try{let J=n6(Z,Date.now(),q1()),Q=await c(this.chatId,J);if(!Q){if(this.ownsBackgroundOpen($))G(`session "${this.sessionName}": background card send failed`);return}let Y;try{Y=await r$(Q)}catch(H){G(`session "${this.sessionName}": background card id_convert failed: ${H}`);return}if(c$(Y,Z.length),!this.ownsBackgroundOpen($)){await this.terminalizeSupersededCard(Y,"⚠️ 后台任务世代已切换,本卡已作废",!1);return}if(this.backgroundCard={messageId:Q,cardId:Y},this.backgroundDetailAdded=new Set(Z.map((H)=>H.id)),this.backgroundDetailAdding.clear(),G(`session "${this.sessionName}": background card opened cardId=${Y.slice(0,12)} tasks=${Z.length}`),!M0(this.backgroundTasks)){this.settleBackgroundCard().catch((H)=>{G(`session "${this.sessionName}": background settle-after-open failed: ${U(H)}`)});return}this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}finally{this.releaseBackgroundOpen($)}}startBackgroundRefreshTick(){if(this.backgroundRefreshTick)return;let $=()=>{if(!this.backgroundCard||!M0(this.backgroundTasks))return;let Z=q1(),J=Date.now(),Q=1/0;for(let Y of this.backgroundTasks){if(N$(Y))continue;let H=R0(J-Y.startedAt,Z).nextDelayMs;if(H<Q)Q=H}if(!isFinite(Q))return;this.backgroundRefreshTick=setTimeout(()=>{this.refreshBackgroundCardFull(),$()},Math.max(1,Math.ceil(Q)))};$()}stopBackgroundRefreshTick(){if(this.backgroundRefreshTick)clearTimeout(this.backgroundRefreshTick),this.backgroundRefreshTick=null}scheduleBackgroundRefresh(){if(!this.backgroundCard||this.settlingBackgroundCard)return;if(this.backgroundRefreshTimer)return;this.backgroundRefreshTimer=setTimeout(()=>{this.backgroundRefreshTimer=null,this.refreshBackgroundCardFull()},1500)}refreshBackgroundCardFull(){let $=this.backgroundCard;if(!$)return;let Z=Date.now(),J=q1();for(let Q of this.backgroundTasks)if(!this.backgroundDetailAdded.has(Q.id)){if(this.backgroundDetailAdding.has(Q.id))continue;this.backgroundDetailAdding.add(Q.id),y0($.cardId,y1(Q,Z,J)).then((Y)=>{if(Y)this.backgroundDetailAdded.add(Q.id);else G(`session "${this.sessionName}": background panel add MISS task=${Q.id}`)}).finally(()=>{this.backgroundDetailAdding.delete(Q.id)})}else d($.cardId,z2.panel(Q.id),y1(Q,Z,J));G0($.cardId,L4(this.backgroundTasks))}async resetBackgroundTasks(){if(this.invalidateBackgroundOpen(),this.backgroundTasks.some(($)=>!N$($))){let $=Date.now();this.backgroundTasks=this.backgroundTasks.map((Z)=>N$(Z)?Z:{...Z,status:"killed",endTime:Z.endTime??$})}if(this.pendingBgTasks=[],this.backgroundCard){await this.settleBackgroundCard();return}if(this.stopBackgroundRefreshTick(),this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;this.backgroundTasks=[],this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear()}async settleBackgroundCard(){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 m$($.cardId),await W0($.messageId,D4(Z)),X$($.cardId),!await q$($.cardId,p$({suffix:"\uD83E\uDDED 后台任务已结束"})))throw Error("background history streaming-off rejected");if(await b$($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((Q)=>!N$(Q)),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===$&&M0(this.backgroundTasks))this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(this.backgroundTasks.length>0)this.onBackgroundTaskChanged()}async migrateBackgroundCard(){let $=this.backgroundCard;if(!$)return;if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;this.stopBackgroundRefreshTick();let Z=this.backgroundTasks.filter(N$).length;if(await m$($.cardId),Z>0)await W0($.messageId,D4(this.backgroundTasks));else await W0($.messageId,o6());if(X$($.cardId),!await q$($.cardId,p$({suffix:"\uD83E\uDDED 已迁移至新卡"})))throw Error("background migration streaming-off rejected");await b$($.cardId),this.backgroundCard=null,this.backgroundTasks=this.backgroundTasks.filter((Q)=>!N$(Q)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),G(`session "${this.sessionName}": background card migrated cardId=${$.cardId.slice(0,12)} terminal=${Z} active=${this.backgroundTasks.length}`)}wireProc($,Z){if(Z===void 0)this.invalidateTurnOpen(),this.invalidateBackgroundOpen();let J=Z??++this.procEpoch;if(Z===void 0&&this.proc!==$)this.proc=$;let Q=()=>this.proc===$&&this.procEpoch===J,Y=!1,H=!1,V=(X,W)=>{$.on(X,(z)=>{if(!Q()){if(!Y)Y=!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(!H)H=!0,G(`session "${this.sessionName}": ignore ${$.provider} event=${String(X)} while process stop is pending`);return}W(z)})};V("error",(X)=>{G(`session "${this.sessionName}": ${$.provider} process error: ${X}`)}),V("init",()=>{if($.provider==="codex"&&$.launchKind==="fresh")this.clearResumeBindingForFreshCodex($);else this.persistResumableSessionId(!0);if(m3(),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)return;let X=this.pendingUserMessageCount>0,W=!X&&this.bgResumePending;if(!X&&!W)return;this.bgResumePending=!1;let z=this.lastUserOpenId;if(X)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let K=X?[...this.currentBatchReactionIds.keys()]:[],_=()=>{for(let B of K){let L=this.currentBatchReactionIds.get(B);if(this.currentBatchReactionIds.delete(B),L)P$(B,L)}},j=this.beginTurnOpen($,J,!0);(async()=>{try{let B=await this.openTurnCard(j,z,X?"user_message":"bg_task_resume");if(!Q()){if(G(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),B&&this.currentTurn===B)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);_();return}if(!B||this.currentTurn!==B){if(!this.ownsTurnOpen(j)){_();return}if(j.sawResult&&j.terminalSuffix)N(this.chatId,j.terminalSuffix);if(X)G(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),_();else if(this.bgResumeCardless=!0,j.sawResult)j.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(j.sawResult)j.sawResult=!1,G(`session "${this.sessionName}": result raced card-open — closing freshly-opened turn card now`),await this.closeTurnCard(j.terminalSuffix,{forcePush:j.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(j)}})().catch((B)=>{G(`session "${this.sessionName}": init turn-open handler failed: ${U(B)}`)})}),V("conversation_materialized",({session_id:X,source:W})=>{if($.provider!=="codex")return;if($.sessionId!==X){G(`session "${this.sessionName}": ignore mismatched Codex materialization session=${X} current=${$.sessionId??"MISS"} source=${W}`);return}G(`session "${this.sessionName}": Codex resume point materialized thread=${X} source=${W}`),this.persistResumableSessionId()}),V("conversation_materialization_failed",({session_id:X,source:W,error:z})=>{if($.provider!=="codex"||$.sessionId!==X)return;let K=`Codex 会话落盘确认失败,未写恢复点: ${U(z)}`,_=this.resumePersistenceError!==K;if(this.resumePersistenceError=K,G(`session "${this.sessionName}": ${K} thread=${X} source=${W}`),_)N(this.chatId,`⚠️ ${K}`)}),V("turn_started",()=>{this.persistResumableSessionId();let X=this.proc?.lastTotalUsage;if(this.usageTotalsSeedUnknown&&!X){this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;return}this.currentTurnUsageBaseline=X?{...X}:null,this.currentTurnUsageBaselineKnown=!0}),V("token_usage",({totalUsage:X})=>{if(this.persistResumableSessionId(),X)this.usageTotalsSeedUnknown=!1}),V("turn_plan_updated",(X)=>{this.handleTurnPlanUpdated(X)}),V("plan_delta",(X)=>{this.handlePlanDelta(X)}),V("context_compacted",(X)=>{this.handleContextCompacted(X)}),V("rate_limits_updated",(X)=>{if($.provider==="codex")nJ(X)}),V("thread_goal_updated",(X)=>{this.handleThreadGoalUpdated(X)}),V("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),V("assistant_text",({text:X})=>{this.appendAssistant(X)}),V("assistant_block_stop",()=>{this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),V("tool_use",({id:X,name:W,input:z,parentToolUseId:K})=>{if(K&&this.bgTaskOwns(K)){this.applyBgStore(l6({active:this.backgroundTasks,pending:this.pendingBgTasks},K,X,W,z)),this.onBackgroundTaskChanged();return}if(MQ(this,X,W,z),!K)this.onMainThreadAdvance();if(!K&&(W==="Task"||W==="Agent"))this.lastMainTaskToolUseId=X}),V("tool_result",({tool_use_id:X,content:W,is_error:z,parentToolUseId:K})=>{if(K&&this.bgTaskOwns(K)){this.applyBgStore(d6({active:this.backgroundTasks,pending:this.pendingBgTasks},K,X,W,z)),this.onBackgroundTaskChanged();return}RQ(this,X,W,z)}),V("can_use_tool",(X)=>{NQ(this,X)}),V("hook_callback",(X)=>{this.proc?.sendHookResponse(X.request_id,{})}),V("result",(X)=>{let W=this.persistResumableSessionId(),z=W?null:this.consumePendingConversationMaterialization(),K=[W,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 F=this.proc?.lastResult.subtype??"unknown",y=this.proc?.lastResult.is_error===!0;G(`session "${this.sessionName}": SDK result after user stop subtype=${F} isError=${y} — 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 j=this.pendingMidTurnMsgs.length>0,B=this.proc?.lastResult.is_error===!0,L=this.proc?.lastResult.subtype??"success",P,A=!1,R=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),D=[K,_].filter(Boolean).join(";")||null;if(D)P=`⚠️ ${D}`,A=!0;else if(j)P=B?`⚠️ ${R} ${L},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(B)P=`⚠️ ${R} ${L}`,A=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=P,this.openingTurnOwner.terminalForcePush=A;if(D&&!this.currentTurn&&!this.openingTurn)N(this.chatId,`⚠️ ${D}`);if(G(`session "${this.sessionName}": SDK result subtype=${L} isError=${B} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${A}`),this.closeTurnCard(P,{forcePush:A,hasFreshResult:!0}).catch((F)=>{G(`session "${this.sessionName}": result card close failed: ${U(F)}`)}),this.status="idle",j)this.drainMidTurnAndOpen().catch((F)=>{G(`session "${this.sessionName}": mid-turn drain failed: ${U(F)}`)})}),V("bg_task_started",(X)=>{let W=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=${W?.slice(0,8)??"-"} desc=${(X.description??"").slice(0,40)}`),this.applyBgStore(I6(this.bgStore(),{...X,tool_use_id:W})),this.onBackgroundTaskChanged()}),V("bg_task_progress",(X)=>{this.applyBgStore(c6(this.bgStore(),X)),this.onBackgroundTaskChanged()}),V("bg_task_updated",(X)=>{this.applyBgStore(m6(this.bgStore(),X)),this.onBackgroundTaskChanged()}),V("bg_task_settled",(X)=>{if(G(`session "${this.sessionName}": bg_task_settled task=${X.task_id} status=${X.status}`),this.applyBgStore(p6(this.bgStore(),X)),this.onBackgroundTaskChanged(),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),V("subagent_step",(X)=>{this.applyBgStore(i6(this.bgStore(),X.thread_id,X.item_id,X.tool,X.phase,X.brief)),this.onBackgroundTaskChanged()}),V("exit",({code:X,signal:W,expected:z})=>{if(G(`session "${this.sessionName}": ${$.provider} exited code=${X} signal=${W} expected=${z}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let L=$.conversationMaterializationFailure?.(),P=this.persistResumableSessionId(!1,$,!1),A=[L&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${U(L)}`:null,P].filter(Boolean).join(";");if(A)N(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${A}`);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.cancelConsultRuns(`${$.provider} process exited`).catch((L)=>{G(`session "${this.sessionName}": cancel consult after process exit failed: ${U(L)}`)});let K=this.backendLabel($.provider),_=`code=${X??"null"}, signal=${W??"null"}`,j=z?`\uD83D\uDED1 ${K} 已退出`:`⚠️ ${K} 异常退出 (${_})`;if(this.currentTurn)this.closeTurnCard(j).catch((L)=>{G(`session "${this.sessionName}": process-exit current main-card close failed: ${U(L)}`)});let B=this.waitForTurnCloses().catch((L)=>{G(`session "${this.sessionName}": process-exit main-card close failed: ${U(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([B,this.resetBackgroundTasks()]);for(let P of L)if(P.status==="rejected")G(`session "${this.sessionName}": process-exit terminal cleanup failed: ${U(P.reason)}`);if(!z)await O(this.chatId,`⚠️ ${K} 异常退出 (${_})。回复任意消息将重新启动。`)}).catch((L)=>{G(`session "${this.sessionName}": process-exit cleanup rejected: ${U(L)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?k6(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=y6(Z),Q=this.proc?.provider==="claude"?0:$.cost_delta_usd??0,Y=$.duration_ms??0;if(J!=null)this.cumStats.tokens+=J;this.cumStats.costUsd+=Q,this.cumStats.turns+=$.num_turns??1,this.lastTurnDelta={tokens:J,costUsd:Q,durationMs:Y}}currentContextTokens($=this.proc){if($?.provider==="claude")return $.lastContextTokens??null;let Z=$?.lastUsage;return c4(Z)}contextLimitForDisplay($=this.proc){return m4($?.lastContextWindow)}async drainMidTurnAndOpen(){if(this.pendingMidTurnMsgs.length===0)return;let $=this.proc,Z=this.procEpoch;if(!$?.isAlive())return;let J=this.pendingMidTurnMsgs;this.pendingMidTurnMsgs=[];let Q=this.beginTurnOpen($,Z);try{for(let W of J)if(this.pendingTurnInputs.push(W.text),W.msgId){let z=this.pendingReactionIds.get(W.msgId)??"";this.currentBatchReactionIds.set(W.msgId,z),this.pendingReactionIds.delete(W.msgId)}let Y=J.map((W)=>W.wireText).join(`
187
+ ${K}`)}return{slug:Q,chatName:H,branch:Y,worktreePath:W,removedWorktree:!1}}function K3($){if(!K1($))throw Error(`project directory does not exist: ${$}`);let Z=j$($,["rev-parse","--show-toplevel"]).trim();if(G3(Z)!==G3($))throw Error(`${$} is not the git repository root (${Z})`)}function lY($,Z){let J=j$($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function hq($,Z,J){let Q=Iq($);if(!Q?.startsWith(r1))return null;let Y=Q.slice(r1.length);if(!_1(Y))throw Error(`invalid worktree branch "${Q}"`);let H=s1(Z,J,Y);if(p9($)!==p9(H))return null;let X=cq($,gq(Y));return X?{path:X,slug:Y}:null}function Iq($){if(!K1($))return null;try{return j$($,["branch","--show-current"]).trim()||null}catch(Z){if(uq(Z))return null;throw Z}}function gq($){return $.split("-",1)[0]??$}function cq($,Z){let J=`agents.${Z}.md`,Q=Sq($).filter((Y)=>Y.toLowerCase()===J).sort();if(Q.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Q.join(", ")}`);return Q[0]?hY($,Q[0]):null}function mq($,Z){try{return j$($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function dY($,Z,J){let Q=j$($,["rev-parse",Z]).trim(),Y=j$($,["rev-parse","HEAD"]).trim();if(Q===Y)return J?"active":"merged";if(vY($,Z,"HEAD"))return"merged";if(vY($,"HEAD",Z))return"active";return"stale"}function vY($,Z,J){try{return j$($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function _3($){let Z=new Map,J=j$($,["worktree","list","--porcelain"]),Q="";for(let Y of J.split(`
188
+ `)){if(Y.startsWith("worktree ")){Q=Y.slice(9);continue}if(Y.startsWith("branch refs/heads/")&&Q)Z.set(Y.slice(18),Q)}return Z}function j$($,Z){try{return Cq("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(q3(J))}}function q3($){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 uq($){return/not a git repository/i.test(q3($))}var r1="work/",vq,u9;var iY=k(()=>{vq=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,u9=new Map});function b0($){return IY(a$($.sessionName)??$.sessionName)}function e1($){return S4(b0($))}function oY($){let Z=a$($.sessionName)??$.sessionName,J=b0($),Q=S4(J);if(J===Z)return Q;let Y=Z.slice(J.length+1,-1);return s1(Q,J,Y)}function aY($){let Z=$.currentProvider()==="claude"?wY:bY,J=d9($);return J?`${Z}
189
+ ${J}`:Z}function B3($){return d9($)?"已载入wt特殊约定":null}function rY($,Z){let J=B3($);return J?`${Z}
190
+ ${J}`:Z}function d9($){let Z=b0($),J=cY($.workDir,e1($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
191
+ `)}async function tY($,Z,J){if(!Z){await j3($);return}let Q=_1(Z);if(!Q){await O($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await O($.chatId,"❌ 找不到发起人,不能拉群。");return}let Y=b0($),H=e1($);try{await l9(H,async()=>{let X;try{X=uY(H,Y,Q)}catch(V){await O($.chatId,`❌ wt 失败: ${U(V)}`);return}try{let V=await w6(X.chatName,J),W=V.created?"已创建":V.joined?"已加入":"已在群内";if(!await c($.chatId,g2({slug:Q,branch:X.branch,status:W})))await y($.chatId,`❌ wt 卡片失败: ${Q}`);if(!await c(V.chatId,g2({slug:Q,branch:X.branch,status:"就绪",body:"开始吧。"})))await y(V.chatId,`❌ wt 卡片失败: ${Q}`)}catch(V){await O($.chatId,`❌ wt 已建,拉群失败: ${U(V)}`)}})}catch(X){await O($.chatId,`❌ wt 失败: ${U(X)}`)}}async function sY($,Z){let J=b0($),Q=e1($);return await l9(Q,async()=>{return await lq($,J,Q,Z)})}async function lq($,Z,J,Q){let Y=mY(J,Z),H=Y.filter((W)=>W.state==="merged"&&!W.mounted).length,X=Y.filter((W)=>W.state!=="merged"||W.mounted),V=await w4();return A7({projectName:Z,projectDir:J,hiddenMergedUnmountedCount:H,notice:Q,entries:X.map((W)=>{let G=V.get(W.chatName)??[],K=Q$.get(W.chatName),_=K&&G.includes(K)?K:G.length===1?G[0]:null;return{slug:W.slug,chatName:W.chatName,branch:W.branch,state:W.state,path:W.worktreePath??W.expectedPath,mounted:W.mounted,dirtyCount:W.dirtyCount,statusLine:W.statusLine,error:W.error,chatId:_,duplicateChatCount:G.length}})})}async function j3($){try{let Z=await sY($);if(!await c($.chatId,Z))await y($.chatId,"❌ wt 列表失败")}catch(Z){await O($.chatId,`❌ wt 列表失败: ${U(Z)}`)}}async function nY($,Z,J,Q){try{return{ok:Z,message:J,card:await sY($,{type:Q,content:J})}}catch(Y){let H=`列表刷新失败: ${U(Y)}`;return z(`session "${$.sessionName}": wt action panel refresh failed: ${U(Y)}`),{ok:!1,message:`${J}
192
+ ${H}`,card:g2({slug:"wt",branch:"work/*",status:J,body:H,template:"red"})}}}async function eY($,Z){let J=_1(Z);if(!J)return nY($,!1,"❌ 名称无效","error");let Q=b0($),Y=e1($),H;try{H=await l9(Y,async()=>{let X=t1(Q,J);if($.hasRunningPeerSession(X))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${X} 群里 stop 或 kill。`,type:"error"};z3(Y,Q,J);let V=await v6(X),W=pY(Y,Q,J);return{ok:!0,message:[`✅ ${J} 已解散`,W.removedWorktree?"dir removed":"dir missing",V.disbanded?"group removed":"group missing",W.branch].join(`
193
+ `),type:"success"}})}catch(X){H={ok:!1,message:`❌ 解散 ${J} 失败: ${U(X)}`,type:"error"}}return nY($,H.ok,H.message,H.type)}var $H=k(()=>{fY();w$();n();w();iY()});import{closeSync as iq,openSync as nq,readSync as oq,readdirSync as aq,statSync as rq}from"node:fs";import{randomUUID as D3}from"node:crypto";import{join as tq}from"node:path";function n9($){return a$($.sessionName)??$.sessionName}function JH($){let Z=N6($,L3);return L3.add(Z),Z}function QH($){L3.delete($)}function $2($){let Z=ZH.get($);if(!Z)Z=new Map,ZH.set($,Z);let J=Date.now();for(let[Q,Y]of Z){let H=Y.status==="consumed"?$B:eq,X=Y.consumedAt??Y.createdAt;if(J-X>H)Z.delete(Q)}return Z}function JB($,Z){return $.provider===Z.provider&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function YH($,Z,J,Q){let Y={id:D3(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:n9($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Q};return $2($).set(Y.id,Y),Y}function A3($,Z,J,Q,Y){let H=$2($).get(J);if(!H||H.mode!==Z)return{error:"这张选择卡已过期,请重新发送命令"};if(!Y||H.requesterOpenId!==Y)return{error:"只有打开这张选择卡的用户可以执行;请自行发送命令重新打开"};if(H.status!=="open")return{error:"这张选择卡已执行或正在处理,请勿重复点击"};if(H.provider!==$.selectedProvider||H.workDir!==$.workDir||H.sourceSessionId!==$.lastSessionId||!JB(H.routing,$.conversationRouting()))return{error:"这张卡对应的 provider、目录或源会话已经变化,请重新发送命令"};let X=H.choices.get(Q);if(!X)return{error:"无效的选择项,这张卡可能已过期"};return H.status="processing",{panel:H,choice:X}}function i9($){$.status="consumed",$.consumedAt=Date.now()}function QB($){return{kind:"fork",source:$.source,through:$}}function YB($){return v1($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function HB($){let Z=U2($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return z$(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function XB($){let Z=W6($),J;try{J=aq(Z)}catch(Y){if(Y?.code==="ENOENT")return[];throw Error(`读取 Claude 会话目录失败: ${Y?.message??Y}`)}let Q=[];for(let Y of J){if(!Y.endsWith(".jsonl"))continue;let H=tq(Z,Y),X;try{X=rq(H).mtimeMs}catch(V){throw Error(`读取 Claude 会话元数据失败 (${Y}): ${V?.message??V}`)}Q.push({provider:"claude",sessionId:Y.slice(0,-6),cwd:$,preview:WB(H),ts:X})}return Q.sort((Y,H)=>H.ts-Y.ts)}function VB($){let Z=$.slice().sort((Y,H)=>H.ts-Y.ts),J=Date.now()-sq,Q=Z.filter((Y)=>Y.ts>=J).length;return Z.slice(0,Math.min(ZB,Math.max(10,Q)))}function WB($){let Z="",J=null;try{J=nq($,"r");let Y=Buffer.alloc(65536),H=oq(J,Y,0,65536,0);Z=Y.subarray(0,H).toString("utf8")}catch(Y){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Y?.message??Y}`)}finally{if(J!==null)iq(J)}let Q="";for(let Y of Z.split(`
194
+ `)){let H=Y.trim();if(!H)continue;let X;try{X=JSON.parse(H)}catch{continue}if(X.type==="queue-operation"&&X.operation==="enqueue"&&typeof X.content==="string"){let V=X.content.trim();if(V)return V.slice(0,80)}if(!Q&&X.type==="user"&&X.message){let V=GB(X.message);if(V)Q=V}}return Q.slice(0,80)}function GB($){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 HH($,Z,J){if(!J){await O($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Q=YB($),Y=HB($),H=new Map,X=[];for(let K=0;K<Q.length;K++){let _=Q[K];if(K===0&&Y===null)continue;let B=D3(),j=K===0?Y:QB(Q[K-1].checkpoint);H.set(B,{kind:Z,launch:j,branchBase:Y,seedAnchors:Q.slice(0,K),writes:Q.slice(K).flatMap((L)=>L.writes)}),X.push({choiceId:B,preview:_.preview,ts:_.ts})}X.reverse();let V=YH($,Z,J,H),W=P7({projectName:n9($),panelId:V.id,mode:Z,entries:X}),G;try{G=await c($.chatId,W)}catch(K){throw $2($).delete(V.id),K}if(!G)$2($).delete(V.id),await y($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function XH($,Z){return HH($,"fork",Z)}function VH($,Z){return HH($,"back",Z)}async function WH($,Z){if(!Z){await O($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():XB($.workDir)}catch(W){await y($.chatId,`❌ 历史会话读取失败: ${W instanceof Error?W.message:W}`);return}let Q=new Map,Y=VB(J).map((W)=>{let G=D3();return Q.set(G,{kind:"resume",launch:{kind:"fork",source:{provider:W.provider,sessionId:W.sessionId,cwd:W.cwd}},sourcePreview:W.preview,sourceTs:W.ts,sourceStatus:W.status}),{choiceId:G,preview:W.preview,ts:W.ts}}),H=YH($,"resume",Z,Q),X=U7({projectName:n9($),panelId:H.id,entries:Y}),V;try{V=await c($.chatId,X)}catch(W){throw $2($).delete(H.id),W}if(!V)$2($).delete(H.id),await y($.chatId,"❌ rs 历史列表发送失败")}async function GH($,Z){if(!Z){await O($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await O($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=JH(n9($));await O($.chatId,`\uD83D\uDE80 正在创建 ${J} · ${$.backendLabel()} 新会话。它与当前群共享工作目录;当前会话不受影响。`);let Q;try{Q=await $.opts.onCreateTempSession({chatName:J,userOpenId:Z,workDir:$.workDir,routing:$.conversationRouting(),launch:{kind:"fresh"},branchBase:{kind:"fresh"},seedAnchors:[]})}finally{QH(J)}if(!Q.ok){await O($.chatId,`❌ 建临时会话失败: ${Q.error??"未知"}`);return}await O($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function zH($){if(!a$($.sessionName)){await O($.chatId,"❌ bye 只能在带 *MMDD-HHMM 后缀的临时会话群里使用。");return}if(!$.opts.onDisbandTempSession){await O($.chatId,"❌ 解散能力未就绪(daemon 未注入回调)。");return}await O($.chatId,`\uD83D\uDC4B 正在停止会话并解散 ${$.sessionName}…`);let Z=await $.opts.onDisbandTempSession($.sessionName,$.chatId);if(!Z.ok)await O($.chatId,`❌ 解散失败: ${Z.error??"未知"}`)}async function KH($,Z,J,Q){let Y=A3($,"fork",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:H,choice:X}=Y;try{if(X.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let V=JH(H.baseName);z(`session-temp: fork ${$.sessionName} → ${V} (${X.launch.kind})`),await O($.chatId,`\uD83D\uDD31 正在分叉到 ${V}…`);let W;try{W=await $.opts.onCreateTempSession({chatName:V,userOpenId:Q,workDir:H.workDir,routing:H.routing,launch:X.launch,branchBase:X.branchBase,seedAnchors:X.seedAnchors})}finally{QH(V)}if(!W.ok)return{ok:!1,message:`分叉失败: ${W.error??"未知"}`};return{ok:!0,message:`已分叉到 ${V};原会话和磁盘文件未回滚`}}catch(V){return{ok:!1,message:`分叉失败: ${V instanceof Error?V.message:V}`}}finally{i9(H)}}async function _H($,Z,J,Q){let Y=A3($,"back",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:H,choice:X}=Y;try{if(X.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let V="";try{if(!await c($.chatId,M7({projectName:H.baseName,entries:X.writes})))V=";文件变更记录卡发送失败"}catch(K){V=`;文件变更记录卡发送失败: ${K instanceof Error?K.message:K}`}if(z(`session-temp: back ${$.sessionName} (${X.launch.kind}, writes=${X.writes.length})`),!await $.rollbackTo(X.launch,{anchors:X.seedAnchors,base:X.branchBase}))return{ok:!1,message:`回退失败;原会话绑定未改,请检查日志后重试${V}`};if(H.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${V}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${G$($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${V}`}}catch(V){return{ok:!1,message:`回退失败: ${V instanceof Error?V.message:V}`}}finally{i9(H)}}async function qH($,Z,J,Q){let Y=A3($,"resume",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:H,choice:X}=Y;if(X.kind!=="resume")throw i9(H),Error("resume panel contained a non-resume choice");let V=X.launch.source.sessionId,W=$.lastSessionId,G=(_,B)=>({projectName:H.baseName,provider:X.launch.source.provider,selectedPreview:X.sourcePreview,selectedTs:X.sourceTs,sourceSessionId:V,...X.sourceStatus?{sourceStatus:X.sourceStatus}:{},previousSessionId:W,newSessionId:_,bindingState:B}),K=(_,B,j,L=null)=>({ok:_,message:B,resumePresentation:G(L,j)});try{if($.isRunning())return K(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(X.sourceStatus==="active")return K(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(z(`session-temp: history fork ${$.sessionName} ← ${X.launch.source.provider} ${V}`),!await $.rollbackTo(X.launch,{anchors:[],base:X.launch,pendingLaunch:X.launch.source.provider==="claude"?{launch:X.launch,previousSessionId:W}:null}))return K(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(X.launch.source.provider==="claude")return K(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let B=$.lastSessionId;if(!B)return K(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(B===V||W&&B===W)return K(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",B);return K(!0,"已创建并接入独立分支;源会话未修改","changed",B)}catch(_){return K(!1,`历史分支创建失败: ${_ instanceof Error?_.message:_}`,"unknown")}finally{i9(H)}}var sq=86400000,eq=1800000,$B=3600000,ZB=40,ZH,L3;var BH=k(()=>{n();w$();w();O4();T1();ZH=new WeakMap,L3=new Set});import{existsSync as jH}from"node:fs";import{randomBytes as KB,timingSafeEqual as _B}from"node:crypto";import{isAbsolute as qB}from"node:path";function P3($,Z=new Set){if($ instanceof B4)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Q=P3(J,Z);if(Q)return Q}if($ instanceof Error&&$.cause!==void 0)return P3($.cause,Z);return null}function BB($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function jB($){return $.itemId||$.turnId||"__latest__"}function LH($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function LB($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function DB($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function q1(){return b.runtime?.live_elapsed??"bucket"}function AH($,Z){return`${$} (${M0(Date.now()-Z,q1()).label})`}var AB="Thinking...",FB="Writing...",PB="Working...",F3=1e4,o9=120000,UB=50,l2=5,MB=256,a9=1e4,DH=250,B1;var FH=k(()=>{E1();r8();c0();N$();P$();p5();O4();t0();w$();n();w();D$();z7();E9();k9();c7();zQ();RQ();NQ();r7();wQ();rQ();sQ();VY();UY();yY();$H();BH();T1();B1=class B1{sessionName;chatId;opts;static all=new Set;proc=null;lifecycleTail=Promise.resolve();lifecycleSequence=0;procEpoch=0;stoppingProc=null;blockedProc=null;blockedProcReason=null;consultCapability=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;B1.all.add(this);let Q=C6($);this.selectedProvider=Q?.provider??"claude",this.selectedModel=Q?.model??null,this.selectedEffort=Q?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Q);let Y=Z$(this.selectedTokenSourceId);if(Y){if(this.selectedProvider=Y.agent,Y.id==="glm"&&this.selectedModel==="claude:glm")this.selectedModel=Y.defaultModel,this.selectedEffort="max";if(Y.id==="claude-native"&&this.selectedModel&&!Y.models.some((X)=>X.model===this.selectedModel))this.selectedModel=Y.defaultModel}if(this.selectedModel)z(`session "${$}": restored selected provider=${this.selectedProvider} model=${this.selectedModel} effort=${this.selectedEffort??"unset"}`);if(this.lastSessionRef=o0($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)z(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let H=M2($);if(H)if(this.selectedProvider!=="claude")C$($,[],null,null),z(`session "${$}": cleared pending Claude fork after provider changed`);else{z$(H.launch,"claude",this.workDir);let X=this.lastSessionId===H.previousSessionId,V=this.lastSessionRef,W=!X&&V?.provider==="claude"&&V.cwd===this.workDir&&V.sessionId!==H.launch.source.sessionId&&V.sessionId!==H.previousSessionId;if(!X&&!W)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=H,z(`session "${$}": restored ${W?"materialized":"pending"} Claude fork source=${H.launch.source.sessionId}`)}}peerSnapshot(){return{name:this.sessionName,status:this.status,uptimeMs:this.startedAt?Date.now()-this.startedAt:void 0}}get workDir(){return oY(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 A4(J==="codex"?"codex":"claude")[0]?.id??null}currentTokenSource(){return Z$(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=Z$($.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=o0(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,y6(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId)}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");if(!E2())throw Error("Codex 未登录 ChatGPT 账号");let $=this.currentTokenSource();if(this.selectedTokenSourceId&&(!$||!$.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Z=$?.enabled?$:void 0,J=Z?(V)=>Z.spawnEnv(V):void 0,Q=new I0({workDir:this.workDir,launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J}),Y=null,H=null;try{Y=await Q.listConversations()}catch(V){H=V}let X=null;try{await Q.kill(2000)}catch(V){X=V}if(H&&X)throw AggregateError([H,X],`Codex history query and cleanup failed: ${U(H)}; ${U(X)}`);if(H)throw H;if(X)throw X;return Y??[]}async resolveLegacyResumeRef($){if($.cwd!==null)return $;if($.provider!==this.selectedProvider)throw Error(`legacy resume provider mismatch: ${$.provider} != ${this.selectedProvider}`);let Z;if($.provider==="claude"){let J=G6(this.workDir,$.sessionId);if(!jH(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${G$($.sessionId)}`);Z={...$,cwd:this.workDir}}else{if(!E2())throw Error("Codex 未登录 ChatGPT 账号");let J=this.currentTokenSource();if(this.selectedTokenSourceId&&(!J||!J.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Q=J?.enabled?J:void 0,Y=new I0({workDir:this.workDir,launch:{kind:"fresh"},tokenSourceId:Q?.id??null,transformEnv:Q?(V)=>Q.spawnEnv(V):void 0}),H=null;try{Z=await Y.readConversationRef($.sessionId)}catch(V){H=V,Z=$}let X=null;try{await Y.kill(2000)}catch(V){X=V}if(H&&X)throw AggregateError([H,X],`Codex legacy resume lookup and cleanup failed: read=${U(H)}; cleanup=${U(X)}`);if(H)throw H;if(X)throw X}return z$({kind:"resume",source:Z},this.selectedProvider,this.workDir),P2(this.sessionName,Z),Z}hasRunningPeerSession($){return[...B1.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:W2}return W2}claudeEffortForSpawn(){return this.selectedProvider==="claude"&&o$(this.selectedEffort)?this.selectedEffort:R0}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"?R0:W2)}runtimeModelSelection(){let $=this.proc?.isAlive()?this.proc:null,Z=$?.provider??this.selectedProvider,J=!$||$.provider===this.selectedProvider,Q=($?.lastModel??(J?this.currentModelLabel():null))?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null,Y=$?.lastEffort??(J?this.currentEffortLabel():Z==="claude"?R0:W2);return{provider:Z,model:Q,effort:Y}}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"?`${H0($.provider)} · ${J}`:J}withModel($,Z){let J=this.modelEffortLabel(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return i($,M.footer,this.footerElement(Z))}footerElement($){return{tag:"markdown",element_id:M.footer,content:$.trim()||" "}}modelLine($){return this.modelEffortLabel($)}backendLabel($=this.selectedProvider){return H0($)}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.consultCapability=KB(32).toString("base64url");let Z={LODESTAR_CONSULT_URL:BB(b.notify.bind,b.notify.port),LODESTAR_CONSULT_CAPABILITY:this.consultCapability,LODESTAR_CONSULT_SESSION:this.sessionName},J=this.pendingConversationLaunch??this.pendingMaterializationLaunch()??($?{kind:"resume",source:$}:{kind:"fresh"});z$(J,this.selectedProvider,this.workDir);let Q=this.currentTokenSource();if(this.selectedTokenSourceId&&(!Q||!Q.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或在 model 面板选择其他账号`);let Y=Q?.enabled?Q:void 0,H=Y?(W)=>Y.spawnEnv(W):void 0,X=Y?Y.resolveSpawnModel(this.selectedModel??Y.defaultModel):this.modelForSpawn();if(this.selectedProvider==="claude"){XZ();let W=J.kind==="fresh"?void 0:J.source.sessionId,G=J.kind==="fork"?J.through:void 0;if(G&&(G.provider!=="claude"||G.kind!=="assistant-message"))throw Error(`Claude cannot fork from ${G.provider}/${G.kind} checkpoint`);let K=new D2({workDir:this.workDir,model:X,effort:this.claudeEffortForSpawn(),resumeSessionId:W,resumeSessionAt:G?.id,forkSession:J.kind==="fork",appendSystemPrompt:this.spawnDeveloperInstructions(),profile:C4(this.worktreeProjectName()),...Y?.settingSources?{settingSources:Y.settingSources}:{},...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:e2},tokenSourceId:Y?.id??null,transformEnv:H,hostEnv:Z});return this.procSourceRevisions.set(K,Y?.spawnRevision??null),K}let V=new I0({workDir:this.workDir,model:X,effort:this.effortForSpawn(),launch:J,appendSystemPrompt:this.spawnDeveloperInstructions(),tokenSourceId:Y?.id??null,transformEnv:H,hostEnv:Z});return this.procSourceRevisions.set(V,Y?.spawnRevision??null),V}async applyModelSelection($,Z,J,Q){await this.runLifecycle("apply-model-selection",()=>this.applyModelSelectionUnlocked($,Z,J,Q))}async applyModelSelectionUnlocked($,Z,J,Q){if(this.selectedProvider!==$)C$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=Q??this.selectedTokenSourceId;let H=Z$(this.selectedTokenSourceId);if(H)this.selectedModel=Z||null,this.selectedEffort=J??H.models.find((X)=>X.model===Z)?.defaultEffort??H.models[0]?.defaultEffort??null;else this.selectedModel=$==="codex"?null:Z,this.selectedEffort=$==="codex"?null:J;this.lastSessionRef=o0(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null,x6(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;z(`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 Q=await this.settleProcResumableState(J),Y=null;try{await J.kill(1000)}catch(V){Y=V}Q=await this.settleProcResumableState(J);let H=this.finishProcStop(J,Y);this.opts.onLifecycleChange?.();let X=[...!H?[Y??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...Q?[Error(Q)]:[]];if(X.length===1)throw X[0];if(X.length>1)throw AggregateError(X,`idle process stop failed: ${X.map(U).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;z(`session "${this.sessionName}": stop idle ${Z.provider} process: ${$}`),this.beginProcStop(Z),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let J=await this.settleProcResumableState(Z),Q=null;try{await Z.kill(1000)}catch(X){Q=X}J=await this.settleProcResumableState(Z);let Y=this.finishProcStop(Z,Q);this.opts.onLifecycleChange?.();let H=[...!Y?[Q??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...J?[Error(J)]:[]];if(H.length===1)throw H[0];if(H.length>1)throw AggregateError(H,`idle process stop failed: ${H.map(U).join("; ")}`);return!0}startFooterTimer($,Z,J=(Q)=>Q){let Q=Date.now(),Y=Z,H=!1,X=()=>{if(H)return;this.replaceFooterContent($,J(AH(Y,Q)))},V=null,W=()=>{if(H)return;let{nextDelayMs:G}=M0(Date.now()-Q,q1());V=setTimeout(()=>{X(),W()},Math.max(1,Math.ceil(G)))};return X(),W(),{setStatus(G){Y=G,X()},stop(){if(H=!0,V)clearTimeout(V)},elapsedSec(){return((Date.now()-Q)/1000).toFixed(1)}}}async openStatusCard($,Z,J="blue"){let Q=Date.now(),Y=K7({sessionName:this.sessionName,title:$,status:AH(Z,Q),template:J}),H=await c(this.chatId,Y);if(!H)return z(`session "${this.sessionName}": status card send failed title=${$}`),await y(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let X;try{X=await r$(H)}catch(V){return z(`session "${this.sessionName}": status card id_convert failed title=${$}: ${V}`),await y(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return c$(X,1),{cardId:X,title:$,timer:this.startFooterTimer(X,Z,(V)=>h2($,V))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Q=h2($.title,`${Z} (${J}s)`);await m$($.cardId);let Y=await U$($.cardId,M.footer,this.footerElement(Q));V$($.cardId);let H=await q$($.cardId,p$({durationSec:J,suffix:Z}));if(Y&&H)await S$($.cardId);else{let X=`footer=${Y?"ok":"MISS"}, settings=${H?"ok":"MISS"}`;z(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${X}`),await y(this.chatId,`⚠️ 状态卡片终态写入失败 (${X}):${Z}`)}}async runLifecycle($,Z){let J=this.lifecycleTail,Q;this.lifecycleTail=new Promise((H)=>{Q=H}),await J;let Y=++this.lifecycleSequence;z(`session "${this.sessionName}": lifecycle#${Y} ${$} begin`);try{return await Z()}finally{Q(),z(`session "${this.sessionName}": lifecycle#${Y} ${$} end`)}}async waitForLifecycleIdle(){await this.lifecycleTail}beginTurnOpen($=this.proc,Z=this.procEpoch,J=!1){if(this.openingTurnOwner)throw Error(`turn card open already owned by token=${this.openingTurnOwner.token}; same-process opens must wait for the current owner`);let Q,Y=new Promise((X)=>{Q=X}),H={token:++this.turnOpenSequence,proc:$,procEpoch:Z,sawResult:!1,terminalForcePush:!1,pendingCompactions:[],backendTurnStarted:J,done:Y,resolveDone:Q};return this.openingTurnOwner=H,this.openingTurn=!0,H}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.consultCapability=null,this.stoppingProc===$)this.stoppingProc=null;if(this.blockedProc===$)this.blockedProc=null,this.blockedProcReason=null;return this.procEpoch++,!0}beginProcStop($){this.stoppingProc=$,this.consultCapability=null}acceptsConsultCapability($){let Z=this.consultCapability;if(!Z||!$||!this.proc?.isAlive())return!1;let J=Buffer.from(Z),Q=Buffer.from($);return J.length===Q.length&&_B(J,Q)}async cancelConsultRuns($="用户取消"){await this.opts.onCancelConsultRuns?.(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?U(Z):"kill returned while process still reports alive",z(`session "${this.sessionName}": process stop unconfirmed; lifecycle blocked: ${this.blockedProcReason}`),!1}blockedProcessMessage(){let $=this.blockedProc;if(!$)return null;if(!$.isAlive())return this.detachProc($),null;return`旧 ${this.backendLabel($.provider)} 进程尚未确认退出,会话已阻断: ${this.blockedProcReason??"未知原因"}`}async stopOwnedProc($,Z){if(this.proc!==$)return!$.isAlive();this.beginProcStop($);let J=null;try{await $.kill(Z)}catch(Q){J=Q}return this.finishProcStop($,J)}async settleProcResumableState($){let Z=null,J=$.conversationMaterializationBarrier?.();if(J)try{await J}catch(H){Z=`Codex 会话落盘确认失败: ${U(H)}`}let Q=$.conversationMaterializationFailure?.();if(Q&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${U(Q)}`;let Y=this.persistResumableSessionId(!1,$,!1);return[Z,Y].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,Q=this.blockedProcessMessage();if(Q){if(this.status="stopped",J?.(`❌ ${Q}`),Z)await O(this.chatId,`❌ ${Q}。请重试 stop/restart,或等待旧进程退出。`);return!1}if(this.proc&&!this.proc.isAlive())this.detachProc(this.proc);if(this.isRunning()){if(this.proc?.provider===this.selectedProvider)return J?.(this.withModel(`✅ ${this.backendLabel()} 已运行`)),!0;if(await this.stopIdleMismatchedProcessUnlocked(),this.proc?.isAlive())return J?.(`⚠️ 当前 ${this.backendLabel(this.proc.provider)} turn 尚未结束,模型切换将在后续新 turn 生效`),!0}if(this.selectedProvider==="codex")J?.("\uD83D\uDD0E 检查 Codex 登录");else J?.("\uD83D\uDD0E 检查 Claude Code");if(this.selectedProvider==="codex"&&!E2()){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z)await O(this.chatId,"❌ Codex 未登录 ChatGPT 账号。\n请在服务器上运行 `codex login` 后再试。");return!1}if(!jH(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await O(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{m6(this.workDir)}catch(K){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${K}`),Z)await O(this.chatId,`❌ 创建项目失败: ${K}`);return!1}}if(!$.freshConversationStateAlreadyReset&&!this.pendingConversationMaterialization)this.resetFreshConversationState();this.status="starting",J?.(this.withModel(`\uD83D\uDE80 启动 ${this.backendLabel()}`));let Y;try{Y=this.spawnAgent()}catch(K){let _=`${this.backendLabel()} 启动失败: ${U(K)}`;if(z(`session "${this.sessionName}": ${_}`),J?.(`❌ ${_}`),Z)await O(this.chatId,`❌ ${_}`);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}this.attachProc(Y);let H=this.backendLabel(),X=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(Y,DH):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${H} 启动`:`⏳ 等待 ${H} init`);let V,W=null;try{if(Y.sendInitialize(),this.selectedProvider==="codex")V=Y.initializationPromise?.()}catch(K){V=void 0,W=K}let G=W?{state:"error",error:W}:this.selectedProvider==="claude"?await X:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(V),()=>{z(`session "${this.sessionName}": codex init still pending after ${F3/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${H} init 确认`))});if(G.state==="error"||G.state==="exit"){let K=G.error?U(G.error):G.state;z(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${K}`);let B=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,j=`❌ ${H} 启动失败: ${K}${B}`;if(J?.(j),Z)await O(this.chatId,j);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(G.state==="timeout"){z(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${o9/1000}s)`);let _=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,B=`❌ ${H} 启动超时: ${o9/1000} 秒内初始化事务未完成${_}`;if(J?.(B),Z)await O(this.chatId,B);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Y||!Y.isAlive()){let K=`${H} 启动期间已退出`;if(z(`session "${this.sessionName}": ${K}`),J?.(`❌ ${K}`),Z)await O(this.chatId,`❌ ${K}`);return this.detachProc(Y),this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(Z){let K=this.modelLine();await O(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),K].filter(Boolean).join(`
195
+ `))}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 Q=!1,Y=(V,W)=>{if(Q)return;Q=!0,clearTimeout(H),clearTimeout(X),J({state:V,error:W})},H=setTimeout(()=>{if(Q)return;try{Z?.()}catch(V){Y("error",V)}},F3),X=setTimeout(()=>{Y("timeout",Error(`codex init timed out after ${o9/1000}s`))},o9);$.then(()=>Y("init"),(V)=>Y("error",V))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Q=!1,Y=(G,K)=>{if(Q)return;Q=!0,clearTimeout(H),$.off("init",X),$.off("error",V),$.off("exit",W),J({state:G,error:K})},H=setTimeout(()=>Y("ready"),Z),X=()=>Y("init"),V=(G)=>Y("error",G),W=(G)=>Y("exit",G);$.once("init",X),$.once("error",V),$.once("exit",W)})}releaseAllReactions(){for(let[$,Z]of[...this.pendingReactionIds.entries(),...this.currentBatchReactionIds.entries()])if(Z)A$($,Z);this.pendingReactionIds=new Map,this.currentBatchReactionIds=new Map}clearStaleIdleQueueState($){if(this.initCount<1||this.currentTurn||this.openingTurn||this.pendingUserMessageCount===0)return;z(`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)A$(Z,J);this.pendingReactionIds=new Map}async stop($="已终止",Z={}){await this.runLifecycle("stop",()=>this.stopUnlocked($,Z))}async stopUnlocked($="已终止",Z={}){let J=Z.announce??!0,Q=Z.onStatus;if(await this.cancelConsultRuns($),!this.proc){if(this.status="stopped",this.opts.onLifecycleChange?.(),Q?.("⚪ session 当前未运行"),J)await O(this.chatId,`⚪ session "${this.sessionName}" 当前未运行`);return}let Y=this.proc,H=this.persistResumableSessionId(!1,Y,!1),X=null;if(Q?.(`\uD83D\uDED1 停止 ${this.backendLabel(this.proc.provider)}`),z(`session "${this.sessionName}": stop (${$})`),this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((P)=>{z(`session "${this.sessionName}": stop current main-card close failed: ${U(P)}`)});let V=this.waitForTurnCloses().catch((P)=>z(`session "${this.sessionName}": stop main-card close failed: ${U(P)}`));this.beginProcStop(Y),this.status="stopped";let W=[];try{this.opts.onLifecycleChange?.()}catch(P){W.push(P),z(`session "${this.sessionName}": stop intent lifecycle write failed: ${U(P)}`)}let G=Y.conversationMaterializationBarrier?.();if(G){try{await G}catch(P){X=`Codex 会话落盘确认失败: ${U(P)}`}H=this.persistResumableSessionId(!1,Y,!1)}this.clearMultiMsgBuffer("stop"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.bgResumePending=!1,this.discardOrphanAssistant(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1;let K=null;try{await Y.kill()}catch(P){K=P}let _=Y.conversationMaterializationFailure?.();if(_&&Y.isConversationResumable?.()!==!0)X=`Codex 会话落盘确认失败: ${U(_)}`;H=this.persistResumableSessionId(!1,Y,!1);let j=(await Promise.allSettled([this.resetBackgroundTasks(),V])).filter((P)=>P.status==="rejected").map((P)=>P.reason);for(let P of j)z(`session "${this.sessionName}": stop terminal cleanup failed: ${U(P)}`);let L=this.finishProcStop(Y,K);try{this.opts.onLifecycleChange?.()}catch(P){W.push(P),z(`session "${this.sessionName}": stop final lifecycle write failed: ${U(P)}`)}let A=[...K?[K]:[],...!L&&!K?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...j,...W,...H?[Error(H)]:[],...X&&Y.isConversationResumable?.()!==!0?[Error(X)]:[]];if(A.length===1)throw A[0];if(A.length>1)throw AggregateError(A,`stop failed: ${A.map(U).join("; ")}`);if(Q?.(`✅ ${$}`),J)await O(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 Q=Z.announce??!0,Y=Z.onStatus,H=this.status,X=null;if(!$&&!this.pendingConversationLaunch&&this.pendingConversationMaterialization)X=this.pendingConversationMaterialization,T0(this.sessionName,null),this.pendingConversationMaterialization=null;let V=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),W=this.lastSessionRef;if($&&!V&&W?.cwd===null)try{W=await this.resolveLegacyResumeRef(W),this.lastSessionRef=W,this.lastSessionId=W.sessionId}catch(T){let E=this.invalidateMissingCodexResume(W.sessionId,T,J),u=E?`❌ 旧会话不可恢复: ${U(T)};${E}`:`❌ 旧会话 cwd 校验失败: ${U(T)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?H:"stopped",Y?.(u),Q)await O(this.chatId,u);return!1}let G=W?.sessionId??null,K=V&&V.kind!=="fresh"?V.source.sessionId:G,_=K?G$(K):"",B=null,j=(T=this.proc)=>{if(!$||V||T?.provider!=="codex"||T.isConversationResumable?.()!==!0)return;B=this.persistResumableSessionId(!1,T,!1),W=this.lastSessionRef,G=W?.sessionId??null,K=G,_=K?G$(K):""},L=null;if(!Y&&Q&&$&&G){let T=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${_}`);if(L=await this.openStatusCard("restart",T),L)Y=(E)=>this.setStatusCard(L,E)}let A=Q&&!L,P=async(T)=>{if(L)await this.closeStatusCard(L,T)},R=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)=>{z(`session "${this.sessionName}": restart current main-card close failed: ${U(T)}`)});let D=this.waitForTurnCloses().catch((T)=>z(`session "${this.sessionName}": restart main-card close failed: ${U(T)}`)),F=null,N=null;if(this.proc){let T=this.proc;Y?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(T.provider)}`),N=T,this.beginProcStop(T);let E=T.conversationMaterializationBarrier?.();if(E)try{await E}catch(p){B=`Codex 会话落盘确认失败: ${U(p)}`}if(j(T),$&&!V&&B&&!R&&T.isAlive()){if(this.stoppingProc===T)this.stoppingProc=null;this.status=H;let p=`❌ ${this.backendLabel(T.provider)} 恢复点尚未安全落盘,已保留当前进程: ${B}`;if(z(`session "${this.sessionName}": abort restart before kill: ${B}`),Y?.(p),A)await O(this.chatId,p);return await P(p),!1}try{await T.kill()}catch(p){F=p}let u=T.conversationMaterializationFailure?.();if(u&&T.isConversationResumable?.()!==!0)B=`Codex 会话落盘确认失败: ${U(u)}`;j(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(),D])).filter((T)=>T.status==="rejected").map((T)=>T.reason);for(let T of x)z(`session "${this.sessionName}": restart terminal cleanup failed: ${U(T)}`);let m=N?this.finishProcStop(N,F):!0,I=[...F?[`kill=${U(F)}`]:[],...!m&&!F?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...x.map((T)=>`cleanup=${U(T)}`),...B?[`resume=${B}`]:[]];if(I.length>0&&X)try{T0(this.sessionName,X),this.pendingConversationMaterialization=X}catch(T){I.push(`pendingRestore=${U(T)}`)}if(I.length>0){let T=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${I.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.(T),A)await O(this.chatId,T);return await P(T),!1}let f=V?.kind==="resume"||V?.kind==="fork";if($&&W||f){this.status="starting",this.usageTotalsSeedUnknown=!0,Y?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${_}`));let T;try{T=this.spawnAgent(W??void 0)}catch(F$){let n$=`❌ ${this.backendLabel()} 恢复失败: ${U(F$)}`;if(z(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${U(F$)}`),Y?.(n$),A)await O(this.chatId,n$);return this.status="stopped",this.opts.onLifecycleChange?.(),await P(n$),!1}this.attachProc(T);let E=this.backendLabel(),u=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(T,DH):null;Y?.(this.selectedProvider==="claude"?`⏳ 检查 ${E} 恢复启动`:`⏳ 等待 ${E} init 确认`);let p,$$=null;try{if(T.sendInitialize(),this.selectedProvider==="codex")p=T.initializationPromise?.()}catch(F$){p=void 0,$$=F$}let o=$$?{state:"error",error:$$}:this.selectedProvider==="claude"?await u:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(p),()=>{z(`session "${this.sessionName}": codex resume init still pending after ${F3/1000}s`),Y?.(this.withModel(`⏳ 仍在等待 ${E} init 确认 thread=${_}`))});if(o.state==="error"||o.state==="exit"||o.state==="timeout"){let F$=o.state==="error"?this.invalidateMissingCodexResume(K,o.error,J):null,n$=[o.error?U(o.error):o.state,F$].filter(Boolean).join(";");z(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${n$}`);let I3=await this.stopOwnedProc(T,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,H8=o.state==="timeout"?`❌ ${E} 恢复超时${I3}`:`❌ ${E} 恢复失败: ${n$}${I3}`;if(Y?.(H8),A)await O(this.chatId,H8);return this.status="stopped",this.opts.onLifecycleChange?.(),await P(H8),!1}if(this.proc!==T||!T.isAlive()){let F$=`❌ ${E} 恢复期间已退出`;if(z(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Y?.(F$),A)await O(this.chatId,F$);return this.detachProc(T),this.status="stopped",this.opts.onLifecycleChange?.(),await P(F$),!1}let P0=this.withModel(this.withWorktreeInstructionNotice(this.selectedProvider==="claude"&&o.state==="ready"?`✅ 已准备恢复上一会话 thread=${_}`:`✅ 已恢复上一会话 thread=${_}`));if(Y?.(P0),A)await O(this.chatId,P0);this.status="idle",this.startedAt=Date.now(),this.opts.onLifecycleChange?.();try{await P(P0)}catch(F$){z(`session "${this.sessionName}": restart succeeded but status-card close failed: ${U(F$)}`),await y(this.chatId,`⚠️ ${P0}
196
+ 状态卡收尾失败: ${U(F$)}`)}return!0}else{if($&&!V){if(Y?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),A)await O(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=M2(this.sessionName),Q=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Q)T0(this.sessionName,Q),this.pendingConversationMaterialization=Q;this.pendingConversationLaunch=$;try{let Y=await this.startUnlocked(Z);if(!Y&&Q)T0(this.sessionName,J),this.pendingConversationMaterialization=J;return Y}catch(Y){if(!Q)throw Y;try{T0(this.sessionName,J),this.pendingConversationMaterialization=J}catch(H){throw AggregateError([Y,H],`fork start and pending-intent restore failed: ${U(Y)}; ${U(H)}`)}throw Y}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{z$($,this.selectedProvider,this.workDir);let Q=Z?{anchors:Z.anchors.slice(),base:Z.base,pendingLaunch:Z.pendingLaunch!==void 0?Z.pendingLaunch:this.selectedProvider==="claude"&&$.kind==="fork"?{launch:$,previousSessionId:this.lastSessionId}:null}:null,Y=this.proc,H=this.lastSessionId,X=this.lastSessionRef,V=v1(this.sessionName).slice(),W=U2(this.sessionName),G=M2(this.sessionName),K={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,f1(this.sessionName,"codex");else if(this.lastSessionId=H,this.lastSessionRef=X,X)P2(this.sessionName,X);else f1(this.sessionName,this.selectedProvider);C$(this.sessionName,V,W,G),this.pendingConversationMaterialization=G,this.turnCounter=K.turnCounter,this.currentGoal=K.currentGoal,this.cumStats=K.cumStats,this.lastTurnDelta=K.lastTurnDelta,this.currentTurnUsageBaseline=K.currentTurnUsageBaseline,this.currentTurnUsageBaselineKnown=K.currentTurnUsageBaselineKnown,this.lastTurnUsage=K.lastTurnUsage,this.usageTotalsSeedUnknown=K.usageTotalsSeedUnknown},j=!1;if(Q?.pendingLaunch)C$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch),this.pendingConversationMaterialization=Q.pendingLaunch,j=!0;this.pendingConversationLaunch=$;let L=(A)=>{_=X?.provider==="codex"&&X.sessionId===A};try{let A;try{A=$.kind==="fresh"?await this.restartUnlocked(!1,J,L):await this.restartUnlocked(!0,J,L)}catch(P){let R=null,D=this.proc&&this.proc!==Y?this.proc:null;if(D)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(x){R=x}let F=!D||this.proc!==D&&!D.isAlive();if(!F&&!R)R=Error("replacement process stop was not confirmed");let N=null;if(F)try{B()}catch(x){N=x}let C=[P,...R?[R]:[],...N?[N]:[]];if(C.length===1)throw P;throw AggregateError(C,`rollback launch and cleanup failed: ${C.map(U).join("; ")}`)}if(!A)return B(),!1;if(Q)try{if(!j)C$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch);this.pendingConversationMaterialization=Q.pendingLaunch}catch(P){let R=null,D=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(x){R=x}let F=!D||this.proc!==D&&!D.isAlive();if(!F&&!R)R=Error("replacement process stop was not confirmed");let N=null;if(F)try{B()}catch(x){N=x}let C=[P,...R?[R]:[],...N?[N]:[]];if(C.length===1)throw P;throw AggregateError(C,`rollback branch commit failed: ${C.map(U).join("; ")}`)}return A}finally{this.pendingConversationLaunch=null}})}dispose(){B1.all.delete(this)}recordTurnAnchor($){let Z=this.proc;if(!Z?.sessionId||!$)return null;if($.provider!==Z.provider||$.source.sessionId!==Z.sessionId||$.source.cwd!==this.workDir){let Q=`拒绝了与当前会话不匹配的 checkpoint provider=${$.provider} source=${$.source.sessionId}`;return z(`session "${this.sessionName}": ${Q}`),this.lastTurnUserPreview="",Q}let J={checkpoint:$,preview:this.lastTurnUserPreview.slice(0,80),ts:Date.now(),writes:this.collectTurnWrites()};if(this.lastTurnUserPreview="",Z.provider==="codex"&&Z.isConversationResumable?.()!==!0){if(this.pendingCodexTurnAnchors.filter((Y)=>Y.proc===Z).length>=64)return z(`session "${this.sessionName}": ${"Codex rollout 长期未确认,延迟 checkpoint 队列已满"} thread=${Z.sessionId}`),"Codex rollout 长期未确认,延迟 checkpoint 队列已满";return this.pendingCodexTurnAnchors.push({proc:Z,anchor:J}),z(`session "${this.sessionName}": defer Codex turn checkpoint until rollout confirmation thread=${Z.sessionId} checkpoint=${$.id}`),null}return this.appendTurnAnchor(J)}appendTurnAnchor($){try{return b4(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${U(Z)}`;return z(`session "${this.sessionName}": ${J}`),J}}flushPendingCodexTurnAnchors($){let Z=null,J=[];for(let Q of this.pendingCodexTurnAnchors){if(Q.proc!==$||Z){J.push(Q);continue}if(Z=this.appendTurnAnchor(Q.anchor),Z)J.push(Q)}return this.pendingCodexTurnAnchors=J,Z}discardPendingCodexTurnAnchors($,Z){if($.provider!=="codex")return;let J=this.pendingCodexTurnAnchors.length;this.pendingCodexTurnAnchors=this.pendingCodexTurnAnchors.filter((Y)=>Y.proc!==$);let Q=J-this.pendingCodexTurnAnchors.length;if(Q>0)z(`session "${this.sessionName}": dropped ${Q} unmaterialized Codex checkpoint(s): ${Z}`)}collectTurnWrites(){let $=this.currentTurn;if(!$)return[];let Z=[];for(let J of $.toolByUseId.values())Z.push(...T7(J.name,J.input));return Z}worktreeProjectName(){return b0(this)}worktreeProjectDir(){return e1(this)}spawnDeveloperInstructions(){return aY(this)}worktreeInstructionLoadedNotice(){return B3(this)}withWorktreeInstructionNotice($){return rY(this,$)}worktreeExtraInstruction(){return d9(this)}runWorktreeCommand($,Z){return tY(this,$,Z)}showWorktrees(){return j3(this)}showTasklistPanel(){return EY(this)}showConsultIdentityPanel($=""){return _Y(this,$)}onConsultIdentityAdd($,Z,J){return qY($,Z,J)}onConsultIdentityRole($,Z,J,Q){return BY($,Z,J,Q)}onConsultIdentityToggle($,Z,J){return jY($,Z,J)}onConsultIdentityDelete($,Z,J){return LY($,Z,J)}onConsultIdentityDeleteConfirm($,Z,J){return DY($,Z,J)}onConsultIdentityPage($,Z,J){return AY($,Z,J)}onConsultIdentityBack($,Z){return FY($,Z)}onTasklistEnable(){return NY(this)}onTasklistDeletePrompt($){return kY(this,$)}onTasklistDeleteConfirm($){return xY(this,$)}runCompactCommand(){return tQ(this)}showModelPanel(){return $Y(this)}onModelSelect($,Z="",J="",Q=null){return HY(this,$,Z,J,Q)}onModelEffortSelect($,Z,J="",Q="",Y=""){return this.runLifecycle("model-effort-select",()=>XY(this,$,Z,J,Q,Y))}onProviderSelect($,Z=""){return ZY(this,$,Z)}onModelPanelCancel($=""){return YY(this,$)}onModelCustomPrompt($,Z,J=""){return JY(this,$,Z,J)}consumeModelCustomMessage($,Z){return QY(this,$,Z)}onWorktreeDisband($){return eY(this,$)}showForkList($=""){return XH(this,$)}showBackList($=""){return VH(this,$)}showResumeList($=""){return WH(this,$)}runBtwCommand($){return GH(this,$)}runByeCommand(){return zH(this)}onForkSelect($,Z,J=""){return KH(this,$,Z,J)}onBackSelect($,Z,J=""){return _H(this,$,Z,J)}onResumeSelect($,Z,J=""){return qH(this,$,Z,J)}runCommand($,Z=""){return aQ(this,$,Z)}async buildConsoleOpts($,Z){let J=await NJ(),Q=this.runtimeModelSelection();return{sessionName:this.sessionName,status:this.status,provider:Q.provider,model:Q.model??void 0,effort:Q.effort,worktreeInstructionNotice:this.worktreeInstructionLoadedNotice(),peers:[...B1.all].filter((Y)=>Y.isRunning()).map((Y)=>({...Y.peerSnapshot(),isCurrent:Y===this})),usage:$,glmUsage:Z,sysinfo:J}}async buildConsoleCard($){return _7(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0),J=Z.provider??this.currentProvider(),Q=this.currentTokenSource(),Y=Q&&Q.agent===J&&Q.enabled?Q:this.selectedTokenSourceId?void 0:A4(J)[0];if(Y)Z.unifiedUsage=await Y.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 g7();else Z.usage=await T9();if(!await U$($,M.consoleUsage,I2(Z),{notifyCardFailure:!1}))throw Error("console usage element replace rejected")}async mutateStaticCard($,Z,J){let Q=!0;try{await J()}catch(H){Q=!1,z(`session "${this.sessionName}": ${Z} mutation failed: ${U(H)}`)}let Y=!1;try{Y=await q$($,{config:{streaming_mode:!1}})}catch(H){z(`session "${this.sessionName}": ${Z} streaming-off failed: ${U(H)}`)}if(!Q||!Y)return z(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Q} streamingOff=${Y} card=${$.slice(0,12)}`),!1;try{await S$($)}catch(H){return z(`session "${this.sessionName}": ${Z} dispose failed: ${U(H)}`),!1}return Q}patchConsoleUsageLater($){this.mutateStaticCard($,"console usage",()=>this.patchConsoleUsage($))}async replaceStatusCardWithConsole($,Z){$.timer.stop();let J=$.timer.elapsedSec(),Q=await this.buildConsoleOpts(void 0);await m$($.cardId);let Y=await U$($.cardId,M.footer,V9(Q,M.footer)),H=await E0($.cardId,X9(Q),{type:"insert_after",targetElementId:M.footer}),X=await E0($.cardId,W9(Q.sysinfo),{type:"insert_after",targetElementId:M.consoleProjects}),V=await E0($.cardId,I2(Q),{type:"insert_after",targetElementId:M.consoleHost});if(!Y||!H||!X||!V){await y(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}V$($.cardId),await q$($.cardId,p$({durationSec:J,suffix:Z})),this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleCard(void 0),Z=await c(this.chatId,$);if(!Z)return;(async()=>{let J="";try{J=await r$(Z),c$(J,4)}catch(Q){z(`session "${this.sessionName}": console card conversion failed: ${U(Q)}`);return}await this.mutateStaticCard(J,"console usage",()=>this.patchConsoleUsage(J))})().catch((J)=>z(`session "${this.sessionName}": console async update rejected: ${U(J)}`))}interrupt(){if(!this.proc)return;z(`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 Q=this.beginTurnOpen();try{let H=await this.openTurnCard(Q,J,"user_message",{initialFooter:"Waiting...(0s)",startThinking:!1,directStart:!0});if(!H||this.currentTurn!==H)return;let X=this.startFooterTimer(H.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(K)=>this.withModel(K)),V=`\uD83D\uDE80 启动 ${this.backendLabel()}`,W=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(K)=>{V=K,X.setStatus(K)}});if(X.stop(),await m$(H.cardId),!W){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(V.startsWith("❌")?V:"❌ 启动失败",{forcePush:!0});return}let G=this.proc;if(!G?.isAlive()){await this.closeTurnCard(`❌ ${this.backendLabel()} 启动后已退出`,{forcePush:!0});return}this.startThinkingFooter(H),this.sendClaimedUserText(G,Z),this.status="working"}finally{this.releaseTurnOpen(Q)}}async onUserMessage($,Z=[],J="",Q=""){await this.runLifecycle("user-message",()=>this.onUserMessageUnlocked($,Z,J,Q))}async onUserMessageUnlocked($,Z,J,Q){let Y=this.blockedProcessMessage();if(Y){await O(this.chatId,`❌ ${Y}。请重试 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 H=this.currentTurn!==null||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0;this.lastUserOpenId=J;let V=(Z.length?Z.map((G)=>`[file: ${G}]`).join(" ")+`
197
+ `:"")+$,W=(G)=>{this.pendingReactionIds.set(G,""),(async()=>{let K=await R$(G,"OneSecond");if(!K)return;if(this.pendingReactionIds.has(G))this.pendingReactionIds.set(G,K);else if(this.currentBatchReactionIds.has(G))this.currentBatchReactionIds.set(G,K);else A$(G,K)})().catch((K)=>{z(`session "${this.sessionName}": reaction tracking failed: ${U(K)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:V,userOpenId:J,msgId:Q}),Q)W(Q);return}await this.startColdUserTurn($,V,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:V,userOpenId:J,msgId:Q}),Q)W(Q);return}if(!this.openingTurn&&this.initCount>=1){let G=this.proc,K=this.procEpoch,_=this.beginTurnOpen(G,K);try{this.pendingTurnInputs.push($);let B=await this.openTurnCard(_,J,"user_message");if(!B||this.currentTurn!==B)return;if(this.proc!==G||this.procEpoch!==K||!G.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(G.provider)} 已退出`);return}this.sendClaimedUserText(G,V),this.status="working"}finally{this.releaseTurnOpen(_)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:V,userOpenId:J,msgId:Q}),Q)W(Q);return}if(this.pendingTurnInputs.push($),this.sendClaimedUserText(this.proc,V),H&&Q)W(Q)}hasPendingAsk(){return kQ(this)}onMultiMessageInbound($,Z,J,Q){return GQ(this,$,Z,J,Q)}clearMultiMsgBuffer($){u7(this,$)}onAskMessageAnswer($,Z,J){return xQ(this,$,Z,J)}onAskAnswer($,Z,J,Q){return yQ(this,$,Z,J,Q)}onAskCustomAnswer($,Z,J,Q){return o7(this,$,Z,J,Q)}onPermissionDecision($,Z,J){return SQ(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=o0(this.sessionName,"codex");if(f1(this.sessionName,"codex"),this.selectedProvider==="codex")this.lastSessionRef=null,this.lastSessionId=null;if(Z)z(`session "${this.sessionName}": cleared pre-fresh Codex resume binding thread=${Z.sessionId}`)}invalidateMissingCodexResume($,Z,J){if(!$||this.selectedProvider!=="codex")return null;let Q=P3(Z);if(!Q||!["thread/read","thread/resume","thread/fork"].includes(Q.method)||Q.serverCode!==-32600||Q.serverMessage!==`no rollout found for thread id ${$}`)return null;let Y=o0(this.sessionName,"codex");if(!Y||Y.sessionId!==$)return null;try{f1(this.sessionName,"codex")}catch(X){let V=`已确认恢复点无 rollout,但作废失败: ${U(X)}`;return z(`session "${this.sessionName}": ${V} thread=${$}`),V}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let H=`已作废无 rollout 的恢复点 thread=${G$($)}`;return z(`session "${this.sessionName}": ${H} fullThread=${$}`),H}persistResumableSessionId($=!1,Z=this.proc,J=!0){let Q=Z?.provider==="claude"?this.pendingConversationMaterialization:null,Y=Z?.sessionId;if(!Z)return null;if(Z.provider==="codex"&&Z.isConversationResumable?.()!==!0)return null;if(!Y){if(!Q)return null;let V=Error("Claude pending fork did not provide a materialized session id");if(z(`session "${this.sessionName}": ${V.message}`),$)throw V;return V.message}let H={provider:Z.provider,sessionId:Y,cwd:this.workDir};if(Q&&(Y===Q.launch.source.sessionId||Q.previousSessionId!==null&&Y===Q.previousSessionId)){let V=Error(`Claude fork did not materialize an independent session id (${Y})`);if(z(`session "${this.sessionName}": ${V.message}`),$)throw V;return V.message}try{P2(this.sessionName,H)}catch(V){let W=`会话恢复点持久化失败: ${U(V)}`,G=this.resumePersistenceError!==W;if(this.resumePersistenceError=W,Z.provider===this.selectedProvider)this.lastSessionRef=H,this.lastSessionId=Y;if(z(`session "${this.sessionName}": ${W}`),$)throw V;if(G&&J)y(this.chatId,`⚠️ ${W};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return W}if(Z.provider===this.selectedProvider)this.lastSessionRef=H,this.lastSessionId=Y;let X=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(X){let V=this.resumePersistenceError!==X;if(this.resumePersistenceError=X,$)throw Error(X);if(V&&J)y(this.chatId,`⚠️ ${X}`);return X}return this.resumePersistenceError=null,null}consumePendingConversationMaterialization(){let $=this.pendingConversationMaterialization;if(!$)return null;let Z=this.lastSessionRef;if(Z?.provider!=="claude"||Z.cwd!==this.workDir||Z.sessionId===$.launch.source.sessionId||Z.sessionId===$.previousSessionId)return z(`session "${this.sessionName}": ${"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker"}`),"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker";try{return T0(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Q=`Claude 待生成分支标记清除失败: ${U(J)}`;return z(`session "${this.sessionName}": ${Q}`),Q}}bgStore(){return{active:this.backgroundTasks,pending:this.pendingBgTasks}}applyBgStore($){this.backgroundTasks=$.active,this.pendingBgTasks=$.pending}onMainThreadAdvance(){if(this.pendingBgTasks.length===0)return;this.applyBgStore(p8(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(!g0(this.backgroundTasks)){if(this.backgroundCard)this.settleBackgroundCard().catch((Z)=>{z(`session "${this.sessionName}": background settle failed: ${U(Z)}`)});return}if(!this.backgroundCard&&!this.openingBackground){this.openBackgroundCard().catch((Z)=>{z(`session "${this.sessionName}": background open failed: ${U(Z)}`)});return}this.scheduleBackgroundRefresh()}async openBackgroundCard(){let $=this.beginBackgroundOpen();if(!$)return;let Z=this.backgroundTasks.slice();try{let J=o8(Z,Date.now(),q1()),Q=await c(this.chatId,J);if(!Q){if(this.ownsBackgroundOpen($))z(`session "${this.sessionName}": background card send failed`);return}let Y;try{Y=await r$(Q)}catch(H){z(`session "${this.sessionName}": background card id_convert failed: ${H}`);return}if(c$(Y,Z.length),!this.ownsBackgroundOpen($)){await this.terminalizeSupersededCard(Y,"⚠️ 后台任务世代已切换,本卡已作废",!1);return}if(this.backgroundCard={messageId:Q,cardId:Y},this.backgroundDetailAdded=new Set(Z.map((H)=>H.id)),this.backgroundDetailAdding.clear(),z(`session "${this.sessionName}": background card opened cardId=${Y.slice(0,12)} tasks=${Z.length}`),!g0(this.backgroundTasks)){this.settleBackgroundCard().catch((H)=>{z(`session "${this.sessionName}": background settle-after-open failed: ${U(H)}`)});return}this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}finally{this.releaseBackgroundOpen($)}}startBackgroundRefreshTick(){if(this.backgroundRefreshTick)return;let $=()=>{if(this.migratingBackgroundCard||!this.backgroundCard||!g0(this.backgroundTasks))return;let Z=q1(),J=Date.now(),Q=1/0;for(let Y of this.backgroundTasks){if(y$(Y))continue;let H=M0(J-Y.startedAt,Z).nextDelayMs;if(H<Q)Q=H}if(!isFinite(Q))return;this.backgroundRefreshTick=setTimeout(()=>{this.refreshBackgroundCardFull(),$()},Math.max(1,Math.ceil(Q)))};$()}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=q1();for(let Q of this.backgroundTasks)if(!this.backgroundDetailAdded.has(Q.id)){if(this.backgroundDetailAdding.has(Q.id))continue;this.backgroundDetailAdding.add(Q.id),E0($.cardId,N1(Q,Z,J)).then((Y)=>{if(Y)this.backgroundDetailAdded.add(Q.id);else z(`session "${this.sessionName}": background panel add MISS task=${Q.id}`)}).finally(()=>{this.backgroundDetailAdding.delete(Q.id)})}else i($.cardId,G2.panel(Q.id),N1(Q,Z,J));z0($.cardId,L4(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){z(`session "${this.sessionName}": background migration failed before settle; retry terminal snapshot: ${U(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 m$($.cardId),await W0($.messageId,D4(Z)),V$($.cardId),!await q$($.cardId,p$({suffix:"\uD83E\uDDED 后台任务已结束"})))throw Error("background history streaming-off rejected");if(await S$($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((Q)=>!y$(Q)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),z(`session "${this.sessionName}": background card settled cardId=${$.cardId.slice(0,12)} remaining=${this.backgroundTasks.length}`)}finally{if(this.settlingBackgroundCard=!1,this.backgroundCard===$&&g0(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 m$($.cardId),this.backgroundCard!==$)return;let Z=[...this.backgroundTasks],J=new Set(Z.filter(y$).map((H)=>H.id)),Q=J.size;if(Q>0)await W0($.messageId,D4(Z));else await W0($.messageId,a8());if(V$($.cardId),!await q$($.cardId,p$({suffix:"\uD83E\uDDED 已迁移至新卡"})))throw Error("background migration streaming-off rejected");if(await S$($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((H)=>!J.has(H.id)||!y$(H)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),z(`session "${this.sessionName}": background card migrated cardId=${$.cardId.slice(0,12)} terminal=${Q} active=${this.backgroundTasks.length}`)}startScheduledTurnCard($,Z,J,Q){if(this.proc!==$||this.procEpoch!==Z||!$.isAlive())return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.bgResumePending)return;let Y;try{Y=this.beginTurnOpen($,Z,!0)}catch(X){z(`session "${this.sessionName}": scheduled turn-open ownership conflict: ${U(X)}`);return}let H=J.replace(/\s+/g," ").trim();this.lastTurnUserPreview=`⏰ ${H.slice(0,78)}`,z(`session "${this.sessionName}": scheduled wakeup prompt=${Q??"MISS"}`),(async()=>{try{let X=await this.openTurnCard(Y,"","scheduled_wakeup");if(this.proc!==$||this.procEpoch!==Z){if(z(`session "${this.sessionName}": scheduled ${$.provider} turn became stale while opening epoch=${Z}`),X&&this.currentTurn===X)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);return}if(!X||this.currentTurn!==X){if(!this.ownsTurnOpen(Y))return;if(this.bgResumeCardless=!0,Y.sawResult)Y.sawResult=!1,z(`session "${this.sessionName}": scheduled open failed after result — flushing orphan now`),this.flushOrphanAssistantToChat("scheduled open failed, result already arrived");else z(`session "${this.sessionName}": scheduled open failed — orphan text flush will cover the output`)}else if(Y.sawResult)Y.sawResult=!1,z(`session "${this.sessionName}": scheduled result raced card-open — closing freshly-opened card`),await this.closeTurnCard(Y.terminalSuffix,{forcePush:Y.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(Y)}})().catch((X)=>{z(`session "${this.sessionName}": scheduled turn-open handler failed: ${U(X)}`)})}wireProc($,Z){if(Z===void 0)this.invalidateTurnOpen(),this.invalidateBackgroundOpen();let J=Z??++this.procEpoch;if(Z===void 0&&this.proc!==$)this.proc=$;let Q=()=>this.proc===$&&this.procEpoch===J,Y=!1,H=!1,X=(V,W)=>{$.on(V,(G)=>{if(!Q()){if(!Y)Y=!0,z(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(V)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(V!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!H)H=!0,z(`session "${this.sessionName}": ignore ${$.provider} event=${String(V)} while process stop is pending`);return}W(G)})};X("error",(V)=>{z(`session "${this.sessionName}": ${$.provider} process error: ${V}`)}),X("init",()=>{if($.provider==="codex"&&$.launchKind==="fresh")this.clearResumeBindingForFreshCodex($);else this.persistResumableSessionId(!0);if(u5(),this.initCount++,z(`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)z(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let V=this.pendingUserMessageCount>0,W=!V&&this.bgResumePending;if(!V&&!W)return;let G=this.lastUserOpenId,K;try{K=this.beginTurnOpen($,J,!0)}catch(j){z(`session "${this.sessionName}": init turn-open ownership conflict: ${U(j)}`);return}if(this.bgResumePending=!1,V)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let _=V?[...this.currentBatchReactionIds.keys()]:[],B=()=>{for(let j of _){let L=this.currentBatchReactionIds.get(j);if(this.currentBatchReactionIds.delete(j),L)A$(j,L)}};(async()=>{try{let j=await this.openTurnCard(K,G,V?"user_message":"bg_task_resume");if(!Q()){if(z(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),j&&this.currentTurn===j)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);B();return}if(!j||this.currentTurn!==j){if(!this.ownsTurnOpen(K)){B();return}if(K.sawResult&&K.terminalSuffix)y(this.chatId,K.terminalSuffix);if(V)z(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),B();else if(this.bgResumeCardless=!0,K.sawResult)K.sawResult=!1,z(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else z(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(K.sawResult)K.sawResult=!1,z(`session "${this.sessionName}": result raced card-open — closing freshly-opened turn card now`),await this.closeTurnCard(K.terminalSuffix,{forcePush:K.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(K)}})().catch((j)=>{z(`session "${this.sessionName}": init turn-open handler failed: ${U(j)}`)})}),X("scheduled_turn_input",({text:V,promptId:W})=>{if($.provider!=="claude")return;this.startScheduledTurnCard($,J,V,W)}),X("conversation_materialized",({session_id:V,source:W})=>{if($.provider!=="codex")return;if($.sessionId!==V){z(`session "${this.sessionName}": ignore mismatched Codex materialization session=${V} current=${$.sessionId??"MISS"} source=${W}`);return}z(`session "${this.sessionName}": Codex resume point materialized thread=${V} source=${W}`),this.persistResumableSessionId()}),X("conversation_materialization_failed",({session_id:V,source:W,error:G})=>{if($.provider!=="codex"||$.sessionId!==V)return;let K=`Codex 会话落盘确认失败,未写恢复点: ${U(G)}`,_=this.resumePersistenceError!==K;if(this.resumePersistenceError=K,z(`session "${this.sessionName}": ${K} thread=${V} source=${W}`),_)y(this.chatId,`⚠️ ${K}`)}),X("turn_started",()=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)z(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;this.persistResumableSessionId();let V=this.proc?.lastTotalUsage;if(this.usageTotalsSeedUnknown&&!V){this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;return}this.currentTurnUsageBaseline=V?{...V}:null,this.currentTurnUsageBaselineKnown=!0}),X("token_usage",({totalUsage:V})=>{if(this.persistResumableSessionId(),V)this.usageTotalsSeedUnknown=!1}),X("turn_plan_updated",(V)=>{this.handleTurnPlanUpdated(V)}),X("plan_delta",(V)=>{this.handlePlanDelta(V)}),X("context_compacted",(V)=>{this.handleContextCompacted(V)}),X("rate_limits_updated",(V)=>{if($.provider==="codex")rJ(V)}),X("thread_goal_updated",(V)=>{this.handleThreadGoalUpdated(V)}),X("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),X("assistant_text",({text:V,parentToolUseId:W})=>{if(W)return;this.appendAssistant(V)}),X("assistant_block_stop",({parentToolUseId:V})=>{if(V)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),X("tool_use",({id:V,name:W,input:G,parentToolUseId:K})=>{if(K&&this.bgTaskOwns(K)){this.applyBgStore(d8({active:this.backgroundTasks,pending:this.pendingBgTasks},K,V,W,G)),this.onBackgroundTaskChanged();return}if(TQ(this,V,W,G),!K)this.onMainThreadAdvance();if(!K&&(W==="Task"||W==="Agent"))this.lastMainTaskToolUseId=V}),X("tool_result",({tool_use_id:V,content:W,is_error:G,parentToolUseId:K})=>{if(K&&this.bgTaskOwns(K)){this.applyBgStore(n8({active:this.backgroundTasks,pending:this.pendingBgTasks},K,V,W,G)),this.onBackgroundTaskChanged();return}EQ(this,V,W,G)}),X("can_use_tool",(V)=>{bQ(this,V)}),X("hook_callback",(V)=>{this.proc?.sendHookResponse(V.request_id,{})}),X("result",(V)=>{let W=this.persistResumableSessionId(),G=W?null:this.consumePendingConversationMaterialization(),K=[W,G].filter(Boolean).join(";")||null;if(this.accumulateResultStats(),this.openingTurnOwner)this.openingTurnOwner.sawResult=!0;if(this.userInterrupted){this.userInterrupted=!1,this.discardOrphanAssistant(),this.bgResumePending=!1;let F=this.proc?.lastResult.subtype??"unknown",N=this.proc?.lastResult.is_error===!0;z(`session "${this.sessionName}": SDK result after user stop subtype=${F} isError=${N} — ignored`),this.status="idle";return}let _=V?.is_error!==!0?this.recordTurnAnchor(V?.checkpoint):null;if(V?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let B=this.pendingMidTurnMsgs.length>0,j=this.proc?.lastResult.is_error===!0,L=this.proc?.lastResult.subtype??"success",A,P=!1,R=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),D=[K,_].filter(Boolean).join(";")||null;if(D)A=`⚠️ ${D}`,P=!0;else if(B)A=j?`⚠️ ${R} ${L},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(j)A=`⚠️ ${R} ${L}`,P=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=A,this.openingTurnOwner.terminalForcePush=P;if(D&&!this.currentTurn&&!this.openingTurn)y(this.chatId,`⚠️ ${D}`);if(z(`session "${this.sessionName}": SDK result subtype=${L} isError=${j} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${P}`),this.closeTurnCard(A,{forcePush:P,hasFreshResult:!0}).catch((F)=>{z(`session "${this.sessionName}": result card close failed: ${U(F)}`)}),this.status="idle",B)this.drainMidTurnAndOpen().catch((F)=>{z(`session "${this.sessionName}": mid-turn drain failed: ${U(F)}`)})}),X("bg_task_started",(V)=>{let W=V.tool_use_id??this.lastMainTaskToolUseId??void 0;z(`session "${this.sessionName}": bg_task_started task=${V.task_id} type=${V.task_type??"-"} subagent=${V.subagent_type??"-"} toolUseId=${W?.slice(0,8)??"-"} desc=${(V.description??"").slice(0,40)}`),this.applyBgStore(c8(this.bgStore(),{...V,tool_use_id:W})),this.onBackgroundTaskChanged()}),X("bg_task_progress",(V)=>{this.applyBgStore(m8(this.bgStore(),V)),this.onBackgroundTaskChanged()}),X("bg_task_updated",(V)=>{this.applyBgStore(u8(this.bgStore(),V)),this.onBackgroundTaskChanged()}),X("bg_task_settled",(V)=>{if(z(`session "${this.sessionName}": bg_task_settled task=${V.task_id} status=${V.status}`),this.applyBgStore(l8(this.bgStore(),V)),this.onBackgroundTaskChanged(),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),X("subagent_step",(V)=>{this.applyBgStore(i8(this.bgStore(),V.thread_id,V.item_id,V.tool,V.phase,V.brief)),this.onBackgroundTaskChanged()}),X("exit",({code:V,signal:W,expected:G})=>{if(z(`session "${this.sessionName}": ${$.provider} exited code=${V} signal=${W} expected=${G}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let L=$.conversationMaterializationFailure?.(),A=this.persistResumableSessionId(!1,$,!1),P=[L&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${U(L)}`:null,A].filter(Boolean).join(";");if(P)y(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${P}`);this.discardPendingCodexTurnAnchors($,"blocked process finally exited")}z(`session "${this.sessionName}": blocked/stopping ${$.provider} exit confirmed`),this.detachProc($),this.status="stopped",this.opts.onLifecycleChange?.();return}this.discardPendingCodexTurnAnchors($,"unexpected process exit"),this.cancelConsultRuns(`${$.provider} process exited`).catch((L)=>{z(`session "${this.sessionName}": cancel consult after process exit failed: ${U(L)}`)});let K=this.backendLabel($.provider),_=`code=${V??"null"}, signal=${W??"null"}`,B=G?`\uD83D\uDED1 ${K} 已退出`:`⚠️ ${K} 异常退出 (${_})`;if(this.currentTurn)this.closeTurnCard(B).catch((L)=>{z(`session "${this.sessionName}": process-exit current main-card close failed: ${U(L)}`)});let j=this.waitForTurnCloses().catch((L)=>{z(`session "${this.sessionName}": process-exit main-card close failed: ${U(L)}`)});this.detachProc($),this.flushOrphanAssistantToChat("process exit"),this.bgResumePending=!1,this.bgResumeCardless=!1,this.clearMultiMsgBuffer("process exit"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.userInterrupted=!1,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped",this.opts.onLifecycleChange?.(),this.runLifecycle("process-exit-cleanup",async()=>{let L=await Promise.allSettled([j,this.resetBackgroundTasks()]);for(let A of L)if(A.status==="rejected")z(`session "${this.sessionName}": process-exit terminal cleanup failed: ${U(A.reason)}`);if(!G)await O(this.chatId,`⚠️ ${K} 异常退出 (${_})。回复任意消息将重新启动。`)}).catch((L)=>{z(`session "${this.sessionName}": process-exit cleanup rejected: ${U(L)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?N8(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=k8(Z),Q=this.proc?.provider==="claude"?0:$.cost_delta_usd??0,Y=$.duration_ms??0;if(J!=null)this.cumStats.tokens+=J;this.cumStats.costUsd+=Q,this.cumStats.turns+=$.num_turns??1,this.lastTurnDelta={tokens:J,costUsd:Q,durationMs:Y}}currentContextTokens($=this.proc){if($?.provider==="claude")return $.lastContextTokens??null;let Z=$?.lastUsage;return c4(Z)}contextLimitForDisplay($=this.proc){return m4($?.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(Y){z(`session "${this.sessionName}": mid-turn open ownership conflict: ${U(Y)}`);return}let Q=this.pendingMidTurnMsgs;this.pendingMidTurnMsgs=[];try{for(let W of Q)if(this.pendingTurnInputs.push(W.text),W.msgId){let G=this.pendingReactionIds.get(W.msgId)??"";this.currentBatchReactionIds.set(W.msgId,G),this.pendingReactionIds.delete(W.msgId)}let Y=Q.map((W)=>W.wireText).join(`
196
198
 
197
- `),V=J[J.length-1]?.userOpenId??this.lastUserOpenId,X=await this.openTurnCard(Q,V,"user_message");if(!X||this.currentTurn!==X){for(let W of J){if(!W.msgId)continue;let z=this.currentBatchReactionIds.get(W.msgId);if(this.currentBatchReactionIds.delete(W.msgId),z)P$(W.msgId,z)}this.status="idle";return}if(this.proc!==$||this.procEpoch!==Z||!$.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);for(let W of J){if(!W.msgId)continue;let z=this.currentBatchReactionIds.get(W.msgId);if(this.currentBatchReactionIds.delete(W.msgId),z)P$(W.msgId,z)}this.status="stopped";return}try{$.sendUserText(Y,[])}catch(W){G(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${W}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await N(this.chatId,`❌ ${this.backendLabel($.provider)} 接收消息失败: ${U(W)}。这批消息未开始处理,请重发。`),this.status="idle";return}this.pendingUserMessageCount++,this.status="working"}finally{if(this.releaseTurnOpen(Q),!this.currentTurn&&this.pendingMidTurnMsgs.length>0&&this.proc===$&&this.procEpoch===Z&&$.isAlive())this.drainMidTurnAndOpen()}}async terminalizeSupersededCard($,Z,J){let Q=J?await U$($,M.footer,this.footerElement(Z)):!0;X$($);let Y=await q$($,p$({suffix:Z}));if(Q&&Y){await b$($);return}let H=`footer=${Q?"ok":"MISS"}, settings=${Y?"ok":"MISS"}`;G(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${H}`),await N(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${H})。`)}async openTurnCard($,Z,J,Q={}){if(!this.ownsTurnOpen($))return null;if(this.bgResumePending=!1,this.backgroundCard&&M0(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 Y=++this.turnCounter,H=this.pendingTurnInputs;this.pendingTurnInputs=[],this.lastTurnUserPreview=H[0]?.slice(0,80)??this.lastTurnUserPreview,G(`session "${this.sessionName}": openTurnCard turn=${Y} trigger=${J} inputs=${H.length}`);let V=this.runtimeModelSelection(),X=this.withModel(Q.initialFooter??"Waiting...(0s)",V),W=H9({sessionName:this.sessionName,turn:Y,provider:V.provider,model:V.model??void 0,effort:V.effort,kind:J,userInputs:H,initialFooter:X,directStart:Q.directStart}),z=await c(this.chatId,W);if(!z){if(!this.ownsTurnOpen($))return null;if(G(`session "${this.sessionName}": openTurnCard sendCard EXHAUSTED retries — surfacing via raw text`),J==="user_message")await N(this.chatId,`❌ 创建对话卡片失败 (Feishu SDK 重试 3 次后仍连不上)。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return null}let K;try{K=await r$(z)}catch(L){if(G(`session "${this.sessionName}": id_convert failed: ${L}`),J==="user_message"&&this.ownsTurnOpen($))await N(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return null}let _=(J==="bg_task_resume"?1:0)+(H.length>0?1:0)+1;if(!this.ownsTurnOpen($))return c$(K,_),await this.terminalizeSupersededCard(K,"⚠️ 会话已切换,本卡已作废",!0),null;let j={cardId:K,...V,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,cardWriteFailureNotified:!1,rotateGivenUp:!1,outboundSeenPaths:new Set,outboundSentPaths:new Set};if(c$(K,_,(L,P)=>{this.onCardWriteFailure(j,K,L,P)}),this.currentTurn=j,Q.startThinking!==!1)this.startThinkingFooter(j);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 P of L)this.handleContextCompacted(P)}let B=this.takeOrphanAssistantText();if(B)this.appendAssistant(B),this.finalizeCurrentAssistantSegment();if(this.pendingRebuildBackgroundCard){if(this.pendingRebuildBackgroundCard=!1,M0(this.backgroundTasks))this.openBackgroundCard().catch((L)=>{G(`session "${this.sessionName}": background rebuild failed: ${U(L)}`)})}return j}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotateGivenUp)return;if($.rotating)return;if(m8($.cardId)<jj)return;this.startMidTurnRotate($)}onCardWriteFailure($,Z,J,Q){let Y=this.currentTurn;if(Y!==$){G(`session "${this.sessionName}": ignore stale card failure card=${Z.slice(0,12)} code=${J??"n/a"} (turn owner changed)`);return}if(Y.cardId!==Z){G(`session "${this.sessionName}": ignore retired-card failure card=${Z.slice(0,12)} current=${Y.cardId.slice(0,12)} code=${J??"n/a"}`);return}if(Y.rotating)return;if(Y.rotateGivenUp)return;if(!gZ(J,Q)){let H=Q?.operation??"unknown operation",V=Q?.elementId?` element=${Q.elementId}`:"";if(G(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${H}${V} code=${J??"n/a"} — not rotating`),!Y.cardWriteFailureNotified)Y.cardWriteFailureNotified=!0,N(this.chatId,`⚠️ 对话卡片有一项写入失败(code=${J??"MISS"}, ${H})。该错误不是卡片元素上限,已停止无效换卡;其余输出继续处理。`);return}if(Y.failureRotateCount>=l2){Y.rotateGivenUp=!0,this.stopFooterStatus(Y),v4(Y.cardId),G(`session "${this.sessionName}": failure-rotate cap (${l2}) hit — giving up, rest of turn is log-only`),N(this.chatId,`⚠️ 本轮已因元素容量超限换卡 ${l2} 次,现停止继续换卡;本轮后续输出仅日志可见。`);return}G(`session "${this.sessionName}": confirmed element limit (${J}) on card=${Y.cardId.slice(0,8)}… — rotating to fresh card`),Y.failureRotateCount++,this.startMidTurnRotate(Y)}startMidTurnRotate($){if($.rotating)return;$.rotateCount++;let{cardId:Z,toolByUseId:J,toolBatches:Q}=$,Y={value:null},H=(V,X)=>{if(!Y.value)Y.value={code:V,failure:X}};$.rotating=(async()=>{try{G(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${m8(Z)}`);let V=H9({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort,kind:"card_full",userInputs:[]}),X=await c(this.chatId,V);if(!X){if(G(`session "${this.sessionName}": mid-turn rotate sendCard EXHAUSTED — staying on old card,subsequent adds will drop`),this.currentTurn===$)$.rotateGivenUp=!0,this.stopFooterStatus($),v4($.cardId);await N(this.chatId,"⚠️ 卡片元素超出飞书上限,本轮后续输出仅日志可见(开新卡失败)。");return}let W;try{W=await r$(X)}catch(B){if(G(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${B}`),this.currentTurn===$)$.rotateGivenUp=!0,this.stopFooterStatus($),v4($.cardId),await N(this.chatId,"⚠️ 新对话卡已发送,但 Card Kit 初始化失败;已停止继续换卡,本轮后续输出仅日志可见。");return}c$(W,2,(B,L)=>{if($.rotating){H(B,L);return}this.onCardWriteFailure($,W,B,L)});let z=$.assistantWriteInflight?.get(Z);if(z?.size)await Promise.allSettled([...z]);this.stopFooterStatus($),$.cardId=W,$.messageId=X,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let K=$.currentAssistantSegmentId,_=($.currentAssistantText??"").trim(),j=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,_)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)W$($.cardId,Y1(this.taskBoard),{type:"insert_before",targetElementId:M.footer});if($.planLiveInserted)W$($.cardId,S2($.planSteps,$.planExplanation,M.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?M.taskBoardLive:M.footer});for(let B of $.contextCompactionPending.values()){if(B.cardId!==Z)continue;B.cardId=W,B.created=!1,B.createFailure=void 0;let L=M.contextCompact(B.i);B.createPromise=g4(W,b2(B.i,B.notice,L),{type:"insert_before",targetElementId:j$($)}).then((P)=>{if(B.cardId===W)B.created=P.landed,B.createFailure=P.failure;return P.landed})}for(let[B,L]of j){if(K&&_&&B===K)continue;if(!g1(Z,B))continue;let P=$.assistantSegmentCount++,A=M.assistant(P);$.segmentTexts.set(A,L),await this.addCompletedAssistantSegment($,A,L)}if(d7(this,Z,W,J,Q),await m$(Z),d7(this,Z,W,J,Q),K&&_){let B=$.assistantSegmentCount++,L=M.assistant(B);$.currentAssistantSegmentId=L,$.currentAssistantText=_,$.segmentTexts.set(L,_)}try{let B=$.mathRenderInflight?.get(Z);if(B?.size)await Promise.allSettled([...B]);await m$(Z);let L=$.mathRendered?.get(Z);for(let[D,F]of j){if(K&&_&&D===K)continue;if(g1(Z,D))continue;if(L?.has(D))continue;await d(Z,D,this.completedAssistantElement(D,F))}let P=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",A=await U$(Z,M.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${P}`)),{notifyCardFailure:!1});X$(Z);let R=await q$(Z,p$({suffix:"\uD83D\uDCE8 转下一张"}));if(A&&R)await b$(Z);else G(`session "${this.sessionName}": rotate old-card terminal MISS footer=${A} settings=${R}`),await N(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${A?"ok":"MISS"}, settings=${R?"ok":"MISS"}),本轮输出已续到新卡。`)}catch(B){G(`session "${this.sessionName}": mid-turn rotate close-old failed: ${B}`)}G(`session "${this.sessionName}": mid-turn rotate done old=${Z.slice(0,8)}… new=${W.slice(0,8)}…`)}finally{$.rotating=null;let V=Y.value;if(V&&this.currentTurn===$)this.onCardWriteFailure($,$.cardId,V.code,V.failure)}})()}addPlanSnapshotOnCurrentTurn(){let $=this.currentTurn;if(!$||$.planSteps.length===0)return;this.maybeMidTurnRotate();let Z=$.cardId,J=M.planUpdate($.planUpdateCount++);W$(Z,V7($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:j$($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=M.goalUpdate(Z.goalUpdateCount++);W$(Z.cardId,X7($,J),{type:"insert_before",targetElementId:j$(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=M.goalUpdate($.goalUpdateCount++);W$($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
199
+ `),X=Q[Q.length-1]?.userOpenId??this.lastUserOpenId,V=await this.openTurnCard(J,X,"user_message");if(!V||this.currentTurn!==V){for(let W of Q){if(!W.msgId)continue;let G=this.currentBatchReactionIds.get(W.msgId);if(this.currentBatchReactionIds.delete(W.msgId),G)A$(W.msgId,G)}this.status="idle";return}if(this.proc!==$||this.procEpoch!==Z||!$.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);for(let W of Q){if(!W.msgId)continue;let G=this.currentBatchReactionIds.get(W.msgId);if(this.currentBatchReactionIds.delete(W.msgId),G)A$(W.msgId,G)}this.status="stopped";return}try{this.sendClaimedUserText($,Y)}catch(W){z(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${W}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await y(this.chatId,`❌ ${this.backendLabel($.provider)} 接收消息失败: ${U(W)}。这批消息未开始处理,请重发。`),this.status="idle";return}this.status="working"}finally{if(this.releaseTurnOpen(J),!this.currentTurn&&this.pendingMidTurnMsgs.length>0&&this.proc===$&&this.procEpoch===Z&&$.isAlive())this.drainMidTurnAndOpen()}}async terminalizeSupersededCard($,Z,J){let Q=J?await U$($,M.footer,this.footerElement(Z)):!0;V$($);let Y=await q$($,p$({suffix:Z}));if(Q&&Y){await S$($);return}let H=`footer=${Q?"ok":"MISS"}, settings=${Y?"ok":"MISS"}`;z(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${H}`),await y(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${H})。`)}rebuildBackgroundAfterTurnOpenFailure(){if(!this.pendingRebuildBackgroundCard)return;if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length===0)return;this.openBackgroundCard().catch(($)=>{z(`session "${this.sessionName}": background rebuild after turn-open failure failed: ${U($)}`)})}async openTurnCard($,Z,J,Q={}){if(!this.ownsTurnOpen($))return null;if(this.bgResumePending=!1,this.backgroundCard&&g0(this.backgroundTasks))try{await this.migrateBackgroundCard(),this.pendingRebuildBackgroundCard=!0}catch(L){z(`session "${this.sessionName}": background migrate failed (non-blocking): ${L}`),this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(!this.ownsTurnOpen($))return null;let Y=++this.turnCounter,H=this.pendingTurnInputs;this.pendingTurnInputs=[],this.lastTurnUserPreview=H[0]?.slice(0,80)??this.lastTurnUserPreview,z(`session "${this.sessionName}": openTurnCard turn=${Y} trigger=${J} inputs=${H.length}`);let X=this.runtimeModelSelection(),V=this.withModel(Q.initialFooter??"Waiting...(0s)",X),W=H9({sessionName:this.sessionName,turn:Y,provider:X.provider,model:X.model??void 0,effort:X.effort,kind:J,userInputs:H,initialFooter:V,directStart:Q.directStart}),G=await c(this.chatId,W);if(!G){if(!this.ownsTurnOpen($))return null;if(z(`session "${this.sessionName}": openTurnCard sendCard EXHAUSTED retries — surfacing via raw text`),J==="user_message")await y(this.chatId,`❌ 创建对话卡片失败 (Feishu SDK 重试 3 次后仍连不上)。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return this.rebuildBackgroundAfterTurnOpenFailure(),null}let K;try{K=await r$(G)}catch(L){if(z(`session "${this.sessionName}": id_convert failed: ${L}`),J==="user_message"&&this.ownsTurnOpen($))await y(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);if(this.ownsTurnOpen($))this.rebuildBackgroundAfterTurnOpenFailure();return null}let _=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(H.length>0?1:0)+1;if(!this.ownsTurnOpen($))return c$(K,_),await this.terminalizeSupersededCard(K,"⚠️ 会话已切换,本卡已作废",!0),null;let B={cardId:K,...X,messageId:G,userOpenId:Z,trigger:J,toolCount:0,toolByUseId:new Map,planSteps:[],planExplanation:null,planUpdateCount:0,goalUpdateCount:0,contextCompactCount:0,contextCompactionPending:new Map,contextCompactionCompleted:new Set,contextCompactionCompleting:new Set,contextCompactionEndOnly:new Map,lastContextCompactionCompletedAt:0,lastContextCompactionWasAnonymous:!1,toolBatches:new Map,openBatchI:null,taskCreateI:null,taskUpdateI:null,taskBoardResetThisTurn:!1,taskLiveInserted:!1,planLiveInserted:!1,assistantSegmentCount:0,currentAssistantSegmentId:null,currentAssistantText:"",segmentTexts:new Map,startedAt:Date.now(),footerStatusHandle:null,footerStatusStartedAt:0,footerStatusLabel:null,rotating:null,rotateCount:0,failureRotateCount:0,cardWriteFailureNotified:!1,rotateGivenUp:!1,outboundSeenPaths:new Set,outboundSentPaths:new Set};if(c$(K,_,(L,A)=>{this.onCardWriteFailure(B,K,L,A)}),this.currentTurn=B,Q.startThinking!==!1)this.startThinkingFooter(B);if($.pendingCompactions.length>0){let L=$.pendingCompactions.splice(0);z(`session "${this.sessionName}": replay ${L.length} context compaction event(s) buffered during card open`);for(let A of L)this.handleContextCompacted(A)}let j=this.takeOrphanAssistantText();if(j)this.appendAssistant(j),this.finalizeCurrentAssistantSegment();if(this.pendingRebuildBackgroundCard){if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length>0)this.openBackgroundCard().catch((L)=>{z(`session "${this.sessionName}": background rebuild failed: ${U(L)}`)})}return B}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotateGivenUp)return;if($.rotating)return;if(u6($.cardId)<UB)return;this.startMidTurnRotate($)}onCardWriteFailure($,Z,J,Q){let Y=this.currentTurn;if(Y!==$){z(`session "${this.sessionName}": ignore stale card failure card=${Z.slice(0,12)} code=${J??"n/a"} (turn owner changed)`);return}if(Y.cardId!==Z){z(`session "${this.sessionName}": ignore retired-card failure card=${Z.slice(0,12)} current=${Y.cardId.slice(0,12)} code=${J??"n/a"}`);return}if(Y.rotating)return;if(Y.rotateGivenUp)return;if(!gZ(J,Q)){let H=Q?.operation??"unknown operation",X=Q?.elementId?` element=${Q.elementId}`:"";if(z(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${H}${X} code=${J??"n/a"} — not rotating`),!Y.cardWriteFailureNotified)Y.cardWriteFailureNotified=!0,y(this.chatId,`⚠️ 对话卡片有一项写入失败(code=${J??"MISS"}, ${H})。该错误不是卡片元素上限,已停止无效换卡;其余输出继续处理。`);return}if(Y.failureRotateCount>=l2){Y.rotateGivenUp=!0,this.stopFooterStatus(Y),v4(Y.cardId),z(`session "${this.sessionName}": failure-rotate cap (${l2}) hit — giving up, rest of turn is log-only`),y(this.chatId,`⚠️ 本轮已因元素容量超限换卡 ${l2} 次,现停止继续换卡;本轮后续输出仅日志可见。`);return}z(`session "${this.sessionName}": confirmed element limit (${J}) on card=${Y.cardId.slice(0,8)}… — rotating to fresh card`),Y.failureRotateCount++,this.startMidTurnRotate(Y)}startMidTurnRotate($){if($.rotating)return;$.rotateCount++;let{cardId:Z,toolByUseId:J,toolBatches:Q}=$,Y={value:null},H=(X,V)=>{if(!Y.value)Y.value={code:X,failure:V}};$.rotating=(async()=>{try{z(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${u6(Z)}`);let X=H9({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort,kind:"card_full",userInputs:[]}),V=await c(this.chatId,X);if(!V){if(z(`session "${this.sessionName}": mid-turn rotate sendCard EXHAUSTED — staying on old card,subsequent adds will drop`),this.currentTurn===$)$.rotateGivenUp=!0,this.stopFooterStatus($),v4($.cardId);await y(this.chatId,"⚠️ 卡片元素超出飞书上限,本轮后续输出仅日志可见(开新卡失败)。");return}let W;try{W=await r$(V)}catch(j){if(z(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${j}`),this.currentTurn===$)$.rotateGivenUp=!0,this.stopFooterStatus($),v4($.cardId),await y(this.chatId,"⚠️ 新对话卡已发送,但 Card Kit 初始化失败;已停止继续换卡,本轮后续输出仅日志可见。");return}c$(W,2,(j,L)=>{if($.rotating){H(j,L);return}this.onCardWriteFailure($,W,j,L)});let G=$.assistantWriteInflight?.get(Z);if(G?.size)await Promise.allSettled([...G]);this.stopFooterStatus($),$.cardId=W,$.messageId=V,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let K=$.currentAssistantSegmentId,_=($.currentAssistantText??"").trim(),B=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,_)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)W$($.cardId,Y1(this.taskBoard),{type:"insert_before",targetElementId:M.footer});if($.planLiveInserted)W$($.cardId,b2($.planSteps,$.planExplanation,M.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?M.taskBoardLive:M.footer});for(let j of $.contextCompactionPending.values()){if(j.cardId!==Z)continue;j.cardId=W,j.created=!1,j.createFailure=void 0;let L=M.contextCompact(j.i);j.createPromise=I4(W,S2(j.i,j.notice,L),{type:"insert_before",targetElementId:B$($)}).then((A)=>{if(j.cardId===W)j.created=A.landed,j.createFailure=A.failure;return A.landed})}for(let[j,L]of B){if(K&&_&&j===K)continue;if(!I1(Z,j))continue;let A=$.assistantSegmentCount++,P=M.assistant(A);$.segmentTexts.set(P,L),await this.addCompletedAssistantSegment($,P,L)}if(n7(this,Z,W,J,Q),await m$(Z),n7(this,Z,W,J,Q),K&&_){let j=$.assistantSegmentCount++,L=M.assistant(j);$.currentAssistantSegmentId=L,$.currentAssistantText=_,$.segmentTexts.set(L,_)}try{let j=$.mathRenderInflight?.get(Z);if(j?.size)await Promise.allSettled([...j]);await m$(Z);let L=$.mathRendered?.get(Z);for(let[D,F]of B){if(K&&_&&D===K)continue;if(I1(Z,D))continue;if(L?.has(D))continue;await i(Z,D,this.completedAssistantElement(D,F))}let A=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",P=await U$(Z,M.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${A}`)),{notifyCardFailure:!1});V$(Z);let R=await q$(Z,p$({suffix:"\uD83D\uDCE8 转下一张"}));if(P&&R)await S$(Z);else z(`session "${this.sessionName}": rotate old-card terminal MISS footer=${P} settings=${R}`),await y(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${P?"ok":"MISS"}, settings=${R?"ok":"MISS"}),本轮输出已续到新卡。`)}catch(j){z(`session "${this.sessionName}": mid-turn rotate close-old failed: ${j}`)}z(`session "${this.sessionName}": mid-turn rotate done old=${Z.slice(0,8)}… new=${W.slice(0,8)}…`)}finally{$.rotating=null;let X=Y.value;if(X&&this.currentTurn===$)this.onCardWriteFailure($,$.cardId,X.code,X.failure)}})()}addPlanSnapshotOnCurrentTurn(){let $=this.currentTurn;if(!$||$.planSteps.length===0)return;this.maybeMidTurnRotate();let Z=$.cardId,J=M.planUpdate($.planUpdateCount++);W$(Z,V7($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:B$($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=M.goalUpdate(Z.goalUpdateCount++);W$(Z.cardId,W7($,J),{type:"insert_before",targetElementId:B$(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=M.goalUpdate($.goalUpdateCount++);W$($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
198
200
 
199
- 已清除`},{type:"insert_before",targetElementId:j$($)})}handleContextCompacted($){let Z=qH($);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<o9){G(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Q=$.itemId?`item:${$.itemId}`:void 0,Y=Z.find((D)=>D.startsWith("turn:")),H=Q??Y,V=H?this.contextCompactionReceipts.get(H):void 0;if(Q&&!V&&$.phase!=="start"&&Y){let D=this.contextCompactionReceipts.get(Y);if(!D?.hasItemAlias&&D?.completed&&Date.now()-D.completedAt<o9||!D?.hasItemAlias&&D?.completionKey&&J?.contextCompactionCompleting.has(D.completionKey))H=Y,V=D,D.hasItemAlias=!0,this.contextCompactionReceipts.delete(Q),this.contextCompactionReceipts.set(Q,D)}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(H&&V?.completed){G(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${H}`);return}let X=this.contextCompactionOwnerId(J);if(H&&V&&V.ownerId!==X){this.rememberContextCompactionReceipt(Z,null,!0),G(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${H} (turn owner changed)`);return}if(H&&V?.completionKey&&J.contextCompactionCompleting.has(V.completionKey)){G(`session "${this.sessionName}": context compaction alias already writing receipt=${H}`);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<o9){G(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let D=Wj($);if(J.contextCompactionPending.has(D)||J.contextCompactionCompleted.has(D)){G(`session "${this.sessionName}": duplicate context compaction start ignored key=${D}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,X,!1);let F=J.contextCompactCount++,y=J.cardId,C=M.contextCompact(F),x={i:F,cardId:y,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};x.createPromise=g4(y,b2(F,$,C),{type:"insert_before",targetElementId:j$(J)}).then((m)=>{if(x.cardId===y)x.created=m.landed,x.createFailure=m.failure;return m.landed}),J.contextCompactionPending.set(D,x),G(`session "${this.sessionName}": context compaction start #${F+1} key=${D}`),G0(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<o9){G(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let W=$.itemId||$.turnId;if(W&&J.contextCompactionCompleted.has(W)){G(`session "${this.sessionName}": duplicate context compaction completion ignored key=${W}`);return}let z=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:zj(J),K=z?J.contextCompactionPending.get(z):void 0,_=z??W??"__anonymous__";if(J.contextCompactionCompleting.has(_)){G(`session "${this.sessionName}": context compaction completion already writing key=${_}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openBatchI=null,this.maybeMidTurnRotate();let j=Gj(K?.notice,$),B=J.contextCompactionEndOnly.get(_),L=K?.i??B??J.contextCompactCount++;if(!K&&B===void 0)J.contextCompactionEndOnly.set(_,L);J.contextCompactionCompleting.add(_);let P=[...new Set([...qH(K?.notice??{}),...Z])];if(P.length>0)this.rememberContextCompactionReceipt(P,X,!1,_);let A=M.contextCompact(L),R=b2(L,j,A);G(`session "${this.sessionName}": context compaction completion write #${L+1} key=${_}`),(async()=>{let D=!1;if(!K)for(let F=0;F<l2+2;F++){let y=J.cardId;if(D=await y0(y,R,{type:"insert_before",targetElementId:j$(J)}),D)break;let C=J.rotating;if(C){await C;continue}if(J.cardId!==y)continue;break}else for(let F=0;F<l2+2;F++){let y=K.cardId;if(await K.createPromise,K.cardId!==y)continue;if(K.created)D=await U$(y,A,R);else{if(IZ(K.createFailure?.code,K.createFailure))cZ(y,A),D=await U$(y,A,R,{notifyCardFailure:!1});if(!D)D=await y0(y,R,{type:"insert_before",targetElementId:j$(J)})}if(K.cardId!==y)continue;if(D){K.created=!0;break}let C=J.rotating;if(C){await C;continue}if(K.cardId!==y)continue;break}if(J.contextCompactionCompleting.delete(_),!D){G(`session "${this.sessionName}": context compaction completion write MISS #${L+1} key=${_}`);return}if(z&&J.contextCompactionPending.get(z)===K)J.contextCompactionPending.delete(z);if(J.contextCompactionEndOnly.delete(_),_!=="__anonymous__")J.contextCompactionCompleted.add(_);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=_==="__anonymous__",P.length>0){let F=[...this.contextCompactionReceipts.entries()].filter(([,y])=>y.completionKey===_).map(([y])=>y);this.rememberContextCompactionReceipt([...new Set([...P,...F])],null,!0)}G(`session "${this.sessionName}": context compaction completed #${L+1} key=${_}`)})().catch((D)=>{J.contextCompactionCompleting.delete(_),G(`session "${this.sessionName}": context compaction completion transaction failed: ${U(D)}`)}),G0(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`)}contextCompactionOwnerId($){let Z=this.contextCompactionOwnerIds.get($);if(Z!==void 0)return Z;let J=++this.contextCompactionOwnerSequence;return this.contextCompactionOwnerIds.set($,J),J}rememberContextCompactionReceipt($,Z,J,Q){let Y={ownerId:J?null:Z,completed:J,completedAt:J?Date.now():0,...J||!Q?{}:{completionKey:Q},hasItemAlias:$.some((H)=>H.startsWith("item:"))};for(let H of $)this.contextCompactionReceipts.delete(H),this.contextCompactionReceipts.set(H,Y);while(this.contextCompactionReceipts.size>Bj){let H;for(let V of this.contextCompactionReceipts.values()){if(V.completed){H=V;break}H??=V}if(!H)break;for(let[V,X]of this.contextCompactionReceipts)if(X===H)this.contextCompactionReceipts.delete(V)}}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,W$(Z.cardId,S2(Z.planSteps,Z.planExplanation,M.planLive),{type:"insert_before",targetElementId:J})}else d(Z.cardId,M.planLive,S2(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&&Y9(Z)===Y9(J))return;let Q=this.currentTurn;if(Q){if(this.startWorkingFooter(Q),Q.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();Q.openBatchI=null}this.addGoalUpdateOnCurrentTurn(J)}handleThreadGoalCleared(){if(!this.currentGoal)return;this.currentGoal=null;let $=this.currentTurn;if(!$)return;if(this.startWorkingFooter($),$.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();$.openBatchI=null,this.addGoalClearedOnCurrentTurn()}appendAssistant($){if(!this.currentTurn){if(this.openingTurn||this.bgResumeCardless)this.orphanAssistantCurrent+=$;return}let Z=this.currentTurn;if(this.startWritingFooter(Z),!Z.currentAssistantSegmentId){Z.openBatchI=null,this.maybeMidTurnRotate();let H=Z.assistantSegmentCount++,V=M.assistant(H);Z.currentAssistantSegmentId=V,Z.currentAssistantText=""}Z.currentAssistantText+=$;let J=Z.currentAssistantSegmentId;if(!J)return;Z.segmentTexts.set(J,Z.currentAssistantText),this.processOutboundMarkers(Z.currentAssistantText);let Y=this.cleanAssistantTextForDisplay(Z.currentAssistantText).slice(0,40);G0(Z.cardId,Y)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
201
+ 已清除`},{type:"insert_before",targetElementId:B$($)})}handleContextCompacted($){let Z=LH($);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;z(`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<a9){z(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Q=$.itemId?`item:${$.itemId}`:void 0,Y=Z.find((D)=>D.startsWith("turn:")),H=Q??Y,X=H?this.contextCompactionReceipts.get(H):void 0;if(Q&&!X&&$.phase!=="start"&&Y){let D=this.contextCompactionReceipts.get(Y);if(!D?.hasItemAlias&&D?.completed&&Date.now()-D.completedAt<a9||!D?.hasItemAlias&&D?.completionKey&&J?.contextCompactionCompleting.has(D.completionKey))H=Y,X=D,D.hasItemAlias=!0,this.contextCompactionReceipts.delete(Q),this.contextCompactionReceipts.set(Q,D)}if(!J){if(this.openingTurnOwner?.backendTurnStarted){this.openingTurnOwner.pendingCompactions.push($),z(`session "${this.sessionName}": buffer context compaction ${$.phase??"event"} while turn card opens`);return}if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");z(`session "${this.sessionName}": context compaction ${$.phase??"event"} with no current turn thread=${$.threadId??"-"} turn=${$.turnId??"-"} item=${$.itemId??"-"}`);return}if(H&&X?.completed){z(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${H}`);return}let V=this.contextCompactionOwnerId(J);if(H&&X&&X.ownerId!==V){this.rememberContextCompactionReceipt(Z,null,!0),z(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${H} (turn owner changed)`);return}if(H&&X?.completionKey&&J.contextCompactionCompleting.has(X.completionKey)){z(`session "${this.sessionName}": context compaction alias already writing receipt=${H}`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.contextCompactionCompleting.has("__anonymous__")){z(`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<a9){z(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let D=jB($);if(J.contextCompactionPending.has(D)||J.contextCompactionCompleted.has(D)){z(`session "${this.sessionName}": duplicate context compaction start ignored key=${D}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,V,!1);let F=J.contextCompactCount++,N=J.cardId,C=M.contextCompact(F),x={i:F,cardId:N,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};x.createPromise=I4(N,S2(F,$,C),{type:"insert_before",targetElementId:B$(J)}).then((m)=>{if(x.cardId===N)x.created=m.landed,x.createFailure=m.failure;return m.landed}),J.contextCompactionPending.set(D,x),z(`session "${this.sessionName}": context compaction start #${F+1} key=${D}`),z0(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionCompleting.size>0){z(`session "${this.sessionName}": anonymous context compaction duplicate ignored while completion writes`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionPending.size===0&&Date.now()-J.lastContextCompactionCompletedAt<a9){z(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let W=$.itemId||$.turnId;if(W&&J.contextCompactionCompleted.has(W)){z(`session "${this.sessionName}": duplicate context compaction completion ignored key=${W}`);return}let G=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:LB(J),K=G?J.contextCompactionPending.get(G):void 0,_=G??W??"__anonymous__";if(J.contextCompactionCompleting.has(_)){z(`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=DB(K?.notice,$),j=J.contextCompactionEndOnly.get(_),L=K?.i??j??J.contextCompactCount++;if(!K&&j===void 0)J.contextCompactionEndOnly.set(_,L);J.contextCompactionCompleting.add(_);let A=[...new Set([...LH(K?.notice??{}),...Z])];if(A.length>0)this.rememberContextCompactionReceipt(A,V,!1,_);let P=M.contextCompact(L),R=S2(L,B,P);z(`session "${this.sessionName}": context compaction completion write #${L+1} key=${_}`),(async()=>{let D=!1;if(!K)for(let F=0;F<l2+2;F++){let N=J.cardId;if(D=await E0(N,R,{type:"insert_before",targetElementId:B$(J)}),D)break;let C=J.rotating;if(C){await C;continue}if(J.cardId!==N)continue;break}else for(let F=0;F<l2+2;F++){let N=K.cardId;if(await K.createPromise,K.cardId!==N)continue;if(K.created)D=await U$(N,P,R);else{if(cZ(K.createFailure?.code,K.createFailure))mZ(N,P),D=await U$(N,P,R,{notifyCardFailure:!1});if(!D)D=await E0(N,R,{type:"insert_before",targetElementId:B$(J)})}if(K.cardId!==N)continue;if(D){K.created=!0;break}let C=J.rotating;if(C){await C;continue}if(K.cardId!==N)continue;break}if(J.contextCompactionCompleting.delete(_),!D){z(`session "${this.sessionName}": context compaction completion write MISS #${L+1} key=${_}`);return}if(G&&J.contextCompactionPending.get(G)===K)J.contextCompactionPending.delete(G);if(J.contextCompactionEndOnly.delete(_),_!=="__anonymous__")J.contextCompactionCompleted.add(_);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=_==="__anonymous__",A.length>0){let F=[...this.contextCompactionReceipts.entries()].filter(([,N])=>N.completionKey===_).map(([N])=>N);this.rememberContextCompactionReceipt([...new Set([...A,...F])],null,!0)}z(`session "${this.sessionName}": context compaction completed #${L+1} key=${_}`)})().catch((D)=>{J.contextCompactionCompleting.delete(_),z(`session "${this.sessionName}": context compaction completion transaction failed: ${U(D)}`)}),z0(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`)}contextCompactionOwnerId($){let Z=this.contextCompactionOwnerIds.get($);if(Z!==void 0)return Z;let J=++this.contextCompactionOwnerSequence;return this.contextCompactionOwnerIds.set($,J),J}rememberContextCompactionReceipt($,Z,J,Q){let Y={ownerId:J?null:Z,completed:J,completedAt:J?Date.now():0,...J||!Q?{}:{completionKey:Q},hasItemAlias:$.some((H)=>H.startsWith("item:"))};for(let H of $)this.contextCompactionReceipts.delete(H),this.contextCompactionReceipts.set(H,Y);while(this.contextCompactionReceipts.size>MB){let H;for(let X of this.contextCompactionReceipts.values()){if(X.completed){H=X;break}H??=X}if(!H)break;for(let[X,V]of this.contextCompactionReceipts)if(V===H)this.contextCompactionReceipts.delete(X)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){z(`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))z(`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,W$(Z.cardId,b2(Z.planSteps,Z.planExplanation,M.planLive),{type:"insert_before",targetElementId:J})}else i(Z.cardId,M.planLive,b2(Z.planSteps,Z.planExplanation,M.planLive));this.addPlanSnapshotOnCurrentTurn()}handlePlanDelta($){if(typeof $.delta!=="string"||!$.delta){z(`session "${this.sessionName}": item/plan/delta missing delta text`);return}if(typeof $.itemId!=="string"||!$.itemId)z(`session "${this.sessionName}": item/plan/delta missing itemId`)}handleThreadGoalUpdated($){if(!$||typeof $.objective!=="string"){z(`session "${this.sessionName}": thread/goal/updated missing objective`);return}if($.tokenBudget!=null&&typeof $.tokenBudget!=="number")z(`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&&Y9(Z)===Y9(J))return;let Q=this.currentTurn;if(Q){if(this.startWorkingFooter(Q),Q.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();Q.openBatchI=null}this.addGoalUpdateOnCurrentTurn(J)}handleThreadGoalCleared(){if(!this.currentGoal)return;this.currentGoal=null;let $=this.currentTurn;if(!$)return;if(this.startWorkingFooter($),$.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();$.openBatchI=null,this.addGoalClearedOnCurrentTurn()}appendAssistant($){if(!this.currentTurn){if(this.openingTurn||this.bgResumeCardless)this.orphanAssistantCurrent+=$;return}let Z=this.currentTurn;if(this.startWritingFooter(Z),!Z.currentAssistantSegmentId){Z.openBatchI=null,this.maybeMidTurnRotate();let H=Z.assistantSegmentCount++,X=M.assistant(H);Z.currentAssistantSegmentId=X,Z.currentAssistantText=""}Z.currentAssistantText+=$;let J=Z.currentAssistantSegmentId;if(!J)return;Z.segmentTexts.set(J,Z.currentAssistantText),this.processOutboundMarkers(Z.currentAssistantText);let Y=this.cleanAssistantTextForDisplay(Z.currentAssistantText).slice(0,40);z0(Z.cardId,Y)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
200
202
 
201
- `).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 (${$})`),O(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
203
+ `).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;z(`session "${this.sessionName}": flushing ${J.length} chars of orphan assistant text (${$})`),O(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
202
204
 
203
- ${J}`)}completedAssistantElement($,Z){if(i7(Z))return this.mathAssistantContainer($,[{type:"markdown",text:Z}]);return{tag:"markdown",element_id:$,content:this.cleanAssistantTextForDisplay(Z).trim()||" "}}mathAssistantContainer($,Z){let J=Z.map((Q)=>Q.type==="markdown"?{tag:"markdown",content:this.cleanAssistantTextForDisplay(Q.text).trim()||" "}:{...Q.element});return{tag:"column_set",element_id:$,flex_mode:"none",columns:[{tag:"column",width:"weighted",weight:1,elements:J.length?J:[{tag:"markdown",content:" "}]}]}}async replaceSegmentWithMathImgs($,Z,J,Q){let Y=await FQ(Q);if(!await U$(Z,J,this.mathAssistantContainer(J,Y.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} (${Y.renderedImageCount} img, ${Y.blocks.length} blocks)`)}addCompletedAssistantSegment($,Z,J){let Q=$.cardId,Y=j$($),H=(async()=>{if(!await y0(Q,this.completedAssistantElement(Z,J),{type:"insert_before",targetElementId:Y}))return G(`session "${this.sessionName}": assistant segment ${Z} raw write failed on card=${Q}`),!1;if(i7(J)){let X=this.replaceSegmentWithMathImgs($,Q,Z,J).catch((W)=>G(`session "${this.sessionName}": math render ${Z} failed: ${W}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Q)??$.mathRenderInflight.set(Q,new Set),$.mathRenderInflight.get(Q).add(X),X.finally(()=>$.mathRenderInflight?.get(Q)?.delete(X))}return!0})();return $.assistantWriteInflight??=new Map,$.assistantWriteInflight.get(Q)??$.assistantWriteInflight.set(Q,new Set),$.assistantWriteInflight.get(Q).add(H),H.finally(()=>$.assistantWriteInflight?.get(Q)?.delete(H)),H}async sendAssistantTextFallback($,Z){let J=$.trim();if(!J)return;let Q=`⚠️ 对话卡片正文写入失败(${Z}),以下为 agent 原始回复:
205
+ ${J}`)}completedAssistantElement($,Z){if(i7(Z))return this.mathAssistantContainer($,[{type:"markdown",text:Z}]);return{tag:"markdown",element_id:$,content:this.cleanAssistantTextForDisplay(Z).trim()||" "}}mathAssistantContainer($,Z){let J=Z.map((Q)=>Q.type==="markdown"?{tag:"markdown",content:this.cleanAssistantTextForDisplay(Q.text).trim()||" "}:{...Q.element});return{tag:"column_set",element_id:$,flex_mode:"none",columns:[{tag:"column",width:"weighted",weight:1,elements:J.length?J:[{tag:"markdown",content:" "}]}]}}async replaceSegmentWithMathImgs($,Z,J,Q){let Y=await MQ(Q);if(!await U$(Z,J,this.mathAssistantContainer(J,Y.blocks),{notifyCardFailure:!1})){z(`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),z(`session "${this.sessionName}": math rendered ${J} (${Y.renderedImageCount} img, ${Y.blocks.length} blocks)`)}addCompletedAssistantSegment($,Z,J){let Q=$.cardId,Y=B$($),H=(async()=>{if(!await E0(Q,this.completedAssistantElement(Z,J),{type:"insert_before",targetElementId:Y}))return z(`session "${this.sessionName}": assistant segment ${Z} raw write failed on card=${Q}`),!1;if(i7(J)){let V=this.replaceSegmentWithMathImgs($,Q,Z,J).catch((W)=>z(`session "${this.sessionName}": math render ${Z} failed: ${W}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Q)??$.mathRenderInflight.set(Q,new Set),$.mathRenderInflight.get(Q).add(V),V.finally(()=>$.mathRenderInflight?.get(Q)?.delete(V))}return!0})();return $.assistantWriteInflight??=new Map,$.assistantWriteInflight.get(Q)??$.assistantWriteInflight.set(Q,new Set),$.assistantWriteInflight.get(Q).add(H),H.finally(()=>$.assistantWriteInflight?.get(Q)?.delete(H)),H}async sendAssistantTextFallback($,Z){let J=$.trim();if(!J)return;let Q=`⚠️ 对话卡片正文写入失败(${Z}),以下为 agent 原始回复:
204
206
 
205
- ${J}`;if(!await O(this.chatId,Q))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($.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 ZQ($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return a($)}sendOutboundPath($,Z){let J=E9($.trim());if(!J)return;let Q=this.currentTurn;if(Q?.outboundSeenPaths.has(J))return;if(Q?.outboundSeenPaths.add(J),!Vj(J)){G(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}Q?.outboundSentPaths.add(J),G(`session "${this.sessionName}": outbound send from ${Z}: ${J}`),I8(this.chatId,J)}startFooterStatus($,Z){if($.rotateGivenUp)return;if($.footerStatusHandle&&$.footerStatusLabel===Z)return;this.stopFooterStatus($),$.footerStatusLabel=Z,$.footerStatusStartedAt=Date.now();let J=()=>{if($.footerStatusLabel!==Z)return;let{label:Y}=R0(Date.now()-$.footerStatusStartedAt,q1());this.replaceFooterContent($.cardId,this.withModel(`${Z} (${Y})`))},Q=()=>{if($.footerStatusLabel!==Z)return;let{nextDelayMs:Y}=R0(Date.now()-$.footerStatusStartedAt,q1());$.footerStatusHandle=setTimeout(()=>{J(),Q()},Math.max(1,Math.ceil(Y)))};J(),Q()}startThinkingFooter($){this.startFooterStatus($,Kj)}startWritingFooter($){this.startFooterStatus($,_j)}startWorkingFooter($){this.startFooterStatus($,qj)}stopFooterStatus($){if(!$)return;if($.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null,$.footerStatusStartedAt=0,$.footerStatusLabel=null}async footerUsageSuffix($,Z,J,Q,Y){if(J&&(!Q||!Q.enabled||Q.agent!==$))return"";if(Q?.agent===$&&Q.enabled&&$==="claude"){let V=await Q.readUsage(),X=V.windows.find((z)=>z.kind==="fiveHour"),W=V.windows.find((z)=>z.kind==="weekly");if(X||W)return this.fmtDualWindowSuffix(X??null,W??null);return V.state==="ok"&&V.planLabel?` | ${V.planLabel}`:""}if($==="codex"){let V=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits?Z:null,W=(V?await rJ(()=>V.readRateLimits()):null)??Y;return W?.state==="ok"?this.fmtDualWindowSuffix(W.fiveHour??null,W.weekly??null):""}let H=await g7();return H.state==="ok"?this.fmtDualWindowSuffix(H.fiveHour??null,H.weekly??null):""}fmtDualWindowSuffix($,Z){let J=(V)=>V.resetsAt&&V.resetsAt.getTime()>Date.now()?j0(V.resetsAt):"",Q=(V)=>{if(V?.percent==null)return null;let X=J(V);return X?`${X}·${Math.round(V.percent)}%`:`${Math.round(V.percent)}%`},Y=Q($),H=Q(Z);if(Y&&H)return` | ${Y}·[${H}]`;if(Y)return` | ${Y}`;if(H)return` | [${H}]`;return""}waitForTurnCloses(){let $=[...this.turnCloseInflight];if($.length===0)return Promise.resolve();return Promise.allSettled($).then((Z)=>{let J=Z.filter((Q)=>Q.status==="rejected").map((Q)=>Q.reason);if(J.length===1)throw J[0];if(J.length>1)throw AggregateError(J,`turn close failed: ${J.map(U).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();this.currentTurn=null,this.stopFooterStatus(J);let Q=this.proc,Y={turn:J,proc:Q,procEpoch:this.procEpoch,contextTokens:this.currentContextTokens(Q),contextLimit:this.contextLimitForDisplay(Q),lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,tokenSourceId:this.selectedTokenSourceId,tokenSource:this.currentTokenSource(),codexUsage:aJ(),currentBatchReactionIds:this.currentBatchReactionIds,pendingReactionIds:this.pendingReactionIds};this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map;let H=this.finishTurnCardClose(Y,$,Z).finally(()=>this.releaseTurnCloseReactions(Y));return this.turnCloseInflight.add(H),H.then(()=>{this.turnCloseInflight.delete(H)},()=>{this.turnCloseInflight.delete(H)}),H}async finishTurnCardClose($,Z,J={}){let{turn:Q}=$;if(Q.rotating)await Q.rotating;this.stopFooterStatus(Q);let Y=((Date.now()-Q.startedAt)/1000).toFixed(1),H=Q.cardId,V=Q.segmentTexts;await m$(H);let X=new Map;if(Q.currentAssistantSegmentId&&Q.currentAssistantText.trim()){let{currentAssistantSegmentId:F,currentAssistantText:y}=Q;if(!await this.addCompletedAssistantSegment(Q,F,y))X.set(F,y);Q.currentAssistantSegmentId=null,Q.currentAssistantText=""}let W=Q.assistantWriteInflight?.get(H);if(W?.size)await Promise.allSettled([...W]);let z=Q.mathRenderInflight?.get(H);if(z?.size)await Promise.allSettled([...z]);let K=Q.mathRendered?.get(H);for(let[F,y]of V){if(g1(H,F)){X.set(F,y);continue}if(K?.has(F))continue;await d(H,F,this.completedAssistantElement(F,y))}if(Q.rotateGivenUp)for(let[F,y]of V)X.set(F,y);let _=Z?Z:"✅",j=[`${_} ⏱ ${Y}s`];if(J.hasFreshResult){let{contextTokens:F,contextLimit:y}=$,C=Q.provider==="claude",x=Y7(F,y,C?0:void 0);if(x)j.push(`\uD83E\uDDE0 ${x}`);let m=$.lastTurnDelta?.costUsd??0;if(m>0)j.push(`\uD83D\uDCB0 $${m.toFixed(3)}`)}if(Q.contextCompactCount>0)j.push(`\uD83D\uDEA8 压缩×${Q.contextCompactCount}`);if(Q.outboundSentPaths.size>0)j.push(`\uD83D\uDCCE ${Q.outboundSentPaths.size}`);let B=this.modelLine(Q);if(B)j.push(B);let L=j.join(" | "),P=J.hasFreshResult?H7($.lastTurnUsage)+(Q.rotateGivenUp?"":await this.footerUsageSuffix(Q.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage)):"",A=P?`${L}
206
- ${P}`:L,R=await U$(H,M.footer,this.footerElement(A));X$(H);let D=await q$(H,p$({durationSec:Y,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(R&&D)await b$(H);else{let F=`footer=${R?"ok":"MISS"}, settings=${D?"ok":"MISS"}`;G(`session "${this.sessionName}": terminal card transaction incomplete card=${H.slice(0,12)} ${F}`),await N(this.chatId,`⚠️ 对话卡片终态写入失败 (${F})。本轮已结束: ${_}`)}for(let F of X.values())await this.sendAssistantTextFallback(F,"CardKit 元素未落地");if((J.forcePush||!Z)&&Q.userOpenId&&Q.messageId&&!Q.rotateGivenUp)a0(Q.messageId,[Q.userOpenId])}}});function f$($){return{card:{type:"raw",data:$}}}import{readFileSync as Lj}from"node:fs";function AH($){return A5.has($)}function UH($){A5.add($)}function MH($){A5.delete($)}function i2(){try{let $={};for(let[Z,J]of $0)$[Z]=J;V$(a9,$)}catch($){throw G(`notify-callbacks: save failed (${a9}): ${$}`),$}}function RH(){let $;try{$=Lj(a9,"utf8")}catch{return}try{let Z=JSON.parse($),J=Date.now()-FH,Q=0;for(let[Y,H]of Object.entries(Z)){if(!H||typeof H!=="object")continue;if(typeof H.notifyId!=="string"||typeof H.callbackUrl!=="string")continue;if(typeof H.createdAt!=="number"||H.createdAt<J){Q++;continue}$0.set(H.notifyId,H)}if(G(`notify-callbacks: loaded ${$0.size} registration(s)${Q?`, dropped ${Q} stale`:""}`),Q>0)i2()}catch(Z){G(`notify-callbacks: load failed (${a9}): ${Z}`)}}function OH($){let Z=Date.now();if(Z-PH>=Dj)Fj(Z),PH=Z;$0.set($.notifyId,$),i2()}function r9($){return $0.get($)}function U5($,Z,J){let Q=$0.get($);if(!Q)throw Error(`notify registration not found: ${$}`);let Y={resolvedAt:Q.resolvedAt,resolvedBy:Q.resolvedBy,unknownAt:Q.unknownAt,unknownBy:Q.unknownBy,unknownReason:Q.unknownReason};Q.resolvedAt=Date.now(),Q.resolvedBy={buttonId:Z,openId:J},delete Q.unknownAt,delete Q.unknownBy,delete Q.unknownReason;try{i2()}catch(H){if(Y.resolvedAt===void 0)delete Q.resolvedAt;else Q.resolvedAt=Y.resolvedAt;if(Y.resolvedBy===void 0)delete Q.resolvedBy;else Q.resolvedBy=Y.resolvedBy;if(Y.unknownAt===void 0)delete Q.unknownAt;else Q.unknownAt=Y.unknownAt;if(Y.unknownBy===void 0)delete Q.unknownBy;else Q.unknownBy=Y.unknownBy;if(Y.unknownReason===void 0)delete Q.unknownReason;else Q.unknownReason=Y.unknownReason;throw H}}function Pj($,Z,J,Q){let Y=$0.get($);if(!Y)throw Error(`notify registration not found: ${$}`);delete Y.resolvedAt,delete Y.resolvedBy,Y.unknownAt=Date.now(),Y.unknownBy={buttonId:Z,openId:J},Y.unknownReason=Q,i2()}function TH($,Z,J){try{return U5($,Z,J),{state:"complete"}}catch(Q){let H=`resolved tombstone persistence failed: ${Q instanceof Error?Q.message:String(Q)}`;try{Pj($,Z,J,H)}catch(V){let X=V instanceof Error?V.message:String(V);H+=`; unknown tombstone persistence also failed: ${X}`;let W=$0.get($);if(W)W.unknownReason=H}return{state:"unknown",detail:H}}}function Fj($=Date.now()){let Z=$-FH,J=0;for(let[Q,Y]of $0)if(typeof Y.createdAt!=="number"||Y.createdAt<Z)$0.delete(Q),J++;if(J>0)i2();return J}async function kH($,Z,J){let Q={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)},Y=new AbortController,H=setTimeout(()=>Y.abort(),DH);try{let V=await fetch($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q),signal:Y.signal});if(V.status>=200&&V.status<300){let W;try{let z=(await V.text()).trim();if(z.startsWith("{")){let K=JSON.parse(z),_=typeof K?.text==="string"?K.text:typeof K?.reply==="string"?K.reply:typeof K?.message==="string"?K.message:"";if(_.trim())W=_.trim().slice(0,500)}else if(z)W=z.slice(0,500)}catch{}return{ok:!0,detail:`${V.status}`,reply:W}}let X="";try{X=(await V.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${V.status}${X?` ${X}`:""}`}}catch(V){if(V?.name==="AbortError")return{ok:!1,detail:`回调超时 ${DH}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(V?.message??V).slice(0,160)}`}}finally{clearTimeout(H)}}function yH($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Q=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Y=Q?$.buttons.find((H)=>H.id===Q):void 0;return{notify_id:$.notifyId,project:$.project,message_id:$.messageId,resolved:Z,unknown:J,...Z?{button:Y?{id:Y.id,text:Y.text,type:Y.type}:{id:Q},resolved_at:$.resolvedAt,resolved_by:$.resolvedBy?.openId??null}:{},...J?{button:Y?{id:Y.id,text:Y.text,type:Y.type}:{id:Q},unknown_at:$.unknownAt,unknown_by:$.unknownBy?.openId??null,unknown_reason:$.unknownReason}:{}}}var FH=604800000,DH=2500,$0,PH,Dj=86400000,A5,a9;var M5=E(()=>{w();D$();h$();$0=new Map,PH=Date.now(),A5=new Set;a9=m5});import{createServer as Aj}from"node:http";import{randomUUID as Uj}from"node:crypto";function NH($){let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Q=!!($.buttons?.length&&$.notifyId),Y=new Date,H=`${String(Y.getHours()).padStart(2,"0")}:${String(Y.getMinutes()).padStart(2,"0")}`,V=[];for(let X of $.images??[])if(X.key)V.push({tag:"img",img_key:X.key,alt:{tag:"plain_text",content:"screenshot"}});else V.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${X.src}</font>`});if(V.push({tag:"markdown",content:f6($.text??"")||"_(空消息)_"}),$.resolution){let X=$.resolution,W;if(X.status==="processing")W=`<font color='blue'>⏳ 已选择:${X.text} · 推送中…</font>`;else if(X.status==="failed")W=`<font color='red'>⚠️ 已选:${X.text} · 回调失败:${X.detail??"未知"} · ${H}</font>`;else if(X.status==="delivered")W=`<font color='green'>✅ 已选择:${X.text} · 反馈已送达 · ${H}</font>`;else if(X.status==="unknown")W=`<font color='red'>⚠️ 已选择:${X.text} · 外部回调已成功,但本地确认状态未知,禁止自动重试 · ${H}</font>`;else W=`<font color='green'>✅ 已选择:${X.text} · ${H}</font>`;if(V.push({tag:"markdown",content:W}),X.status==="delivered"&&X.reply)V.push({tag:"markdown",content:a(X.reply)})}if(Q&&(!$.resolution||$.resolution.status==="failed"))V.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 V.push({tag:"hr"}),V.push({tag:"markdown",content:`<font color='grey'>via notify · ${H}</font>`}),{schema:"2.0",config:Q?{update_multi:!0}:{},header:{title:{tag:"plain_text",content:`${J} ${$.title}`},template:Z},body:{elements:V}}}function Tj($){if($===void 0||$===null)return{buttons:[]};if(!Array.isArray($))return{error:'"buttons" must be an array'};if($.length===0)return{buttons:[]};let Z=new Set,J=[];for(let Q of $){if(!Q||typeof Q!=="object")return{error:"each button must be an object"};let Y=String(Q.id??"").trim(),H=String(Q.text??"").trim();if(!Oj.test(Y))return{error:`button id "${Y.slice(0,32)}" invalid (need ^[A-Za-z0-9_-]{1,64}$)`};if(!H)return{error:`button "${Y}" missing text`};if(H.length>EH)return{error:`button "${Y}" text > ${EH} chars`};if(Z.has(Y))return{error:`button id "${Y}" duplicated`};Z.add(Y);let V=String(Q.type??"default").toLowerCase(),X=Rj.has(V)?V:"default";J.push({id:Y,text:H,type:X})}return{buttons:J}}function kj($){if($===void 0||$===null)return{};let Z=String($).trim();if(!Z)return{};let J;try{J=new URL(Z)}catch{return{error:`"callback" bad URL: "${Z.slice(0,64)}"`}}if(J.protocol!=="http:")return{error:`"callback" must be http (本机内), got "${J.protocol}"`};let Q=J.hostname.replace(/^\[|]$/g,"");if(Q!=="127.0.0.1"&&Q!=="localhost"&&Q!=="::1")return{error:`"callback" must be loopback (本机内), got "${J.hostname}"`};return{url:Z}}function CH($){try{let Z=Aj((J,Q)=>{let Y=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Q,Y).then((V)=>V?void 0:xH(J,Q)):xH(J,Q)).catch((V)=>{if(G(`notify: handler crash: ${V?.message??V}`),!Q.headersSent)Q.statusCode=500,Q.setHeader("content-type","text/plain; charset=utf-8"),Q.end("internal error");else try{Q.end()}catch{}})});Z.on("error",(J)=>{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 xH($,Z){let J=new URL($.url??"/",`http://${$.headers.host??"localhost"}`),Q=(T,k)=>{Z.statusCode=T,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(k)},Y=(T,k)=>{Z.statusCode=T,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(k))};if($.method==="GET"&&J.pathname==="/")return Q(200,`lodestar notify
207
+ ${J}`;if(!await O(this.chatId,Q))z(`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($.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 YQ($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return s($)}sendOutboundPath($,Z){let J=x9($.trim());if(!J)return;let Q=this.currentTurn;if(Q?.outboundSeenPaths.has(J))return;if(Q?.outboundSeenPaths.add(J),!qB(J)){z(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}Q?.outboundSentPaths.add(J),z(`session "${this.sessionName}": outbound send from ${Z}: ${J}`),c6(this.chatId,J)}startFooterStatus($,Z){if($.rotateGivenUp)return;if($.footerStatusHandle&&$.footerStatusLabel===Z)return;this.stopFooterStatus($),$.footerStatusLabel=Z,$.footerStatusStartedAt=Date.now();let J=()=>{if($.footerStatusLabel!==Z)return;let{label:Y}=M0(Date.now()-$.footerStatusStartedAt,q1());this.replaceFooterContent($.cardId,this.withModel(`${Z} (${Y})`))},Q=()=>{if($.footerStatusLabel!==Z)return;let{nextDelayMs:Y}=M0(Date.now()-$.footerStatusStartedAt,q1());$.footerStatusHandle=setTimeout(()=>{J(),Q()},Math.max(1,Math.ceil(Y)))};J(),Q()}startThinkingFooter($){this.startFooterStatus($,AB)}startWritingFooter($){this.startFooterStatus($,FB)}startWorkingFooter($){this.startFooterStatus($,PB)}stopFooterStatus($){if(!$)return;if($.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null,$.footerStatusStartedAt=0,$.footerStatusLabel=null}async footerUsageSuffix($,Z,J,Q,Y){if(J&&(!Q||!Q.enabled||Q.agent!==$))return"";if(Q?.agent===$&&Q.enabled&&$==="claude"){let X=await Q.readUsage(),V=X.windows.find((G)=>G.kind==="fiveHour"),W=X.windows.find((G)=>G.kind==="weekly");if(V||W)return this.fmtDualWindowSuffix(V??null,W??null);return X.state==="ok"&&X.planLabel?` | ${X.planLabel}`:""}if($==="codex"){let X=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits?Z:null,W=(X?await eJ(()=>X.readRateLimits()):null)??Y;return W?.state==="ok"?this.fmtDualWindowSuffix(W.fiveHour??null,W.weekly??null):""}let H=await g7();return H.state==="ok"?this.fmtDualWindowSuffix(H.fiveHour??null,H.weekly??null):""}fmtDualWindowSuffix($,Z){let J=(X)=>X.resetsAt&&X.resetsAt.getTime()>Date.now()?B0(X.resetsAt):"",Q=(X)=>{if(X?.percent==null)return null;let V=J(X);return V?`${V}·${Math.round(X.percent)}%`:`${Math.round(X.percent)}%`},Y=Q($),H=Q(Z);if(Y&&H)return` | ${Y}·[${H}]`;if(Y)return` | ${Y}`;if(H)return` | [${H}]`;return""}waitForTurnCloses(){let $=[...this.turnCloseInflight];if($.length===0)return Promise.resolve();return Promise.allSettled($).then((Z)=>{let J=Z.filter((Q)=>Q.status==="rejected").map((Q)=>Q.reason);if(J.length===1)throw J[0];if(J.length>1)throw AggregateError(J,`turn close failed: ${J.map(U).join("; ")}`)})}releaseTurnCloseReactions($){for(let[Z,J]of[...$.currentBatchReactionIds.entries(),...$.pendingReactionIds.entries()])if(J)A$(Z,J)}closeTurnCard($,Z={}){let J=this.currentTurn;if(!J)return this.waitForTurnCloses();this.currentTurn=null,this.stopFooterStatus(J);let Q=this.proc,Y={turn:J,proc:Q,procEpoch:this.procEpoch,contextTokens:this.currentContextTokens(Q),contextLimit:this.contextLimitForDisplay(Q),lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,tokenSourceId:this.selectedTokenSourceId,tokenSource:this.currentTokenSource(),codexUsage:sJ(),currentBatchReactionIds:this.currentBatchReactionIds,pendingReactionIds:this.pendingReactionIds};this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map;let H=this.finishTurnCardClose(Y,$,Z).finally(()=>this.releaseTurnCloseReactions(Y));return this.turnCloseInflight.add(H),H.then(()=>{this.turnCloseInflight.delete(H)},()=>{this.turnCloseInflight.delete(H)}),H}async finishTurnCardClose($,Z,J={}){let{turn:Q}=$;if(Q.rotating)await Q.rotating;this.stopFooterStatus(Q);let Y=((Date.now()-Q.startedAt)/1000).toFixed(1),H=Q.cardId,X=Q.segmentTexts;await m$(H);let V=new Map;if(Q.currentAssistantSegmentId&&Q.currentAssistantText.trim()){let{currentAssistantSegmentId:F,currentAssistantText:N}=Q;if(!await this.addCompletedAssistantSegment(Q,F,N))V.set(F,N);Q.currentAssistantSegmentId=null,Q.currentAssistantText=""}let W=Q.assistantWriteInflight?.get(H);if(W?.size)await Promise.allSettled([...W]);let G=Q.mathRenderInflight?.get(H);if(G?.size)await Promise.allSettled([...G]);let K=Q.mathRendered?.get(H);for(let[F,N]of X){if(I1(H,F)){V.set(F,N);continue}if(K?.has(F))continue;await i(H,F,this.completedAssistantElement(F,N))}if(Q.rotateGivenUp)for(let[F,N]of X)V.set(F,N);let _=Z?Z:"✅",B=[`${_} ⏱ ${Y}s`];if(J.hasFreshResult){let{contextTokens:F,contextLimit:N}=$,C=Q.provider==="claude",x=H7(F,N,C?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(Q.contextCompactCount>0)B.push(`\uD83D\uDEA8 压缩×${Q.contextCompactCount}`);if(Q.outboundSentPaths.size>0)B.push(`\uD83D\uDCCE ${Q.outboundSentPaths.size}`);let j=this.modelLine(Q);if(j)B.push(j);let L=B.join(" | "),A=J.hasFreshResult?X7($.lastTurnUsage)+(Q.rotateGivenUp?"":await this.footerUsageSuffix(Q.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage)):"",P=A?`${L}
208
+ ${A}`:L,R=await U$(H,M.footer,this.footerElement(P));V$(H);let D=await q$(H,p$({durationSec:Y,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(R&&D)await S$(H);else{let F=`footer=${R?"ok":"MISS"}, settings=${D?"ok":"MISS"}`;z(`session "${this.sessionName}": terminal card transaction incomplete card=${H.slice(0,12)} ${F}`),await y(this.chatId,`⚠️ 对话卡片终态写入失败 (${F})。本轮已结束: ${_}`)}for(let F of V.values())await this.sendAssistantTextFallback(F,"CardKit 元素未落地");if((J.forcePush||!Z)&&Q.userOpenId&&Q.messageId&&!Q.rotateGivenUp)a0(Q.messageId,[Q.userOpenId])}}});function f$($){return{card:{type:"raw",data:$}}}import{readFileSync as RB}from"node:fs";function RH($){return U3.has($)}function OH($){U3.add($)}function TH($){U3.delete($)}function d2(){try{let $={};for(let[Z,J]of $0)$[Z]=J;X$(r9,$)}catch($){throw z(`notify-callbacks: save failed (${r9}): ${$}`),$}}function EH(){let $;try{$=RB(r9,"utf8")}catch{return}try{let Z=JSON.parse($),J=Date.now()-MH,Q=0;for(let[Y,H]of Object.entries(Z)){if(!H||typeof H!=="object")continue;if(typeof H.notifyId!=="string"||typeof H.callbackUrl!=="string")continue;if(typeof H.createdAt!=="number"||H.createdAt<J){Q++;continue}$0.set(H.notifyId,H)}if(z(`notify-callbacks: loaded ${$0.size} registration(s)${Q?`, dropped ${Q} stale`:""}`),Q>0)d2()}catch(Z){z(`notify-callbacks: load failed (${r9}): ${Z}`)}}function NH($){let Z=Date.now();if(Z-UH>=OB)EB(Z),UH=Z;$0.set($.notifyId,$),d2()}function t9($){return $0.get($)}function M3($,Z,J){let Q=$0.get($);if(!Q)throw Error(`notify registration not found: ${$}`);let Y={resolvedAt:Q.resolvedAt,resolvedBy:Q.resolvedBy,unknownAt:Q.unknownAt,unknownBy:Q.unknownBy,unknownReason:Q.unknownReason};Q.resolvedAt=Date.now(),Q.resolvedBy={buttonId:Z,openId:J},delete Q.unknownAt,delete Q.unknownBy,delete Q.unknownReason;try{d2()}catch(H){if(Y.resolvedAt===void 0)delete Q.resolvedAt;else Q.resolvedAt=Y.resolvedAt;if(Y.resolvedBy===void 0)delete Q.resolvedBy;else Q.resolvedBy=Y.resolvedBy;if(Y.unknownAt===void 0)delete Q.unknownAt;else Q.unknownAt=Y.unknownAt;if(Y.unknownBy===void 0)delete Q.unknownBy;else Q.unknownBy=Y.unknownBy;if(Y.unknownReason===void 0)delete Q.unknownReason;else Q.unknownReason=Y.unknownReason;throw H}}function TB($,Z,J,Q){let Y=$0.get($);if(!Y)throw Error(`notify registration not found: ${$}`);delete Y.resolvedAt,delete Y.resolvedBy,Y.unknownAt=Date.now(),Y.unknownBy={buttonId:Z,openId:J},Y.unknownReason=Q,d2()}function kH($,Z,J){try{return M3($,Z,J),{state:"complete"}}catch(Q){let H=`resolved tombstone persistence failed: ${Q instanceof Error?Q.message:String(Q)}`;try{TB($,Z,J,H)}catch(X){let V=X instanceof Error?X.message:String(X);H+=`; unknown tombstone persistence also failed: ${V}`;let W=$0.get($);if(W)W.unknownReason=H}return{state:"unknown",detail:H}}}function EB($=Date.now()){let Z=$-MH,J=0;for(let[Q,Y]of $0)if(typeof Y.createdAt!=="number"||Y.createdAt<Z)$0.delete(Q),J++;if(J>0)d2();return J}async function xH($,Z,J){let Q={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)},Y=new AbortController,H=setTimeout(()=>Y.abort(),PH);try{let X=await fetch($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q),signal:Y.signal});if(X.status>=200&&X.status<300){let W;try{let G=(await X.text()).trim();if(G.startsWith("{")){let K=JSON.parse(G),_=typeof K?.text==="string"?K.text:typeof K?.reply==="string"?K.reply:typeof K?.message==="string"?K.message:"";if(_.trim())W=_.trim().slice(0,500)}else if(G)W=G.slice(0,500)}catch{}return{ok:!0,detail:`${X.status}`,reply:W}}let V="";try{V=(await X.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${X.status}${V?` ${V}`:""}`}}catch(X){if(X?.name==="AbortError")return{ok:!1,detail:`回调超时 ${PH}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(X?.message??X).slice(0,160)}`}}finally{clearTimeout(H)}}function yH($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Q=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Y=Q?$.buttons.find((H)=>H.id===Q):void 0;return{notify_id:$.notifyId,project:$.project,message_id:$.messageId,resolved:Z,unknown:J,...Z?{button:Y?{id:Y.id,text:Y.text,type:Y.type}:{id:Q},resolved_at:$.resolvedAt,resolved_by:$.resolvedBy?.openId??null}:{},...J?{button:Y?{id:Y.id,text:Y.text,type:Y.type}:{id:Q},unknown_at:$.unknownAt,unknown_by:$.unknownBy?.openId??null,unknown_reason:$.unknownReason}:{}}}var MH=604800000,PH=2500,$0,UH,OB=86400000,U3,r9;var R3=k(()=>{w();D$();h$();$0=new Map,UH=Date.now(),U3=new Set;r9=u3});import{createServer as NB}from"node:http";import{randomUUID as kB}from"node:crypto";function bH($){let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Q=!!($.buttons?.length&&$.notifyId),Y=new Date,H=`${String(Y.getHours()).padStart(2,"0")}:${String(Y.getMinutes()).padStart(2,"0")}`,X=[];for(let V of $.images??[])if(V.key)X.push({tag:"img",img_key:V.key,alt:{tag:"plain_text",content:"screenshot"}});else X.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${V.src}</font>`});if(X.push({tag:"markdown",content:v8($.text??"")||"_(空消息)_"}),$.resolution){let V=$.resolution,W;if(V.status==="processing")W=`<font color='blue'>⏳ 已选择:${V.text} · 推送中…</font>`;else if(V.status==="failed")W=`<font color='red'>⚠️ 已选:${V.text} · 回调失败:${V.detail??"未知"} · ${H}</font>`;else if(V.status==="delivered")W=`<font color='green'>✅ 已选择:${V.text} · 反馈已送达 · ${H}</font>`;else if(V.status==="unknown")W=`<font color='red'>⚠️ 已选择:${V.text} · 外部回调已成功,但本地确认状态未知,禁止自动重试 · ${H}</font>`;else W=`<font color='green'>✅ 已选择:${V.text} · ${H}</font>`;if(X.push({tag:"markdown",content:W}),V.status==="delivered"&&V.reply)X.push({tag:"markdown",content:s(V.reply)})}if(Q&&(!$.resolution||$.resolution.status==="failed"))X.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}}]}))}]});return X.push({tag:"hr"}),X.push({tag:"markdown",content:`<font color='grey'>via notify · ${H}</font>`}),{schema:"2.0",config:Q?{update_multi:!0}:{},header:{title:{tag:"plain_text",content:`${J} ${$.title}`},template:Z},body:{elements:X}}}function SB($){if($===void 0||$===null)return{buttons:[]};if(!Array.isArray($))return{error:'"buttons" must be an array'};if($.length===0)return{buttons:[]};let Z=new Set,J=[];for(let Q of $){if(!Q||typeof Q!=="object")return{error:"each button must be an object"};let Y=String(Q.id??"").trim(),H=String(Q.text??"").trim();if(!CB.test(Y))return{error:`button id "${Y.slice(0,32)}" invalid (need ^[A-Za-z0-9_-]{1,64}$)`};if(!H)return{error:`button "${Y}" missing text`};if(H.length>CH)return{error:`button "${Y}" text > ${CH} chars`};if(Z.has(Y))return{error:`button id "${Y}" duplicated`};Z.add(Y);let X=String(Q.type??"default").toLowerCase(),V=yB.has(X)?X:"default";J.push({id:Y,text:H,type:V})}return{buttons:J}}function bB($){if($===void 0||$===null)return{};let Z=String($).trim();if(!Z)return{};let J;try{J=new URL(Z)}catch{return{error:`"callback" bad URL: "${Z.slice(0,64)}"`}}if(J.protocol!=="http:")return{error:`"callback" must be http (本机内), got "${J.protocol}"`};let Q=J.hostname.replace(/^\[|]$/g,"");if(Q!=="127.0.0.1"&&Q!=="localhost"&&Q!=="::1")return{error:`"callback" must be loopback (本机内), got "${J.hostname}"`};return{url:Z}}function wH($){try{let Z=NB((J,Q)=>{let Y=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Q,Y).then((X)=>X?void 0:SH(J,Q)):SH(J,Q)).catch((X)=>{if(z(`notify: handler crash: ${X?.message??X}`),!Q.headersSent)Q.statusCode=500,Q.setHeader("content-type","text/plain; charset=utf-8"),Q.end("internal error");else try{Q.end()}catch{}})});Z.on("error",(J)=>{z(`notify: server bind failed (${$.bind}:${$.port}): ${J.message}`)}),Z.listen($.port,$.bind,()=>{z(`notify: HTTP listening at http://${$.bind}:${$.port}/notify`)})}catch(Z){z(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function SH($,Z){let J=new URL($.url??"/",`http://${$.headers.host??"localhost"}`),Q=(T,E)=>{Z.statusCode=T,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(E)},Y=(T,E)=>{Z.statusCode=T,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(E))};if($.method==="GET"&&J.pathname==="/")return Q(200,`lodestar notify
207
209
  `+`POST /notify body={project,text,title?,level?,images?,buttons?,callback?} → push card to group
208
210
  `+`GET /notify/result/<notify_id> → poll a button card's resolution (pull mode, no callback server)
209
211
  `+`GET /consult/identities; POST/GET/DELETE /consult/runs[/<id>] → capability-protected model consultation
210
212
  `+`levels: info|warn|error (default info); images=[/abs/*.png] uploaded + embedded
211
213
  `+`buttons:[{id,text,type?}] (any count, one per row); callback=http://127.0.0.1:PORT/path optional (push) — omit to poll
212
- `);if($.method==="GET"&&J.pathname.startsWith("/notify/result/")){let T=decodeURIComponent(J.pathname.slice(15)).trim();if(!T)return Q(400,"missing notify_id in path");let k=r9(T);if(!k)return Y(404,{error:"unknown notify_id",notify_id:T});return Y(200,yH(k))}if($.method!=="POST"||J.pathname!=="/notify")return Q(405,"use POST /notify");let H="";for await(let T of $)H+=T.toString();let V={};try{V=JSON.parse(H)}catch{return Q(400,"bad json")}let X=String(V.project??"").trim(),W=String(V.text??""),z=String(V.title??"").trim(),K=String(V.level??"info").toLowerCase();if(!X)return Q(400,'missing "project"');if(!W)return Q(400,'missing "text"');let{buttons:_,error:j}=Tj(V.buttons);if(j)return Q(400,j);let{url:B,error:L}=kj(V.callback);if(L)return Q(400,L);let P=!!(_&&_.length),A=B??"",R=Mj.has(K)?K:"info",D=z||X,F=y2(X),y=h1(F);if(!y)return G(`notify: project "${X}" (sanitized "${F}") has no chat binding → 404`),Q(404,`project "${X}" not bound — send any message in that Feishu group at least once after the daemon started, then retry`);let C=Array.isArray(V.images)?V.images:[],x=[];for(let T of C){let k=String(T??"").trim();if(!k)continue;let u=await g8(k);x.push({key:u??"",src:k})}let m=P?`nf_${Uj()}`:"",g=NH({title:D,text:W,level:R,images:x,buttons:_,notifyId:m}),f=await c(y,g);if(!f)return G(`notify: sendCard failed → 502 (project="${X}" chat=${y.slice(0,8)}…)`),Q(502,"feishu sendCard failed (see daemon log)");if(P&&m){let T={notifyId:m,callbackUrl:A,chatId:y,messageId:f,project:X,title:D,text:W,level:R,imageKeys:x,buttons:_,createdAt:Date.now()};OH(T)}G(`notify: → ${X} (${y.slice(0,8)}…) level=${R} bytes=${W.length} images=${x.length} buttons=${_?.length??0} push=${P&&!!A?1:0} msg=${f}`),Y(200,{ok:!0,chat_id:y,message_id:f,...m?{notify_id:m}:{}})}function t9($,Z){return NH({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,notifyId:$.notifyId,resolution:Z})}var Mj,Rj,Oj,EH=64;var R5=E(()=>{w();n();x$();M5();Mj=new Set(["info","warn","error"]),Rj=new Set(["default","primary","danger"]),Oj=/^[A-Za-z0-9_-]{1,64}$/});import{existsSync as SH,readFileSync as wH}from"node:fs";import{homedir as bH}from"node:os";import{join as d2}from"node:path";function s9($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){G(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[d2(bH(),".codex","skills"),d2(bH(),".claude","skills")];for(let Q of J){let Y=d2(Q,$.name,"SKILL.md");try{let H=SH(Y)?wH(Y,"utf8"):null;if(H===$.body)continue;J0(Y,$.body),G(`skill: ${H===null?"installed":"updated"} ${Y}`)}catch(H){G(`skill: sync failed (${Y}): ${H}`)}}if(!Z)yj($,e2)}function yj($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){G(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=d2(Z,".claude-plugin","plugin.json"),Q=d2(Z,"skills",$.name,"SKILL.md"),Y=JSON.stringify({name:"lodestar-managed",description:"Lodestar daemon-managed Skills for Claude Agent SDK sessions",version:"1.0.0",author:{name:"Lodestar"}},null,2)+`
213
- `;for(let[H,V]of[[J,Y],[Q,$.body]])try{let X=SH(H)?wH(H,"utf8"):null;if(X===V)continue;J0(H,V),G(`skill: ${X===null?"installed":"updated"} ${H}`)}catch(X){G(`skill: Claude plugin sync failed (${H}): ${X}`)}}var O5=E(()=>{w();h$();D$()});function Ej($){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`---
214
- name: ${fH}
214
+ `);if($.method==="GET"&&J.pathname.startsWith("/notify/result/")){let T=decodeURIComponent(J.pathname.slice(15)).trim();if(!T)return Q(400,"missing notify_id in path");let E=t9(T);if(!E)return Y(404,{error:"unknown notify_id",notify_id:T});return Y(200,yH(E))}if($.method!=="POST"||J.pathname!=="/notify")return Q(405,"use POST /notify");let H="";for await(let T of $)H+=T.toString();let X={};try{X=JSON.parse(H)}catch{return Q(400,"bad json")}let V=String(X.project??"").trim(),W=String(X.text??""),G=String(X.title??"").trim(),K=String(X.level??"info").toLowerCase();if(!V)return Q(400,'missing "project"');if(!W)return Q(400,'missing "text"');let{buttons:_,error:B}=SB(X.buttons);if(B)return Q(400,B);let{url:j,error:L}=bB(X.callback);if(L)return Q(400,L);let A=!!(_&&_.length),P=j??"",R=xB.has(K)?K:"info",D=G||V,F=N2(V),N=h1(F);if(!N)return z(`notify: project "${V}" (sanitized "${F}") has no chat binding → 404`),Q(404,`project "${V}" not bound — send any message in that Feishu group at least once after the daemon started, then retry`);let C=Array.isArray(X.images)?X.images:[],x=[];for(let T of C){let E=String(T??"").trim();if(!E)continue;let u=await g6(E);x.push({key:u??"",src:E})}let m=A?`nf_${kB()}`:"",I=bH({title:D,text:W,level:R,images:x,buttons:_,notifyId:m}),f=await c(N,I);if(!f)return z(`notify: sendCard failed → 502 (project="${V}" chat=${N.slice(0,8)}…)`),Q(502,"feishu sendCard failed (see daemon log)");if(A&&m){let T={notifyId:m,callbackUrl:P,chatId:N,messageId:f,project:V,title:D,text:W,level:R,imageKeys:x,buttons:_,createdAt:Date.now()};NH(T)}z(`notify: → ${V} (${N.slice(0,8)}…) level=${R} bytes=${W.length} images=${x.length} buttons=${_?.length??0} push=${A&&!!P?1:0} msg=${f}`),Y(200,{ok:!0,chat_id:N,message_id:f,...m?{notify_id:m}:{}})}function s9($,Z){return bH({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,notifyId:$.notifyId,resolution:Z})}var xB,yB,CB,CH=64;var O3=k(()=>{w();n();x$();R3();xB=new Set(["info","warn","error"]),yB=new Set(["default","primary","danger"]),CB=/^[A-Za-z0-9_-]{1,64}$/});import{existsSync as vH,readFileSync as hH}from"node:fs";import{homedir as fH}from"node:os";import{join as i2}from"node:path";function e9($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){z(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[i2(fH(),".codex","skills"),i2(fH(),".claude","skills")];for(let Q of J){let Y=i2(Q,$.name,"SKILL.md");try{let H=vH(Y)?hH(Y,"utf8"):null;if(H===$.body)continue;J0(Y,$.body),z(`skill: ${H===null?"installed":"updated"} ${Y}`)}catch(H){z(`skill: sync failed (${Y}): ${H}`)}}if(!Z)wB($,e2)}function wB($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){z(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=i2(Z,".claude-plugin","plugin.json"),Q=i2(Z,"skills",$.name,"SKILL.md"),Y=JSON.stringify({name:"lodestar-managed",description:"Lodestar daemon-managed Skills for Claude Agent SDK sessions",version:"1.0.0",author:{name:"Lodestar"}},null,2)+`
215
+ `;for(let[H,X]of[[J,Y],[Q,$.body]])try{let V=vH(H)?hH(H,"utf8"):null;if(V===X)continue;J0(H,X),z(`skill: ${V===null?"installed":"updated"} ${H}`)}catch(V){z(`skill: Claude plugin sync failed (${H}): ${V}`)}}var T3=k(()=>{w();h$();D$()});function fB($){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`---
216
+ name: ${IH}
215
217
  description: ${JSON.stringify(Z)}
216
218
  ---
217
219
 
@@ -379,8 +381,8 @@ Notes:
379
381
  Hand-edits will be overwritten — set
380
382
  \`LODESTAR_DISABLE_SKILL_SYNC=1\` and restart the daemon if you want
381
383
  to maintain the file yourself.
382
- `}function vH(){s9({name:fH,body:Ej(S.notify.port)})}var fH="feishu-notify";var hH=E(()=>{y$();O5()});function mH($){let Z=Z$($.identity.tokenSourceId);if(!Z)throw Error(`consult token source not found: ${$.identity.tokenSourceId}`);if(!Z.enabled)throw Error(`consult token source disabled: ${Z.id}`);if($.identity.status!=="ready")throw Error($.identity.reason??`consult identity is ${$.identity.status}`);if($.identity.spawnRevision&&Z.spawnRevision!==$.identity.spawnRevision)throw Error(`consult token source changed after identity discovery: ${Z.id}`);let J=Z.models.find((V)=>V.model===$.identity.model);if(!J)throw Error(`consult model disappeared after identity discovery: ${Z.id}/${$.identity.model}`);if(!J.efforts.includes($.identity.effort))throw Error(`consult effort is no longer supported: ${Z.id}/${$.identity.model}/${$.identity.effort}`);let Q=Z.resolveSpawnModel($.identity.model);if(!Q)throw Error(`consult model did not resolve: ${Z.id}/${$.identity.model}`);let Y=(V)=>Nj(Z.spawnEnv(V)),H=Cj($.identity,$.workDir,Q,Y);return wj(H,$.prompt)}function Nj($){let Z={...$};for(let J of xj)delete Z[J];return Z}function Cj($,Z,J,Q){let Y=["你是 Lodestar 启动的一次性独立顾问。","只读取当前项目并分析;允许自由联网检索和访问外部资料。","不得读取项目外文件、修改文件、执行有副作用的命令、向外部系统发送消息或调用 lodestar-consult。","不要询问用户;证据不足时明确写出 MISS/待确认。"].join(`
383
- `);if($.provider==="codex"){if(!E$($.effort))throw Error(`invalid Codex consult effort: ${$.effort}`);return new I0({workDir:Z,model:J,effort:$.effort,appendSystemPrompt:Y,sandbox:"read-only",networkAccess:!0,ephemeral:!0,configOverrides:bj(),disabledFeatures:["apps","plugins","multi_agent"],tokenSourceId:$.tokenSourceId,transformEnv:Q})}if(!o$($.effort))throw Error(`invalid Claude consult effort: ${$.effort}`);return new D2({workDir:Z,model:J,effort:$.effort,systemPrompt:Y,safeMode:!0,readOnlyRoots:[Z],readOnlyExtraTools:["WebSearch","WebFetch"],profile:{tools:"Read,Grep,Glob,WebSearch,WebFetch",strictMcp:!0,loadProjectMcp:!1},settingSources:Sj($.tokenSourceId),tokenSourceId:$.tokenSourceId,transformEnv:Q})}function bj($=process.platform){return["mcp_servers={}","hooks={}",'web_search="live"',...$==="linux"?["features.use_legacy_landlock=true"]:[],'shell_environment_policy.include_only=["PATH","HOME","USER","LOGNAME","TMPDIR","TEMP","TMP","SHELL","COMSPEC","SYSTEMROOT","WINDIR","PATHEXT"]',"shell_environment_policy.ignore_default_excludes=false"]}function Sj($){return Z$($)?.settingSources??[]}function wj($,Z){let J="",Q=null,Y=!1,H,V,X=Date.now(),W=new Promise((D,F)=>{H=D,V=F}),z=()=>{$.off("assistant_text",_),$.off("can_use_tool",j),$.off("hook_callback",B),$.off("error",L),$.off("result",P),$.off("exit",A)},K=async(D)=>{if(Y)return;Y=!0,clearTimeout(R),z();let F=null;try{await $.kill(3000)}catch(x){F=x instanceof Error?x:Error(String(x))}let y=D??F;if(y){V(y);return}let C=J.trim();if(!C){V(Error("consult reviewer completed without assistant output"));return}H({output:C,durationMs:Date.now()-X,usage:$.lastUsage?{...$.lastUsage}:null})},_=(D)=>{if(typeof D?.text!=="string")return;if(J+=D.text,J.length>IH)K(Error(`consult reviewer output exceeds ${IH} chars`))},j=(D)=>{$.sendPermissionResponse(D.request_id,"deny",{denyMessage:"一次性顾问不接受交互或副作用工具"})},B=(D)=>$.sendHookResponse(String(D.request_id),{}),L=(D)=>{Q=D instanceof Error?D:Error(String(D))},P=(D)=>{let F=D?.is_error?Error(String(D.error??D.subtype??$.lastResult.subtype??"consult reviewer failed")):void 0;K(F)},A=(D)=>{if(Y)return;let F=`code=${D?.code??"null"} signal=${D?.signal??"null"}`;K(Q??Error(`consult reviewer exited before result (${F})`))},R=setTimeout(()=>{K(Error(`consult reviewer timed out after ${gH/1000}s`))},gH);$.on("assistant_text",_),$.on("can_use_tool",j),$.on("hook_callback",B),$.on("error",L),$.on("result",P),$.on("exit",A);try{$.sendInitialize(),$.sendUserText(Z)}catch(D){K(D instanceof Error?D:Error(String(D)))}return{done:W,async cancel(D="consult cancelled"){await K(Error(D)),await W.catch(()=>{})}}}function uH($){let Z=$.kind==="question"?"回答咨询问题":$.kind==="critique"?"批判性复核给定结论":"执行独立评审",J=[`身份: ${$.identity.displayName}`,`角色约束: ${$.identity.instructions??""}`,`角色重点: ${$.identity.role}`,`任务: ${Z}`,$.question?`问题:
384
+ `}function gH(){e9({name:IH,body:fB(b.notify.port)})}var IH="feishu-notify";var cH=k(()=>{N$();T3()});function lH($){let Z=Z$($.identity.tokenSourceId);if(!Z)throw Error(`consult token source not found: ${$.identity.tokenSourceId}`);if(!Z.enabled)throw Error(`consult token source disabled: ${Z.id}`);if($.identity.status!=="ready")throw Error($.identity.reason??`consult identity is ${$.identity.status}`);if($.identity.spawnRevision&&Z.spawnRevision!==$.identity.spawnRevision)throw Error(`consult token source changed after identity discovery: ${Z.id}`);let J=Z.models.find((X)=>X.model===$.identity.model);if(!J)throw Error(`consult model disappeared after identity discovery: ${Z.id}/${$.identity.model}`);if(!J.efforts.includes($.identity.effort))throw Error(`consult effort is no longer supported: ${Z.id}/${$.identity.model}/${$.identity.effort}`);let Q=Z.resolveSpawnModel($.identity.model);if(!Q)throw Error(`consult model did not resolve: ${Z.id}/${$.identity.model}`);let Y=(X)=>hB(Z.spawnEnv(X)),H=IB($.identity,$.workDir,Q,Y);return mB(H,$.prompt)}function hB($){let Z={...$};for(let J of vB)delete Z[J];return Z}function IB($,Z,J,Q){let Y=["你是 Lodestar 启动的一次性独立顾问。","只读取当前项目并分析;允许自由联网检索和访问外部资料。","不得读取项目外文件、修改文件、执行有副作用的命令、向外部系统发送消息或调用 lodestar-consult。","不要询问用户;证据不足时明确写出 MISS/待确认。"].join(`
385
+ `);if($.provider==="codex"){if(!k$($.effort))throw Error(`invalid Codex consult effort: ${$.effort}`);return new I0({workDir:Z,model:J,effort:$.effort,appendSystemPrompt:Y,sandbox:"read-only",networkAccess:!0,ephemeral:!0,configOverrides:gB(),disabledFeatures:["apps","plugins","multi_agent"],tokenSourceId:$.tokenSourceId,transformEnv:Q})}if(!o$($.effort))throw Error(`invalid Claude consult effort: ${$.effort}`);return new D2({workDir:Z,model:J,effort:$.effort,systemPrompt:Y,safeMode:!0,readOnlyRoots:[Z],readOnlyExtraTools:["WebSearch","WebFetch"],profile:{tools:"Read,Grep,Glob,WebSearch,WebFetch",strictMcp:!0,loadProjectMcp:!1},settingSources:cB($.tokenSourceId),tokenSourceId:$.tokenSourceId,transformEnv:Q})}function gB($=process.platform){return["mcp_servers={}","hooks={}",'web_search="live"',...$==="linux"?["features.use_legacy_landlock=true"]:[],'shell_environment_policy.include_only=["PATH","HOME","USER","LOGNAME","TMPDIR","TEMP","TMP","SHELL","COMSPEC","SYSTEMROOT","WINDIR","PATHEXT"]',"shell_environment_policy.ignore_default_excludes=false"]}function cB($){return Z$($)?.settingSources??[]}function mB($,Z){let J="",Q=null,Y=!1,H,X,V=Date.now(),W=new Promise((D,F)=>{H=D,X=F}),G=()=>{$.off("assistant_text",_),$.off("can_use_tool",B),$.off("hook_callback",j),$.off("error",L),$.off("result",A),$.off("exit",P)},K=async(D)=>{if(Y)return;Y=!0,clearTimeout(R),G();let F=null;try{await $.kill(3000)}catch(x){F=x instanceof Error?x:Error(String(x))}let N=D??F;if(N){X(N);return}let C=J.trim();if(!C){X(Error("consult reviewer completed without assistant output"));return}H({output:C,durationMs:Date.now()-V,usage:$.lastUsage?{...$.lastUsage}:null})},_=(D)=>{if(typeof D?.text!=="string")return;if(J+=D.text,J.length>uH)K(Error(`consult reviewer output exceeds ${uH} chars`))},B=(D)=>{$.sendPermissionResponse(D.request_id,"deny",{denyMessage:"一次性顾问不接受交互或副作用工具"})},j=(D)=>$.sendHookResponse(String(D.request_id),{}),L=(D)=>{Q=D instanceof Error?D:Error(String(D))},A=(D)=>{let F=D?.is_error?Error(String(D.error??D.subtype??$.lastResult.subtype??"consult reviewer failed")):void 0;K(F)},P=(D)=>{if(Y)return;let F=`code=${D?.code??"null"} signal=${D?.signal??"null"}`;K(Q??Error(`consult reviewer exited before result (${F})`))},R=setTimeout(()=>{K(Error(`consult reviewer timed out after ${mH/1000}s`))},mH);$.on("assistant_text",_),$.on("can_use_tool",B),$.on("hook_callback",j),$.on("error",L),$.on("result",A),$.on("exit",P);try{$.sendInitialize(),$.sendUserText(Z)}catch(D){K(D instanceof Error?D:Error(String(D)))}return{done:W,async cancel(D="consult cancelled"){await K(Error(D)),await W.catch(()=>{})}}}function dH($){let Z=$.kind==="question"?"回答咨询问题":$.kind==="critique"?"批判性复核给定结论":"执行独立评审",J=[`身份: ${$.identity.displayName}`,`角色约束: ${$.identity.instructions??""}`,`角色重点: ${$.identity.role}`,`任务: ${Z}`,$.question?`问题:
384
386
  ${$.question}`:"",$.instructions?`额外要求:
385
387
  ${$.instructions}`:"",`目标上下文:
386
388
  ${$.targetContext}`];if($.peerOutputs?.length)J.push(["其他顾问首轮结果(仅供交叉复核):",...$.peerOutputs.map((Y,H)=>`
@@ -390,29 +392,29 @@ ${Y.output}`),`
390
392
  `));J.push(["输出要求:","- 用 Markdown,先给结论。","- review/critique 需按 blocker/high/medium/low 列出 findings,包含位置、证据和建议。","- 没有发现时明确写“未发现具体问题”,不得伪造证据。","- 不修改任何文件。"].join(`
391
393
  `));let Q=J.filter(Boolean).join(`
392
394
 
393
- `);if(Q.length>cH)throw Error(`consult reviewer prompt exceeds ${cH} chars`);return Q}var gH=1800000,IH=200000,cH=800000,xj;var pH=E(()=>{c0();O4();k1();A$();xj=["LODESTAR_CONSULT_URL","LODESTAR_CONSULT_CAPABILITY","LODESTAR_CONSULT_SESSION"]});import{createHash as fj}from"node:crypto";import{execFile as vj}from"node:child_process";import{existsSync as hj,statSync as gj}from"node:fs";import{isAbsolute as Ij}from"node:path";import{promisify as cj}from"node:util";async function dH($,Z){if(!Ij($))throw Error(`consult cwd is not absolute: ${$}`);if(!hj($)||!gj($).isDirectory())throw Error(`consult cwd is not a directory: ${$}`);let J;switch(Z.type){case"working_directory":{let Q=await lj($);J=[`工作目录: ${$}`,Q.snapshot?`Git 快照:
395
+ `);if(Q.length>pH)throw Error(`consult reviewer prompt exceeds ${pH} chars`);return Q}var mH=1800000,uH=200000,pH=800000,vB;var iH=k(()=>{c0();O4();E1();P$();vB=["LODESTAR_CONSULT_URL","LODESTAR_CONSULT_CAPABILITY","LODESTAR_CONSULT_SESSION"]});import{createHash as uB}from"node:crypto";import{execFile as pB}from"node:child_process";import{existsSync as lB,statSync as dB}from"node:fs";import{isAbsolute as iB}from"node:path";import{promisify as nB}from"node:util";async function aH($,Z){if(!iB($))throw Error(`consult cwd is not absolute: ${$}`);if(!lB($)||!dB($).isDirectory())throw Error(`consult cwd is not a directory: ${$}`);let J;switch(Z.type){case"working_directory":{let Q=await tB($);J=[`工作目录: ${$}`,Q.snapshot?`Git 快照:
394
396
  ${Q.snapshot}`:`Git 快照 MISS: ${Q.error}`,"按需读取项目文件,不得修改。"].join(`
395
397
 
396
398
  `);break}case"uncommitted_changes":{let Q=await Z0($,["status","--short","--untracked-files=all"]),Y=await Z0($,["diff","--no-ext-diff","HEAD","--"]);J=[`工作目录: ${$}`,"评审目标: 当前未提交变更。",`git status --short:
397
399
  ${Q||"(clean)"}`,`git diff HEAD --:
398
400
  ${Y||"(empty diff)"}`,"未跟踪文件不会出现在 diff 正文中;如需证据,根据 status 列表以只读方式检查。"].join(`
399
401
 
400
- `);break}case"commit":{iH(Z.sha);let Q=(await Z0($,["rev-parse","--verify",`${Z.sha}^{commit}`])).trim(),Y=await Z0($,["show","--no-ext-diff","--format=fuller","--stat","--patch",Q,"--"]);J=`工作目录: ${$}
402
+ `);break}case"commit":{oH(Z.sha);let Q=(await Z0($,["rev-parse","--verify",`${Z.sha}^{commit}`])).trim(),Y=await Z0($,["show","--no-ext-diff","--format=fuller","--stat","--patch",Q,"--"]);J=`工作目录: ${$}
401
403
 
402
404
  评审 commit: ${Q}
403
405
 
404
- ${Y}`;break}case"base_branch":{iH(Z.branch);let Q=(await Z0($,["rev-parse","--verify",`${Z.branch}^{commit}`])).trim(),Y=(await Z0($,["rev-parse","--verify","HEAD^{commit}"])).trim(),H=await Z0($,["diff","--no-ext-diff","--stat","--patch",`${Q}...${Y}`,"--"]);J=`工作目录: ${$}
406
+ ${Y}`;break}case"base_branch":{oH(Z.branch);let Q=(await Z0($,["rev-parse","--verify",`${Z.branch}^{commit}`])).trim(),Y=(await Z0($,["rev-parse","--verify","HEAD^{commit}"])).trim(),H=await Z0($,["diff","--no-ext-diff","--stat","--patch",`${Q}...${Y}`,"--"]);J=`工作目录: ${$}
405
407
 
406
408
  评审范围: ${Z.branch}(${Q})...HEAD(${Y})
407
409
 
408
410
  ${H}`;break}case"proposal":J=`项目工作目录: ${$}
409
411
 
410
412
  待评审文本:
411
- ${Z.text}`;break}if(J.length>lH)throw Error(`consult target context is too large (${J.length}/${lH} chars)`);return{target:Z,promptContext:J,fingerprint:fj("sha256").update(J).digest("hex")}}async function lj($){try{let Z=(await Z0($,["rev-parse","--show-toplevel"])).trim(),J=(await Z0($,["rev-parse","--verify","HEAD^{commit}"])).trim(),Q=await Z0($,["status","--short","--untracked-files=all"]);return{snapshot:[`root=${Z}`,`HEAD=${J}`,Q||"clean"].join(`
412
- `),error:null}}catch(Z){return{snapshot:null,error:Z instanceof Error?Z.message:String(Z)}}}function iH($){if(!$||$.startsWith("-")||/[\u0000-\u001f\u007f\s]/.test($))throw Error(`invalid git ref: ${JSON.stringify($)}`)}async function Z0($,Z){try{let{stdout:J}=await pj("git",Z,{cwd:$,encoding:"utf8",maxBuffer:mj,timeout:uj,killSignal:"SIGKILL"});return String(J)}catch(J){let Q=J,Y=Buffer.isBuffer(Q.stderr)?Q.stderr.toString("utf8"):String(Q.stderr??""),H=Buffer.isBuffer(Q.stdout)?Q.stdout.toString("utf8"):String(Q.stdout??"");throw Error([`git ${Z.join(" ")} failed`,Q.message,H.trim(),Y.trim()].filter(Boolean).join(": "))}}var lH=500000,mj=8388608,uj=1e4,pj;var nH=E(()=>{pj=cj(vj)});import{randomUUID as ij}from"node:crypto";import{join as T5}from"node:path";class k5{deps;runs=new Map;startingRunsByChat=new Map;constructor($=nj){this.deps=$}async startRun($,Z){this.pruneRuns();let J=`consult_${ij()}`,Q=this.startingRunsByChat.get($.chatId),Y=[...this.runs.values()].find((H)=>H.chatId===$.chatId&&!H.finalized);if(Q||Y)throw Error(`consult run already active: ${Q??Y.snapshot.runId}; batch all identities into one run with repeated --identity flags`);this.startingRunsByChat.set($.chatId,J);try{let H=this.deps.getCatalog(),V=Z.identityIds.map((B)=>{let L=H.identities.find((P)=>P.id===B);if(!L)throw Error(`consult identity not found: ${B}`);if(L.status!=="ready")throw Error(`${L.displayName}: ${L.reason??L.status}`);return L}),X=Z.target??{type:"working_directory"},W=await this.deps.buildTargetContext($.workDir,X),z={runId:J,sessionName:$.sessionName,kind:Z.kind,target:X,question:Z.question??"",instructions:Z.instructions??"",crossReview:Z.crossReview===!0,status:"running",targetFingerprint:W.fingerprint,reviewers:V.map((B)=>oj(B)),createdAt:new Date().toISOString()},K=await this.deps.sendCard($.chatId,N7(z));if(!K)throw Error("consult card creation failed; reviewers were not started");let _;try{_=await this.deps.convertMessageToCard(K)}catch(B){throw await this.deps.sendTextRaw($.chatId,`❌ consult 卡片初始化失败,reviewer 未启动: ${T$(B)}`),B}z.cardMessageId=K,this.deps.recordCardCreated(_,z.reviewers.length+2,(B)=>{G(`consult: card write failed run=${J} code=${B??"MISS"}`)});let j={snapshot:z,targetContext:W,identities:V,workDir:$.workDir,chatId:$.chatId,cardId:_,workers:new Map,cancelled:!1,terminalized:!1,finalized:!1,presentationErrors:[]};return this.runs.set(J,j),this.executeRun(j).catch(async(B)=>{G(`consult: run=${J} crashed: ${T$(B)}`),await this.finishRun(j,"failed",T$(B))}),oH(z)}finally{if(this.startingRunsByChat.get($.chatId)===J)this.startingRunsByChat.delete($.chatId)}}getRun($){this.pruneRuns();let Z=this.runs.get($);if(!Z)return null;let J=oH(Z.snapshot);if(Z.terminalized&&!Z.finalized)J.status="running",delete J.finishedAt;return J}ownsRun($,Z){let J=this.runs.get($);return!!J&&J.snapshot.sessionName===Z.sessionName&&J.chatId===Z.chatId}async cancelRun($,Z="consult cancelled"){let J=this.runs.get($);if(!J||J.snapshot.status!=="running"||J.terminalized)return!1;J.cancelled=!0;let Q=[...J.workers.values()];await Promise.allSettled(Q.map((Y)=>Y.cancel(Z)));for(let Y of J.snapshot.reviewers)if(Y.status==="queued"||Y.status==="running")Y.status="cancelled",Y.error=Z,Y.finishedAt=new Date().toISOString();return await this.finishRun(J,"cancelled",Z),!0}async cancelSessionRuns($,Z,J){let Q=[...this.runs.values()].filter((Y)=>Y.snapshot.sessionName===$&&Y.chatId===Z&&Y.snapshot.status==="running"&&!Y.terminalized);await Promise.allSettled(Q.map((Y)=>this.cancelRun(Y.snapshot.runId,J)))}pruneRuns(){if(this.runs.size<=256)return;let $=[...this.runs.values()].filter((Z)=>Z.finalized).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<=256)break;this.runs.delete(Z.snapshot.runId)}}async executeRun($){if(await this.executeRound($,!1),$.cancelled||$.snapshot.status!=="running")return;if($.snapshot.reviewers.some((Q)=>Q.status!=="completed")){await this.finishRun($,"failed","一个或多个选定顾问失败,未进入后续复核");return}if($.snapshot.crossReview&&$.snapshot.reviewers.length>1){for(let Q of $.snapshot.reviewers)Q.firstPassOutput=Q.output,Q.output="",Q.status="queued",Q.error=void 0,Q.startedAt=void 0,Q.finishedAt=void 0,Q.durationMs=void 0;if(await Promise.all($.snapshot.reviewers.map((Q)=>this.updateReviewerCard($,Q))),await this.executeRound($,!0),$.cancelled||$.snapshot.status!=="running")return;if($.snapshot.reviewers.some((Q)=>Q.status!=="completed")){await this.finishRun($,"failed","交叉复核未全部完成");return}}if((await this.deps.buildTargetContext($.workDir,$.snapshot.target)).fingerprint!==$.snapshot.targetFingerprint){await this.finishRun($,"failed","评审期间目标已变化,结果已标记为过期");return}await this.finishRun($,"completed")}async executeRound($,Z){let J=$.snapshot.reviewers.map((Q)=>({identityId:Q.identityId,name:Q.identityName,output:Q.firstPassOutput??Q.output}));await aj($.identities,dj,async(Q)=>{let Y=$.snapshot.reviewers.find((V)=>V.identityId===Q.id);if($.cancelled)return;let H;try{let V=uH({identity:Q,kind:$.snapshot.kind,question:$.snapshot.question,instructions:$.snapshot.instructions,targetContext:$.targetContext.promptContext,...Z?{peerOutputs:J.filter((X)=>X.identityId!==Q.id).map((X)=>({name:X.name,output:X.output}))}:{}});H=this.deps.startWorker({identity:Q,workDir:$.workDir,prompt:V})}catch(V){await this.failReviewer($,Y,T$(V));return}if($.workers.set(Q.id,H),$.cancelled){await H.cancel("consult cancelled before reviewer start"),$.workers.delete(Q.id);return}Y.status="running",Y.startedAt=new Date().toISOString(),await this.updateReviewerCard($,Y);try{let V=await H.done;if($.cancelled)return;Y.status="completed",Y.output=V.output,Y.durationMs=V.durationMs,Y.usage=V.usage,Y.finishedAt=new Date().toISOString(),await this.updateReviewerCard($,Y)}catch(V){if($.cancelled)return;await this.failReviewer($,Y,T$(V))}finally{$.workers.delete(Q.id)}})}async failReviewer($,Z,J){if(Z.status="failed",Z.error=J,Z.finishedAt=new Date().toISOString(),Z.startedAt)Z.durationMs=Date.now()-Date.parse(Z.startedAt);await this.updateReviewerCard($,Z)}async updateReviewerCard($,Z){try{if(!await this.deps.replaceElementChecked($.cardId,P9(Z.identityId),L9(Z)))this.recordPresentationError($,`reviewer card MISS: ${Z.identityName}`)}catch(J){this.recordPresentationError($,`reviewer card update failed (${Z.identityName}): ${T$(J)}`)}try{this.deps.patchSummaryThrottled($.cardId,F9($.snapshot))}catch(J){this.recordPresentationError($,`reviewer summary update failed: ${T$(J)}`)}}async finishRun($,Z,J){if($.terminalized)return;$.terminalized=!0;try{if($.snapshot.status=Z,$.snapshot.finishedAt=new Date().toISOString(),J)f0($.snapshot,J);if($.presentationErrors.length)for(let Y of $.presentationErrors)f0($.snapshot,Y);try{this.deps.writeArtifact(T5(s2,`${$.snapshot.runId}.json`),$.snapshot)}catch(Y){let H=T$(Y);$.snapshot.status="failed",f0($.snapshot,`artifact persistence failed: ${H}`),G(`consult: run artifact persistence failed run=${$.snapshot.runId}: ${H}`)}let Q=!1;try{await this.deps.flush($.cardId);let Y=await this.deps.replaceElementChecked($.cardId,M.consultRunFooter,D9($.snapshot));this.deps.cancelSummary($.cardId);let H=await this.deps.patchSettingsChecked($.cardId,p$({suffix:$.snapshot.status==="completed"?"✅ 咨询完成":$.snapshot.status==="cancelled"?"\uD83D\uDED1 咨询取消":"❌ 咨询失败"}));if(Y&&H)await this.deps.dispose($.cardId);else{let V=`footer=${Y?"ok":"MISS"} settings=${H?"ok":"MISS"}`;if(f0($.snapshot,`card finalization failed: ${V}`),Q=!0,G(`consult: terminal card transaction MISS run=${$.snapshot.runId} ${V}`),!await this.sendWarning($,`⚠️ consult ${$.snapshot.runId} 结果已产生,但卡片未能正常收尾 (${V})`))Q=!0}}catch(Y){let H=T$(Y);if(f0($.snapshot,`card finalization failed: ${H}`),Q=!0,G(`consult: terminal card finalization crashed run=${$.snapshot.runId}: ${H}`),!await this.sendWarning($,`⚠️ consult ${$.snapshot.runId} 结果已产生,但卡片收尾失败: ${H}`))Q=!0}if($.presentationErrors.length){if(!await this.sendWarning($,`⚠️ consult ${$.snapshot.runId} 完整结果已返回主 Agent,但 ${$.presentationErrors.length} 次评审卡更新未落地。`))Q=!0}if(Q)try{this.deps.writeArtifact(T5(s2,`${$.snapshot.runId}.json`),$.snapshot)}catch(Y){let H=T$(Y);$.snapshot.status="failed",f0($.snapshot,`artifact diagnostic persistence failed: ${H}`),G(`consult: failed to persist final diagnostics run=${$.snapshot.runId}: ${H}`)}}catch(Q){let Y=T$(Q);$.snapshot.status="failed",f0($.snapshot,`terminal finalization crashed: ${Y}`),G(`consult: unexpected terminal finalization crash run=${$.snapshot.runId}: ${Y}`);try{this.deps.writeArtifact(T5(s2,`${$.snapshot.runId}.json`),$.snapshot)}catch(H){G(`consult: failed to persist terminal crash run=${$.snapshot.runId}: ${T$(H)}`)}}finally{$.finalized=!0}}recordPresentationError($,Z){$.presentationErrors.push(Z),G(`consult: ${Z} run=${$.snapshot.runId}`)}async sendWarning($,Z){try{return await this.deps.sendTextRaw($.chatId,Z),!0}catch(J){let Q=`warning delivery failed: ${T$(J)}`;return f0($.snapshot,Q),G(`consult: ${Q} run=${$.snapshot.runId}`),!1}}}function oj($){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,model:$.model,effort:$.effort,status:"queued",output:""}}function oH($){return JSON.parse(JSON.stringify($))}function T$($){return $ instanceof Error?$.message:String($)}function f0($,Z){$.error=[$.error,Z].filter(Boolean).join("; ")}async function aj($,Z,J){let Q=0,Y=Array.from({length:Math.min(Z,$.length)},async()=>{while(!0){let H=Q++;if(H>=$.length)return;await J($[H])}});await Promise.all(Y)}var dj=4,nj;var aH=E(()=>{t0();w$();n();v9();pH();nH();D$();h$();w();nj={getCatalog:D0,startWorker:mH,buildTargetContext:dH,sendCard:c,sendTextRaw:N,convertMessageToCard:r$,recordCardCreated:c$,replaceElementChecked:U$,patchSummaryThrottled:G0,flush:m$,cancelSummary:X$,patchSettingsChecked:q$,dispose:b$,writeArtifact:V$}});function rH($){if(!$||typeof $!=="object")throw Error("consult request must be an object");let Z=$,J=Array.isArray(Z.identity_ids)?Z.identity_ids.map(String):Array.isArray(Z.identityIds)?Z.identityIds.map(String):[],Q=[...new Set(J.map((z)=>z.trim()).filter(Boolean))];if(Q.length===0)throw Error("consult request requires at least one identity_id");if(Q.length>64)throw Error("consult request supports at most 64 identities");let Y=String(Z.kind??"");if(Y!=="question"&&Y!=="review"&&Y!=="critique")throw Error(`unsupported consult kind: ${String(Z.kind??"")}`);let H=String(Z.question??"").trim(),V=String(Z.instructions??"").trim(),X=rj(Z.target);if(Y==="question"&&!H)throw Error('question consult requires "question"');if(Y==="critique"&&!H&&X.type!=="proposal")throw Error('critique consult requires "question" or a proposal target');let W=Z.cross_review===!0||Z.crossReview===!0;if(W&&Q.length>8)throw Error("cross-review supports at most 8 identities");return{identityIds:Q,kind:Y,target:X,question:H,instructions:V,crossReview:W}}function rj($){if($===void 0||$===null)return{type:"working_directory"};if(!$||typeof $!=="object")throw Error("consult target must be an object");let Z=$,J=String(Z.type??"");switch(J){case"working_directory":return{type:J};case"uncommitted_changes":return{type:J};case"commit":{let Q=String(Z.sha??"").trim();if(!Q)throw Error("commit target requires sha");return{type:J,sha:Q}}case"base_branch":{let Q=String(Z.branch??"").trim();if(!Q)throw Error("base_branch target requires branch");return{type:J,branch:Q}}case"proposal":{let Q=String(Z.text??"");if(!Q.trim())throw Error("proposal target requires text");return{type:J,text:Q}}default:throw Error(`unsupported consult target: ${J||"MISS"}`)}}async function ZV($,Z,J,Q){if(J.pathname!=="/consult"&&!J.pathname.startsWith("/consult/"))return!1;let Y=(W,z)=>{return Z.statusCode=W,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(z)),!0},H=tj($.headers.authorization);if(!H)return Y(401,{error:"missing bearer capability"});let V=Q.authorize(H);if(!V)return Y(403,{error:"invalid or stale consult capability"});if($.method==="GET"&&J.pathname==="/consult/identities")return await e6(),Y(200,ej(D0()));if($.method==="POST"&&J.pathname==="/consult/runs"){let W;try{W=rH(await sj($))}catch(z){return Y(400,{error:$V(z)})}try{let z=await Q.service.startRun(V,W);return Y(202,eH(z))}catch(z){return Y(409,{error:$V(z)})}}let X=J.pathname.match(/^\/consult\/runs\/([^/]+)$/);if(X&&$.method==="GET"){let W=sH(X[1]);if(!W)return Y(400,{error:"invalid consult run id encoding"});let z=Q.service.getRun(W);if(!z||!Q.service.ownsRun(W,V))return Y(404,{error:"consult run not found"});return Y(200,eH(z))}if(X&&$.method==="DELETE"){let W=sH(X[1]);if(!W)return Y(400,{error:"invalid consult run id encoding"});if(!Q.service.getRun(W)||!Q.service.ownsRun(W,V))return Y(404,{error:"consult run not found"});let K=await Q.service.cancelRun(W,"cancelled by consult client");return Y(K?200:409,K?{ok:!0,run_id:W}:{error:"consult run is already terminal",run_id:W})}return Y(405,{error:"unsupported consult endpoint"})}function sH($){try{return decodeURIComponent($)}catch{return null}}function tj($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function sj($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>tH)throw Error(`request body exceeds ${tH} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function ej($){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,effort:Z.effort,supported_efforts:Z.supportedEfforts,source_default:Z.sourceDefault,origin:Z.origin,status:Z.status,reason:Z.reason,role:Z.role,instructions:Z.instructions,base_identity_id:Z.baseIdentityId})),source_failures:$.sourceFailures.map((Z)=>({token_source_id:Z.tokenSourceId,display:Z.display,status:Z.status,reason:Z.reason})),...$.presetFailure?{preset_failure:$.presetFailure}:{}}}function eH($){return{run_id:$.runId,session_name:$.sessionName,kind:$.kind,target:$.target,question:$.question,instructions:$.instructions,cross_review:$.crossReview,status:$.status,target_fingerprint:$.targetFingerprint,reviewers:$.reviewers.map((Z)=>({identity_id:Z.identityId,identity_name:Z.identityName,token_source_id:Z.tokenSourceId,model:Z.model,effort:Z.effort,status:Z.status,output:Z.output,first_pass_output:Z.firstPassOutput,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,card_message_id:$.cardMessageId}}function $V($){return $ instanceof Error?$.message:String($)}var tH=2097152;var JV=E(()=>{v9();A$()});function $B(){return["---",`name: ${QV}`,`description: ${JSON.stringify('Run any code, change, plan, architecture, security, testing, or correctness review, and consult, ask, or obtain a second opinion from another configured model, LLM, AI, or agent through Lodestar. Always use this skill for every review request and whenever the user asks to "让 DeepSeek 审查", "问一下 GLM5.3", "找其他模型看看", "多模型评审", "交叉复核", "ask another AI/model/agent", or "second opinion". Discover identities first; batch every selected identity into exactly one Lodestar run so reviewers execute concurrently; never call provider CLIs directly.')}`,"---","","# lodestar-consult","","Use Lodestar's configured reviewer identities to ask another model or run an","independent review. The daemon owns credentials, model routing, read-only","isolation, unrestricted network access, progress cards, cancellation, and result capture.","","## Required workflow","","1. Always query the live identity catalog first:","","```bash","# desc: 查询当前可用的全局评审身份","lodestar-consult identities --json","```","",'2. Select only identities returned by that command with `status: "ready"`.'," Never reuse an id from an earlier turn and never invent or substitute a model.","3. Finish selecting the complete identity set before starting any run. If two"," or more identities are selected, pass every id to exactly one command using"," repeated `--identity` flags. This single-run batch is mandatory for concurrency.","4. Resolve the user's wording:"," - Exact model request (for example `GLM-5.3`): exact normalized model match."," - Token Source/family only (for example `DeepSeek`): select that source's"," unique `source_default: true` identity.",' - Named global role: prefer the matching `origin: "preset"` identity.'," - Generic review without a named model: prefer a ready preset matching"," the requested review role; otherwise choose one relevant ready"," source-default catalog identity and state which identity was used."," - Ambiguous matches: ask the user with the host's native question tool.",' - "several/other models": choose a small relevant set from different token'," sources. Call every ready identity only when the user explicitly asks for all.","5. Run the consultation and wait for its terminal report. Attribute every result"," to the actual identity/model and surface failures without replacing them.","6. If no suitable ready identity exists, show the catalog failure and tell the"," user to configure accounts with `model` or global roles with `reviewers`.","","## Mandatory batching","","- Never launch one `lodestar-consult run` per identity, whether sequentially,"," as background tasks, with shell parallelism, or in separate tool calls.","- The daemon permits one active run per project group. Reviewer concurrency is"," server-side fan-out inside one run; separate run commands serialize or conflict.","- Query once, select all identities, issue one run, and wait once.","","## Ask another model","","```bash","# desc: 请求指定模型回答独立咨询","lodestar-consult run --identity '<identity-id>' --kind question --stdin <<'EOF'","<question and only the context that materially helps>","EOF","```","","## Review current changes","","```bash","# desc: 并发请求多个模型审查当前未提交变更","lodestar-consult run --identity '<identity-id-1>' --identity '<identity-id-2>' --kind review --target uncommitted_changes","```","","Keep adding `--identity` flags to this same command for all selected reviewers.","Add `--cross-review` to the same run only when the user asks for cross-review,","debate, consensus, or reviewers to critique each other.","","## Review a proposal","","```bash","# desc: 请求指定模型复核当前方案","lodestar-consult run --identity '<identity-id>' --kind review --target proposal --stdin <<'EOF'","<proposal>","EOF","```","","## Boundaries","","- Do not run `codex`, `claude`, or provider HTTP APIs directly for this task.","- Do not expose `LODESTAR_CONSULT_CAPABILITY` in output, logs, or command args.","- A non-zero command exit is a real consultation failure. Report it; do not"," continue as though consensus succeeded.","- Reviewer output is advisory. Check its evidence before applying changes.",""].join(`
413
- `)}function YV(){s9({name:QV,body:$B()})}var QV="lodestar-consult";var HV=E(()=>{O5()});import{chmodSync as ZB,existsSync as WV,readFileSync as JB}from"node:fs";import{homedir as QB}from"node:os";import{basename as YB,dirname as HB,join as B1,resolve as VB}from"node:path";function XB($={}){let Z=VB($.daemonEntry??process.argv[1]??""),J=$.runtime??process.execPath,Q=$.exists??WV,Y=HB(Z),H=B1(Y,"src","consult-cli.ts"),V=B1(Y,"lodestar-consult.js"),X=B1(Y,"dist","lodestar-consult.js"),z=/^bun(?:\.exe)?$/i.test(YB(J))?[H,V,X]:[V,X],K=z.find(Q);if(!K)throw Error(`lodestar-consult entry not found beside daemon: ${z.join(", ")}`);return{runtime:J,entry:K}}function zV($={}){let Z=$.platform??process.platform,J=$.env??process.env,Q=$.targetDir??WB(Z,$.homeDir??QB(),$.localAppData??process.env.LOCALAPPDATA),Y=$.launch??XB(),H=B1(Q,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult"),V=Z==="win32"?`@"${XV(Y.runtime)}" "${XV(Y.entry)}" %*\r
413
+ ${Z.text}`;break}if(J.length>nH)throw Error(`consult target context is too large (${J.length}/${nH} chars)`);return{target:Z,promptContext:J,fingerprint:uB("sha256").update(J).digest("hex")}}async function tB($){try{let Z=(await Z0($,["rev-parse","--show-toplevel"])).trim(),J=(await Z0($,["rev-parse","--verify","HEAD^{commit}"])).trim(),Q=await Z0($,["status","--short","--untracked-files=all"]);return{snapshot:[`root=${Z}`,`HEAD=${J}`,Q||"clean"].join(`
414
+ `),error:null}}catch(Z){return{snapshot:null,error:Z instanceof Error?Z.message:String(Z)}}}function oH($){if(!$||$.startsWith("-")||/[\u0000-\u001f\u007f\s]/.test($))throw Error(`invalid git ref: ${JSON.stringify($)}`)}async function Z0($,Z){try{let{stdout:J}=await rB("git",Z,{cwd:$,encoding:"utf8",maxBuffer:oB,timeout:aB,killSignal:"SIGKILL"});return String(J)}catch(J){let Q=J,Y=Buffer.isBuffer(Q.stderr)?Q.stderr.toString("utf8"):String(Q.stderr??""),H=Buffer.isBuffer(Q.stdout)?Q.stdout.toString("utf8"):String(Q.stdout??"");throw Error([`git ${Z.join(" ")} failed`,Q.message,H.trim(),Y.trim()].filter(Boolean).join(": "))}}var nH=500000,oB=8388608,aB=1e4,rB;var rH=k(()=>{rB=nB(pB)});import{randomUUID as sB}from"node:crypto";import{join as E3}from"node:path";class N3{deps;runs=new Map;startingRunsByChat=new Map;constructor($=$j){this.deps=$}async startRun($,Z){this.pruneRuns();let J=`consult_${sB()}`,Q=this.startingRunsByChat.get($.chatId),Y=[...this.runs.values()].find((H)=>H.chatId===$.chatId&&!H.finalized);if(Q||Y)throw Error(`consult run already active: ${Q??Y.snapshot.runId}; batch all identities into one run with repeated --identity flags`);this.startingRunsByChat.set($.chatId,J);try{let H=this.deps.getCatalog(),X=Z.identityIds.map((j)=>{let L=H.identities.find((A)=>A.id===j);if(!L)throw Error(`consult identity not found: ${j}`);if(L.status!=="ready")throw Error(`${L.displayName}: ${L.reason??L.status}`);return L}),V=Z.target??{type:"working_directory"},W=await this.deps.buildTargetContext($.workDir,V),G={runId:J,sessionName:$.sessionName,kind:Z.kind,target:V,question:Z.question??"",instructions:Z.instructions??"",crossReview:Z.crossReview===!0,status:"running",targetFingerprint:W.fingerprint,reviewers:X.map((j)=>Zj(j)),createdAt:new Date().toISOString()},K=await this.deps.sendCard($.chatId,C7(G));if(!K)throw Error("consult card creation failed; reviewers were not started");let _;try{_=await this.deps.convertMessageToCard(K)}catch(j){throw await this.deps.sendTextRaw($.chatId,`❌ consult 卡片初始化失败,reviewer 未启动: ${T$(j)}`),j}G.cardMessageId=K,this.deps.recordCardCreated(_,G.reviewers.length+2,(j)=>{z(`consult: card write failed run=${J} code=${j??"MISS"}`)});let B={snapshot:G,targetContext:W,identities:X,workDir:$.workDir,chatId:$.chatId,cardId:_,workers:new Map,cancelled:!1,terminalized:!1,finalized:!1,presentationErrors:[]};return this.runs.set(J,B),this.executeRun(B).catch(async(j)=>{z(`consult: run=${J} crashed: ${T$(j)}`),await this.finishRun(B,"failed",T$(j))}),tH(G)}finally{if(this.startingRunsByChat.get($.chatId)===J)this.startingRunsByChat.delete($.chatId)}}getRun($){this.pruneRuns();let Z=this.runs.get($);if(!Z)return null;let J=tH(Z.snapshot);if(Z.terminalized&&!Z.finalized)J.status="running",delete J.finishedAt;return J}ownsRun($,Z){let J=this.runs.get($);return!!J&&J.snapshot.sessionName===Z.sessionName&&J.chatId===Z.chatId}async cancelRun($,Z="consult cancelled"){let J=this.runs.get($);if(!J||J.snapshot.status!=="running"||J.terminalized)return!1;J.cancelled=!0;let Q=[...J.workers.values()];await Promise.allSettled(Q.map((Y)=>Y.cancel(Z)));for(let Y of J.snapshot.reviewers)if(Y.status==="queued"||Y.status==="running")Y.status="cancelled",Y.error=Z,Y.finishedAt=new Date().toISOString();return await this.finishRun(J,"cancelled",Z),!0}async cancelSessionRuns($,Z,J){let Q=[...this.runs.values()].filter((Y)=>Y.snapshot.sessionName===$&&Y.chatId===Z&&Y.snapshot.status==="running"&&!Y.terminalized);await Promise.allSettled(Q.map((Y)=>this.cancelRun(Y.snapshot.runId,J)))}pruneRuns(){if(this.runs.size<=256)return;let $=[...this.runs.values()].filter((Z)=>Z.finalized).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<=256)break;this.runs.delete(Z.snapshot.runId)}}async executeRun($){if(await this.executeRound($,!1),$.cancelled||$.snapshot.status!=="running")return;if($.snapshot.reviewers.some((Q)=>Q.status!=="completed")){await this.finishRun($,"failed","一个或多个选定顾问失败,未进入后续复核");return}if($.snapshot.crossReview&&$.snapshot.reviewers.length>1){for(let Q of $.snapshot.reviewers)Q.firstPassOutput=Q.output,Q.output="",Q.status="queued",Q.error=void 0,Q.startedAt=void 0,Q.finishedAt=void 0,Q.durationMs=void 0;if(await Promise.all($.snapshot.reviewers.map((Q)=>this.updateReviewerCard($,Q))),await this.executeRound($,!0),$.cancelled||$.snapshot.status!=="running")return;if($.snapshot.reviewers.some((Q)=>Q.status!=="completed")){await this.finishRun($,"failed","交叉复核未全部完成");return}}if((await this.deps.buildTargetContext($.workDir,$.snapshot.target)).fingerprint!==$.snapshot.targetFingerprint){await this.finishRun($,"failed","评审期间目标已变化,结果已标记为过期");return}await this.finishRun($,"completed")}async executeRound($,Z){let J=$.snapshot.reviewers.map((Q)=>({identityId:Q.identityId,name:Q.identityName,output:Q.firstPassOutput??Q.output}));await Jj($.identities,eB,async(Q)=>{let Y=$.snapshot.reviewers.find((X)=>X.identityId===Q.id);if($.cancelled)return;let H;try{let X=dH({identity:Q,kind:$.snapshot.kind,question:$.snapshot.question,instructions:$.snapshot.instructions,targetContext:$.targetContext.promptContext,...Z?{peerOutputs:J.filter((V)=>V.identityId!==Q.id).map((V)=>({name:V.name,output:V.output}))}:{}});H=this.deps.startWorker({identity:Q,workDir:$.workDir,prompt:X})}catch(X){await this.failReviewer($,Y,T$(X));return}if($.workers.set(Q.id,H),$.cancelled){await H.cancel("consult cancelled before reviewer start"),$.workers.delete(Q.id);return}Y.status="running",Y.startedAt=new Date().toISOString(),await this.updateReviewerCard($,Y);try{let X=await H.done;if($.cancelled)return;Y.status="completed",Y.output=X.output,Y.durationMs=X.durationMs,Y.usage=X.usage,Y.finishedAt=new Date().toISOString(),await this.updateReviewerCard($,Y)}catch(X){if($.cancelled)return;await this.failReviewer($,Y,T$(X))}finally{$.workers.delete(Q.id)}})}async failReviewer($,Z,J){if(Z.status="failed",Z.error=J,Z.finishedAt=new Date().toISOString(),Z.startedAt)Z.durationMs=Date.now()-Date.parse(Z.startedAt);await this.updateReviewerCard($,Z)}async updateReviewerCard($,Z){try{if(!await this.deps.replaceElementChecked($.cardId,A9(Z.identityId),L9(Z,F9($.snapshot.reviewers.length))))this.recordPresentationError($,`reviewer card MISS: ${Z.identityName}`)}catch(J){this.recordPresentationError($,`reviewer card update failed (${Z.identityName}): ${T$(J)}`)}try{this.deps.patchSummaryThrottled($.cardId,P9($.snapshot))}catch(J){this.recordPresentationError($,`reviewer summary update failed: ${T$(J)}`)}}async finishRun($,Z,J){if($.terminalized)return;$.terminalized=!0;try{if($.snapshot.status=Z,$.snapshot.finishedAt=new Date().toISOString(),J)w0($.snapshot,J);if($.presentationErrors.length)for(let Y of $.presentationErrors)w0($.snapshot,Y);try{this.deps.writeArtifact(E3(s2,`${$.snapshot.runId}.json`),$.snapshot)}catch(Y){let H=T$(Y);$.snapshot.status="failed",w0($.snapshot,`artifact persistence failed: ${H}`),z(`consult: run artifact persistence failed run=${$.snapshot.runId}: ${H}`)}let Q=!1;try{await this.deps.flush($.cardId);let Y=await this.deps.replaceElementChecked($.cardId,M.consultRunFooter,D9($.snapshot));this.deps.cancelSummary($.cardId);let H=await this.deps.patchSettingsChecked($.cardId,p$({suffix:$.snapshot.status==="completed"?"✅ 咨询完成":$.snapshot.status==="cancelled"?"\uD83D\uDED1 咨询取消":"❌ 咨询失败"}));if(Y&&H)await this.deps.dispose($.cardId);else{let X=`footer=${Y?"ok":"MISS"} settings=${H?"ok":"MISS"}`;if(w0($.snapshot,`card finalization failed: ${X}`),Q=!0,z(`consult: terminal card transaction MISS run=${$.snapshot.runId} ${X}`),!await this.sendWarning($,`⚠️ consult ${$.snapshot.runId} 结果已产生,但卡片未能正常收尾 (${X})`))Q=!0}}catch(Y){let H=T$(Y);if(w0($.snapshot,`card finalization failed: ${H}`),Q=!0,z(`consult: terminal card finalization crashed run=${$.snapshot.runId}: ${H}`),!await this.sendWarning($,`⚠️ consult ${$.snapshot.runId} 结果已产生,但卡片收尾失败: ${H}`))Q=!0}if($.presentationErrors.length){if(!await this.sendWarning($,`⚠️ consult ${$.snapshot.runId} 完整结果已返回主 Agent,但 ${$.presentationErrors.length} 次评审卡更新未落地。`))Q=!0}if(Q)try{this.deps.writeArtifact(E3(s2,`${$.snapshot.runId}.json`),$.snapshot)}catch(Y){let H=T$(Y);$.snapshot.status="failed",w0($.snapshot,`artifact diagnostic persistence failed: ${H}`),z(`consult: failed to persist final diagnostics run=${$.snapshot.runId}: ${H}`)}}catch(Q){let Y=T$(Q);$.snapshot.status="failed",w0($.snapshot,`terminal finalization crashed: ${Y}`),z(`consult: unexpected terminal finalization crash run=${$.snapshot.runId}: ${Y}`);try{this.deps.writeArtifact(E3(s2,`${$.snapshot.runId}.json`),$.snapshot)}catch(H){z(`consult: failed to persist terminal crash run=${$.snapshot.runId}: ${T$(H)}`)}}finally{$.finalized=!0}}recordPresentationError($,Z){$.presentationErrors.push(Z),z(`consult: ${Z} run=${$.snapshot.runId}`)}async sendWarning($,Z){try{return await this.deps.sendTextRaw($.chatId,Z),!0}catch(J){let Q=`warning delivery failed: ${T$(J)}`;return w0($.snapshot,Q),z(`consult: ${Q} run=${$.snapshot.runId}`),!1}}}function Zj($){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,model:$.model,effort:$.effort,status:"queued",output:""}}function tH($){return JSON.parse(JSON.stringify($))}function T$($){return $ instanceof Error?$.message:String($)}function w0($,Z){$.error=[$.error,Z].filter(Boolean).join("; ")}async function Jj($,Z,J){let Q=0,Y=Array.from({length:Math.min(Z,$.length)},async()=>{while(!0){let H=Q++;if(H>=$.length)return;await J($[H])}});await Promise.all(Y)}var eB=4,$j;var sH=k(()=>{t0();w$();n();h9();iH();rH();D$();h$();w();$j={getCatalog:D0,startWorker:lH,buildTargetContext:aH,sendCard:c,sendTextRaw:y,convertMessageToCard:r$,recordCardCreated:c$,replaceElementChecked:U$,patchSummaryThrottled:z0,flush:m$,cancelSummary:V$,patchSettingsChecked:q$,dispose:S$,writeArtifact:X$}});function eH($){if(!$||typeof $!=="object")throw Error("consult request must be an object");let Z=$,J=Array.isArray(Z.identity_ids)?Z.identity_ids.map(String):Array.isArray(Z.identityIds)?Z.identityIds.map(String):[],Q=[...new Set(J.map((G)=>G.trim()).filter(Boolean))];if(Q.length===0)throw Error("consult request requires at least one identity_id");if(Q.length>64)throw Error("consult request supports at most 64 identities");let Y=String(Z.kind??"");if(Y!=="question"&&Y!=="review"&&Y!=="critique")throw Error(`unsupported consult kind: ${String(Z.kind??"")}`);let H=String(Z.question??"").trim(),X=String(Z.instructions??"").trim(),V=Qj(Z.target);if(Y==="question"&&!H)throw Error('question consult requires "question"');if(Y==="critique"&&!H&&V.type!=="proposal")throw Error('critique consult requires "question" or a proposal target');let W=Z.cross_review===!0||Z.crossReview===!0;if(W&&Q.length>8)throw Error("cross-review supports at most 8 identities");return{identityIds:Q,kind:Y,target:V,question:H,instructions:X,crossReview:W}}function Qj($){if($===void 0||$===null)return{type:"working_directory"};if(!$||typeof $!=="object")throw Error("consult target must be an object");let Z=$,J=String(Z.type??"");switch(J){case"working_directory":return{type:J};case"uncommitted_changes":return{type:J};case"commit":{let Q=String(Z.sha??"").trim();if(!Q)throw Error("commit target requires sha");return{type:J,sha:Q}}case"base_branch":{let Q=String(Z.branch??"").trim();if(!Q)throw Error("base_branch target requires branch");return{type:J,branch:Q}}case"proposal":{let Q=String(Z.text??"");if(!Q.trim())throw Error("proposal target requires text");return{type:J,text:Q}}default:throw Error(`unsupported consult target: ${J||"MISS"}`)}}async function YX($,Z,J,Q){if(J.pathname!=="/consult"&&!J.pathname.startsWith("/consult/"))return!1;let Y=(W,G)=>{return Z.statusCode=W,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(G)),!0},H=Yj($.headers.authorization);if(!H)return Y(401,{error:"missing bearer capability"});let X=Q.authorize(H);if(!X)return Y(403,{error:"invalid or stale consult capability"});if($.method==="GET"&&J.pathname==="/consult/identities")return await $6(),Y(200,Xj(D0()));if($.method==="POST"&&J.pathname==="/consult/runs"){let W;try{W=eH(await Hj($))}catch(G){return Y(400,{error:QX(G)})}try{let G=await Q.service.startRun(X,W);return Y(202,JX(G))}catch(G){return Y(409,{error:QX(G)})}}let V=J.pathname.match(/^\/consult\/runs\/([^/]+)$/);if(V&&$.method==="GET"){let W=ZX(V[1]);if(!W)return Y(400,{error:"invalid consult run id encoding"});let G=Q.service.getRun(W);if(!G||!Q.service.ownsRun(W,X))return Y(404,{error:"consult run not found"});return Y(200,JX(G))}if(V&&$.method==="DELETE"){let W=ZX(V[1]);if(!W)return Y(400,{error:"invalid consult run id encoding"});if(!Q.service.getRun(W)||!Q.service.ownsRun(W,X))return Y(404,{error:"consult run not found"});let K=await Q.service.cancelRun(W,"cancelled by consult client");return Y(K?200:409,K?{ok:!0,run_id:W}:{error:"consult run is already terminal",run_id:W})}return Y(405,{error:"unsupported consult endpoint"})}function ZX($){try{return decodeURIComponent($)}catch{return null}}function Yj($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function Hj($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>$X)throw Error(`request body exceeds ${$X} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function Xj($){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,effort:Z.effort,supported_efforts:Z.supportedEfforts,source_default:Z.sourceDefault,origin:Z.origin,status:Z.status,reason:Z.reason,role:Z.role,instructions:Z.instructions,base_identity_id:Z.baseIdentityId})),source_failures:$.sourceFailures.map((Z)=>({token_source_id:Z.tokenSourceId,display:Z.display,status:Z.status,reason:Z.reason})),...$.presetFailure?{preset_failure:$.presetFailure}:{}}}function JX($){return{run_id:$.runId,session_name:$.sessionName,kind:$.kind,target:$.target,question:$.question,instructions:$.instructions,cross_review:$.crossReview,status:$.status,target_fingerprint:$.targetFingerprint,reviewers:$.reviewers.map((Z)=>({identity_id:Z.identityId,identity_name:Z.identityName,token_source_id:Z.tokenSourceId,model:Z.model,effort:Z.effort,status:Z.status,output:Z.output,first_pass_output:Z.firstPassOutput,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,card_message_id:$.cardMessageId}}function QX($){return $ instanceof Error?$.message:String($)}var $X=2097152;var HX=k(()=>{h9();P$()});function Vj(){return["---",`name: ${XX}`,`description: ${JSON.stringify('Run any code, change, plan, architecture, security, testing, or correctness review, and consult, ask, or obtain a second opinion from another configured model, LLM, AI, or agent through Lodestar. Always use this skill for every review request and whenever the user asks to "让 DeepSeek 审查", "问一下 GLM5.3", "找其他模型看看", "多模型评审", "交叉复核", "ask another AI/model/agent", or "second opinion". Discover identities first; batch every selected identity into exactly one Lodestar run so reviewers execute concurrently; never call provider CLIs directly.')}`,"---","","# lodestar-consult","","Use Lodestar's configured reviewer identities to ask another model or run an","independent review. The daemon owns credentials, model routing, read-only","isolation, unrestricted network access, progress cards, cancellation, and result capture.","","## Required workflow","","1. Always query the live identity catalog first:","","```bash","# desc: 查询当前可用的全局评审身份","lodestar-consult identities --json","```","",'2. Select only identities returned by that command with `status: "ready"`.'," Never reuse an id from an earlier turn and never invent or substitute a model.","3. Finish selecting the complete identity set before starting any run. If two"," or more identities are selected, pass every id to exactly one command using"," repeated `--identity` flags. This single-run batch is mandatory for concurrency.","4. Resolve the user's wording:"," - Exact model request (for example `GLM-5.3`): exact normalized model match."," - Token Source/family only (for example `DeepSeek`): select that source's"," unique `source_default: true` identity.",' - Named global role: prefer the matching `origin: "preset"` identity.'," - Generic review without a named model: prefer a ready preset matching"," the requested review role; otherwise choose one relevant ready"," source-default catalog identity and state which identity was used."," - Ambiguous matches: ask the user with the host's native question tool.",' - "several/other models": choose a small relevant set from different token'," sources. Call every ready identity only when the user explicitly asks for all.","5. Run the consultation and wait for its terminal report. Attribute every result"," to the actual identity/model and surface failures without replacing them.","6. If no suitable ready identity exists, show the catalog failure and tell the"," user to configure accounts with `model` or global roles with `reviewers`.","","## Mandatory batching","","- Never launch one `lodestar-consult run` per identity, whether sequentially,"," as background tasks, with shell parallelism, or in separate tool calls.","- The daemon permits one active run per project group. Reviewer concurrency is"," server-side fan-out inside one run; separate run commands serialize or conflict.","- Query once, select all identities, issue one run, and wait once.","","## Ask another model","","```bash","# desc: 请求指定模型回答独立咨询","lodestar-consult run --identity '<identity-id>' --kind question --stdin <<'EOF'","<question and only the context that materially helps>","EOF","```","","## Review current changes","","```bash","# desc: 并发请求多个模型审查当前未提交变更","lodestar-consult run --identity '<identity-id-1>' --identity '<identity-id-2>' --kind review --target uncommitted_changes","```","","Keep adding `--identity` flags to this same command for all selected reviewers.","Add `--cross-review` to the same run only when the user asks for cross-review,","debate, consensus, or reviewers to critique each other.","","## Review a proposal","","```bash","# desc: 请求指定模型复核当前方案","lodestar-consult run --identity '<identity-id>' --kind review --target proposal --stdin <<'EOF'","<proposal>","EOF","```","","## Boundaries","","- Do not run `codex`, `claude`, or provider HTTP APIs directly for this task.","- Do not expose `LODESTAR_CONSULT_CAPABILITY` in output, logs, or command args.","- A non-zero command exit is a real consultation failure. Report it; do not"," continue as though consensus succeeded.","- Reviewer output is advisory. Check its evidence before applying changes.",""].join(`
415
+ `)}function VX(){e9({name:XX,body:Vj()})}var XX="lodestar-consult";var WX=k(()=>{T3()});import{chmodSync as Wj,existsSync as KX,readFileSync as Gj}from"node:fs";import{homedir as zj}from"node:os";import{basename as Kj,dirname as _j,join as j1,resolve as qj}from"node:path";function Bj($={}){let Z=qj($.daemonEntry??process.argv[1]??""),J=$.runtime??process.execPath,Q=$.exists??KX,Y=_j(Z),H=j1(Y,"src","consult-cli.ts"),X=j1(Y,"lodestar-consult.js"),V=j1(Y,"dist","lodestar-consult.js"),G=/^bun(?:\.exe)?$/i.test(Kj(J))?[H,X,V]:[X,V],K=G.find(Q);if(!K)throw Error(`lodestar-consult entry not found beside daemon: ${G.join(", ")}`);return{runtime:J,entry:K}}function _X($={}){let Z=$.platform??process.platform,J=$.env??process.env,Q=$.targetDir??jj(Z,$.homeDir??zj(),$.localAppData??process.env.LOCALAPPDATA),Y=$.launch??Bj(),H=j1(Q,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult"),X=Z==="win32"?`@"${zX(Y.runtime)}" "${zX(Y.entry)}" %*\r
414
416
  `:`#!/bin/sh
415
- exec ${VV(Y.runtime)} ${VV(Y.entry)} "$@"
416
- `,X=WV(H)?JB(H,"utf8"):null;if(X!==V)a5(H,V),G(`command: ${X===null?"installed":"updated"} ${H}`);else ZB(H,448);return zB(J,Q,Z),H}function WB($,Z,J){if($==="win32")return B1(J??B1(Z,"AppData","Local"),"Lodestar","bin");return B1(Z,".local","bin")}function zB($,Z,J){let Q=J==="win32"?Object.keys($).find((X)=>X.toLowerCase()==="path")??"Path":"PATH",Y=J==="win32"?";":":",H=$[Q]??"",V=(X)=>J==="win32"?X.toLowerCase():X;if(H.split(Y).some((X)=>V(X)===V(Z)))return;$[Q]=H?`${Z}${Y}${H}`:Z}function VV($){return`'${$.replaceAll("'",`'"'"'`)}'`}function XV($){return $.replaceAll('"','""')}var GV=E(()=>{w();h$()});function KV($,Z,J){return $>0&&Z-$>J}function _V($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function y5($){return typeof $==="string"&&$.length>0?$:void 0}function qV($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let V=y5(J.image_key);return V?{key:V,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Q=y5(J.file_key);if(!Q)return null;let Y=y5(J.file_name);return{key:Q,type:"file",...Y?{name:Y}:{},displayText:Y?`(${$==="media"?"video":"file"}: ${Y})`:""}}function jV($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function BV($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}function KB($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!GB.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 Y=(this.tails.get(J)??Promise.resolve()).then(Z),H;return H=Y.then(()=>{},()=>{}).finally(()=>{if(this.tails.get(J)===H)this.tails.delete(J)}),this.tails.set(J,H),{accepted:!0,completion:Y}}enqueue($,Z){let J=this.tryEnqueue($,Z);return J.accepted?J.completion:Promise.reject(Error(`per-key actor ${J.reason}`))}close(){this.accepting=!1}isAccepting(){return this.accepting}pending(){return this.tails.values()}}function LV($){let Z=$.now??Date.now;return{accept(J){let Q=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Q))}}}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 E5($){if(Array.isArray($))return`[${$.map(E5).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)}:${E5(J)}`).join(",")}}`}function _B($){let Z=$?.action?.value??{},J=String(Z?.kind??"unknown"),Q=String($?.context?.open_chat_id??""),Y=String($?.context?.open_message_id??""),H=null;switch(J){case"menu":H={request_id:Z.request_id};break;case"permission":H={request_id:Z.request_id};break;case"ask":H={tool_use_id:Z.tool_use_id,question_idx:Z.question_idx};break;case"worktree_disband":H={slug:Z.slug};break;case"temp_fork_select":case"temp_back_select":case"temp_resume_select":H={panel_id:Z.panel_id};break;case"tasklist_delete_prompt":case"tasklist_delete_confirm":H={guid:Z.guid};break;case"tasklist_enable":H={guid:Z.guid,project:Z.project,panel_id:Z.panel_id};break;case"token_source_enable":H={source_id:Z.source_id};break;case"consult_identity_add":H={panel_id:Z.panel_id,identity_id:Z.identity_id};break;case"consult_identity_role":H={panel_id:Z.panel_id,identity_id:Z.identity_id};break;case"consult_identity_toggle":case"consult_identity_delete":case"consult_identity_delete_confirm":H={panel_id:Z.panel_id,preset_id:Z.preset_id};break;case"consult_identity_page":H={panel_id:Z.panel_id,page:Z.page};break;case"consult_identity_back":H={panel_id:Z.panel_id};break;case"notify_callback":H={notify_id:Z.notify_id};break;case"provider_select":case"model_select":case"model_custom_prompt":case"model_panel_cancel":case"model_effort_select":H={panel_id:Z.panel_id};break;default:H=Z}return`${Q}\x00${Y}\x00${J}\x00${E5(H)}`}function qB($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${_B($)}`}}function jB(){return new Promise(($)=>setTimeout($,0))}function e9($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function DV($){let Z=$.afterAck??jB,J=(Y)=>{try{$.onBackgroundError?.(Y)}catch{}},Q=async(Y)=>{try{await Y()}catch(H){J(H)}};return{accept(Y){if(!$.actor.isAccepting())return $.responses.closed(Y);let H=KB(Y);if(H)return $.responses.invalid(Y,H);let V=qB(Y),X=V.deliveryKey?[V.deliveryKey,V.businessKey]:[V.businessKey],W=$.deduper.claimAll(X);if(W==="inflight")return $.responses.inflight(Y);if(W==="completed")return $.responses.completed(Y);let z=$.actor.tryEnqueue($.scope(Y),async()=>{try{await Z()}catch(j){$.deduper.failAll(X),J(j);return}let K;try{K=await $.execute(Y)}catch(j){$.deduper.completeAll(X),await Q(()=>$.presentExecutionFailure(Y,j));return}await Q(async()=>{try{await $.present(Y,K)}catch(j){await $.presentPresentationFailure(Y,j)}});let _;try{_=$.completion(Y,K)}catch(j){e9($.deduper,V,!1),J(j);return}if(_){let j=_.then((B)=>{e9($.deduper,V,B==="complete")},(B)=>{e9($.deduper,V,!1),J(B)});$.track(j);return}e9($.deduper,V,$.businessSucceeded(Y,K))});if(!z.accepted)return $.deduper.failAll(X),$.responses.closed(Y);return $.track(z.completion),z.completion.catch(J),$.responses.accepted(Y)}}}var GB;var PV=E(()=>{GB=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","consult_identity_add","consult_identity_role","consult_identity_toggle","consult_identity_delete","consult_identity_delete_confirm","consult_identity_page","consult_identity_back","notify_callback"])});function F0($){return $ instanceof Error?$.message:String($)}function FV($,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 AV($){let Z=(Y,H)=>{let V=$.registry.get(Y);if(V&&V.sessionName!==H)throw Error(`chat ${Y} is already owned by session "${V.sessionName}", not "${H}"`);if(!V)V=$.createSession(H,Y),$.registry.set(Y,V);return V};return{sessionFor:Z,createTempSession:async(Y)=>{let H;try{if(G$(Y.launch,Y.routing.provider,Y.workDir),Y.launch.kind==="resume")throw Error("temporary groups must start fresh or fork; resume is not allowed");if(H=await $.ensureChatForSession(Y.chatName,Y.userOpenId),!H.created)return{ok:!1,chatId:H.chatId,error:"临时会话必须使用新群;既有群保留,未执行加入、启动或删除"}}catch(X){let W=F0(X);return $.log(`temp-session: create "${Y.chatName}" failed: ${W}`),{ok:!1,error:W}}let V=async()=>{let X=null;try{if($.registerTempSessionLease(Y.chatName,H.chatId),X=Z(H.chatId,Y.chatName),X.isRunning())return{ok:!1,error:`${Y.chatName} 已有会话在跑,先 bye 解散再重试`};if(X.workDir!==Y.workDir)throw Error(`临时群 cwd 不匹配: source=${Y.workDir} target=${X.workDir}`);if(X.applyConversationRouting(Y.routing),!(Y.launch.kind==="fork"?await X.startForked(Y.launch,{announce:!1}):await X.start({announce:!1})))throw Error(`${X.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Y.chatName,Y.seedAnchors??[],Y.branchBase),{ok:!0,chatId:H.chatId}}catch(W){let z=F0(W);if($.log(`temp-session: initialize "${Y.chatName}" failed: ${z}`),X)try{await X.stop("临时群启动失败清理",{announce:!1})}catch(_){let j=F0(_);return $.log(`temp-session: failed-create stop "${Y.chatName}" failed: ${j}`),{ok:!1,chatId:H.chatId,error:`${z};无法确认 Session 已停止,临时群/session 仍保留: ${j}`}}if(!H.created)return{ok:!1,error:`${z};既有群保留,未执行删除`};let K;try{let _=await $.disbandChatForSessionExact(Y.chatName,H.chatId);K=FV(Y.chatName,H.chatId,_)}catch(_){let j=F0(_);return $.log(`temp-session: create cleanup "${Y.chatName}" failed: ${j}`),{ok:!1,chatId:H.chatId,error:`${z};自动解散失败,临时群/session 仍保留: ${j}`}}try{$.registry.delete(K),X?.dispose(),$.clearSessionConversationState(Y.chatName)}catch(_){let j=F0(_);return $.log(`temp-session: local cleanup "${Y.chatName}" failed: ${j}`),{ok:!1,error:`${z};临时群已确认解散,但本地状态清理失败: ${j}`}}return{ok:!1,error:`${z};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(H.chatId,V):await V()}catch(X){let W=F0(X);return $.log(`temp-session: target actor "${Y.chatName}" failed: ${W}`),{ok:!1,chatId:H.chatId,error:`${W};临时群/session 仍保留`}}},disbandTempSession:async(Y,H)=>{let V=$.chatIdForSession(Y);if(!H||V!==H){let z=`临时群 chat_id 已变化: expected=${H||"-"} bound=${V??"-"}`;return $.log(`temp-session: disband identity rejected "${Y}": ${z}`),{ok:!1,error:`${z};未执行停止或删群`}}if(!$.hasTempSessionLease(Y,H)){let z=`群 ${H} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Y}": ${z}`),{ok:!1,error:`${z};未执行停止或删群`}}let X=$.registry.get(V);try{if(X)await X.stop("bye 解散",{announce:!1})}catch(z){let K=F0(z);return $.log(`temp-session: stop before disband "${Y}" failed: ${K}`),{ok:!1,error:`${K};无法确认 Session 已停止,未执行删群`}}let W;try{let z=await $.disbandChatForSessionExact(Y,V);W=FV(Y,V,z)}catch(z){let K=F0(z);return $.log(`temp-session: disband "${Y}" failed: ${K}`),{ok:!1,error:`${K};临时群/session 仍保留`}}try{return $.registry.delete(W),X?.dispose(),$.clearSessionConversationState(Y),{ok:!0}}catch(z){let K=F0(z);return $.log(`temp-session: local cleanup after disband "${Y}" failed: ${K}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${K}`}}}}}var UV=E(()=>{T1()});var gB={};import*as Q2 from"@larksuiteoapi/node-sdk";import{chmodSync as BB,existsSync as b5,mkdirSync as LB,readFileSync as DB,unlinkSync as J6,writeFileSync as PB}from"node:fs";import{dirname as FB}from"node:path";function Y2($,Z){if(L1=Math.max(L1,Z),$6)return $6;w5=!0,o2.close(),S5=f5();try{R2(S5)}catch(J){G(`shutdown alive marker write failed: ${J}`),L1=1}return $6=(async()=>{G(`${$}: staged shutdown begin sessions=${J2.size}`);try{let J=(async()=>{return await BV(()=>[...o2.pending(),...kV]),await Promise.allSettled([...[...J2.values()].map((V)=>V.stop(`daemon ${$}`,{announce:!1}))])})(),Q=null,Y=new Promise((V)=>{Q=setTimeout(()=>V("deadline"),RV)}),H=await Promise.race([J.then((V)=>{for(let X of V)if(X.status==="rejected")L1=1,G(`shutdown session stop failed: ${X.reason}`);return"stopped"}),Y]);if(Q)clearTimeout(Q);if(H==="deadline")L1=1,G(`${$}: shutdown deadline ${RV}ms reached; forcing exit`);else G(`${$}: all sessions stopped`)}catch(J){G(`${$}: staged shutdown failed: ${J}`),L1=1}finally{OV(),process.exit(L1)}})(),$6}function yV($){return jV(kV,$)}function EV($,Z="ws"){if(w5)return G(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Q=UB.accept($);if(!Q.accepted)return G(`${Z}: reject inbound message${J?"":" without chat_id"}: actor ${Q.reason}`),!1;return Q.completion.catch((Y)=>{G(`${Z}: handleMessage rejected chat=${J.slice(0,8)}…: ${Y}`)}),!0}function f5(){let $=new Set;for(let Z of J2.values())if(Z.shouldRevive())$.add(Z.sessionName);for(let Z of n2)$.add(Z);return[...$]}function Z6(){R2(f5())}function xV($,Z){return v5.sessionFor($,Z)}async function MB($){return await v5.createTempSession($)}async function RB($,Z){return await v5.disbandTempSession($,Z)}async function OB(){let $=[...new Set(b8())];if($.length===0)return;n2=new Set($),G(`revive: ${$.length} session(s) marked alive on shutdown: ${$.join(", ")}`);try{await Promise.all($.map(async(Z)=>{let J=h1(Z);if(!J){G(`revive: no chatId binding for "${Z}", skip`),n2.delete(Z),Z6();return}let Q=xV(J,Z);try{if(await Q.restart(!0))G(`revive: spawned "${Z}" (chat ${J.slice(0,8)}…)`);else G(`revive: "${Z}" did not start`)}catch(Y){G(`revive: restart "${Z}" failed: ${Y}`)}finally{n2.delete(Z),Z6()}}))}finally{n2.clear(),Z6()}}function TB($){let Z=[],J=[],Q=[],Y=typeof $?.title==="string"?$.title.trim():"";if(Y)Q.push(`# ${Y}`);let H=Array.isArray($?.content)?$.content:[];for(let V of H){if(!Array.isArray(V))continue;let X=[];for(let z of V){if(!z||typeof z!=="object")continue;switch(z.tag){case"text":{let K=String(z.text??""),_=Array.isArray(z.style)?z.style:[];if(_.includes("bold"))K=`**${K}**`;if(_.includes("italic"))K=`*${K}*`;if(_.includes("lineThrough")||_.includes("strikethrough"))K=`~~${K}~~`;X.push(K);break}case"a":{let K=String(z.href??""),_=String(z.text??K);X.push(`[${_}](${K})`);break}case"at":{let K=String(z.user_name??z.user_id??"");X.push(`@${K}`);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 W=X.join("");if(W.trim())Q.push(W)}return{markdown:Q.join(`
417
+ exec ${GX(Y.runtime)} ${GX(Y.entry)} "$@"
418
+ `,V=KX(H)?Gj(H,"utf8"):null;if(V!==X)r3(H,X),z(`command: ${V===null?"installed":"updated"} ${H}`);else Wj(H,448);return Lj(J,Q,Z),H}function jj($,Z,J){if($==="win32")return j1(J??j1(Z,"AppData","Local"),"Lodestar","bin");return j1(Z,".local","bin")}function Lj($,Z,J){let Q=J==="win32"?Object.keys($).find((V)=>V.toLowerCase()==="path")??"Path":"PATH",Y=J==="win32"?";":":",H=$[Q]??"",X=(V)=>J==="win32"?V.toLowerCase():V;if(H.split(Y).some((V)=>X(V)===X(Z)))return;$[Q]=H?`${Z}${Y}${H}`:Z}function GX($){return`'${$.replaceAll("'",`'"'"'`)}'`}function zX($){return $.replaceAll('"','""')}var qX=k(()=>{w();h$()});function BX($,Z,J){return $>0&&Z-$>J}function jX($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function k3($){return typeof $==="string"&&$.length>0?$:void 0}function LX($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let X=k3(J.image_key);return X?{key:X,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Q=k3(J.file_key);if(!Q)return null;let Y=k3(J.file_name);return{key:Q,type:"file",...Y?{name:Y}:{},displayText:Y?`(${$==="media"?"video":"file"}: ${Y})`:""}}function DX($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function AX($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}function Aj($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!Dj.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 y3{tails=new Map;accepting=!0;tryEnqueue($,Z){if(!this.accepting)return{accepted:!1,reason:"closed"};let J=$.trim();if(!J)return{accepted:!1,reason:"invalid-key"};let Y=(this.tails.get(J)??Promise.resolve()).then(Z),H;return H=Y.then(()=>{},()=>{}).finally(()=>{if(this.tails.get(J)===H)this.tails.delete(J)}),this.tails.set(J,H),{accepted:!0,completion:Y}}enqueue($,Z){let J=this.tryEnqueue($,Z);return J.accepted?J.completion:Promise.reject(Error(`per-key actor ${J.reason}`))}close(){this.accepting=!1}isAccepting(){return this.accepting}pending(){return this.tails.values()}}function FX($){let Z=$.now??Date.now;return{accept(J){let Q=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Q))}}}class C3{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 x3($){if(Array.isArray($))return`[${$.map(x3).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)}:${x3(J)}`).join(",")}}`}function Fj($){let Z=$?.action?.value??{},J=String(Z?.kind??"unknown"),Q=String($?.context?.open_chat_id??""),Y=String($?.context?.open_message_id??""),H=null;switch(J){case"menu":H={request_id:Z.request_id};break;case"permission":H={request_id:Z.request_id};break;case"ask":H={tool_use_id:Z.tool_use_id,question_idx:Z.question_idx};break;case"worktree_disband":H={slug:Z.slug};break;case"temp_fork_select":case"temp_back_select":case"temp_resume_select":H={panel_id:Z.panel_id};break;case"tasklist_delete_prompt":case"tasklist_delete_confirm":H={guid:Z.guid};break;case"tasklist_enable":H={guid:Z.guid,project:Z.project,panel_id:Z.panel_id};break;case"token_source_enable":H={source_id:Z.source_id};break;case"consult_identity_add":H={panel_id:Z.panel_id,identity_id:Z.identity_id};break;case"consult_identity_role":H={panel_id:Z.panel_id,identity_id:Z.identity_id};break;case"consult_identity_toggle":case"consult_identity_delete":case"consult_identity_delete_confirm":H={panel_id:Z.panel_id,preset_id:Z.preset_id};break;case"consult_identity_page":H={panel_id:Z.panel_id,page:Z.page};break;case"consult_identity_back":H={panel_id:Z.panel_id};break;case"notify_callback":H={notify_id:Z.notify_id};break;case"provider_select":case"model_select":case"model_custom_prompt":case"model_panel_cancel":case"model_effort_select":H={panel_id:Z.panel_id};break;default:H=Z}return`${Q}\x00${Y}\x00${J}\x00${x3(H)}`}function Pj($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${Fj($)}`}}function Uj(){return new Promise(($)=>setTimeout($,0))}function $8($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function PX($){let Z=$.afterAck??Uj,J=(Y)=>{try{$.onBackgroundError?.(Y)}catch{}},Q=async(Y)=>{try{await Y()}catch(H){J(H)}};return{accept(Y){if(!$.actor.isAccepting())return $.responses.closed(Y);let H=Aj(Y);if(H)return $.responses.invalid(Y,H);let X=Pj(Y),V=X.deliveryKey?[X.deliveryKey,X.businessKey]:[X.businessKey],W=$.deduper.claimAll(V);if(W==="inflight")return $.responses.inflight(Y);if(W==="completed")return $.responses.completed(Y);let G=$.actor.tryEnqueue($.scope(Y),async()=>{try{await Z()}catch(B){$.deduper.failAll(V),J(B);return}let K;try{K=await $.execute(Y)}catch(B){$.deduper.completeAll(V),await Q(()=>$.presentExecutionFailure(Y,B));return}await Q(async()=>{try{await $.present(Y,K)}catch(B){await $.presentPresentationFailure(Y,B)}});let _;try{_=$.completion(Y,K)}catch(B){$8($.deduper,X,!1),J(B);return}if(_){let B=_.then((j)=>{$8($.deduper,X,j==="complete")},(j)=>{$8($.deduper,X,!1),J(j)});$.track(B);return}$8($.deduper,X,$.businessSucceeded(Y,K))});if(!G.accepted)return $.deduper.failAll(V),$.responses.closed(Y);return $.track(G.completion),G.completion.catch(J),$.responses.accepted(Y)}}}var Dj;var UX=k(()=>{Dj=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","consult_identity_add","consult_identity_role","consult_identity_toggle","consult_identity_delete","consult_identity_delete_confirm","consult_identity_page","consult_identity_back","notify_callback"])});function F0($){return $ instanceof Error?$.message:String($)}function MX($,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 RX($){let Z=(Y,H)=>{let X=$.registry.get(Y);if(X&&X.sessionName!==H)throw Error(`chat ${Y} is already owned by session "${X.sessionName}", not "${H}"`);if(!X)X=$.createSession(H,Y),$.registry.set(Y,X);return X};return{sessionFor:Z,createTempSession:async(Y)=>{let H;try{if(z$(Y.launch,Y.routing.provider,Y.workDir),Y.launch.kind==="resume")throw Error("temporary groups must start fresh or fork; resume is not allowed");if(H=await $.ensureChatForSession(Y.chatName,Y.userOpenId),!H.created)return{ok:!1,chatId:H.chatId,error:"临时会话必须使用新群;既有群保留,未执行加入、启动或删除"}}catch(V){let W=F0(V);return $.log(`temp-session: create "${Y.chatName}" failed: ${W}`),{ok:!1,error:W}}let X=async()=>{let V=null;try{if($.registerTempSessionLease(Y.chatName,H.chatId),V=Z(H.chatId,Y.chatName),V.isRunning())return{ok:!1,error:`${Y.chatName} 已有会话在跑,先 bye 解散再重试`};if(V.workDir!==Y.workDir)throw Error(`临时群 cwd 不匹配: source=${Y.workDir} target=${V.workDir}`);if(V.applyConversationRouting(Y.routing),!(Y.launch.kind==="fork"?await V.startForked(Y.launch,{announce:!1}):await V.start({announce:!1})))throw Error(`${V.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Y.chatName,Y.seedAnchors??[],Y.branchBase),{ok:!0,chatId:H.chatId}}catch(W){let G=F0(W);if($.log(`temp-session: initialize "${Y.chatName}" failed: ${G}`),V)try{await V.stop("临时群启动失败清理",{announce:!1})}catch(_){let B=F0(_);return $.log(`temp-session: failed-create stop "${Y.chatName}" failed: ${B}`),{ok:!1,chatId:H.chatId,error:`${G};无法确认 Session 已停止,临时群/session 仍保留: ${B}`}}if(!H.created)return{ok:!1,error:`${G};既有群保留,未执行删除`};let K;try{let _=await $.disbandChatForSessionExact(Y.chatName,H.chatId);K=MX(Y.chatName,H.chatId,_)}catch(_){let B=F0(_);return $.log(`temp-session: create cleanup "${Y.chatName}" failed: ${B}`),{ok:!1,chatId:H.chatId,error:`${G};自动解散失败,临时群/session 仍保留: ${B}`}}try{$.registry.delete(K),V?.dispose(),$.clearSessionConversationState(Y.chatName)}catch(_){let B=F0(_);return $.log(`temp-session: local cleanup "${Y.chatName}" failed: ${B}`),{ok:!1,error:`${G};临时群已确认解散,但本地状态清理失败: ${B}`}}return{ok:!1,error:`${G};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(H.chatId,X):await X()}catch(V){let W=F0(V);return $.log(`temp-session: target actor "${Y.chatName}" failed: ${W}`),{ok:!1,chatId:H.chatId,error:`${W};临时群/session 仍保留`}}},disbandTempSession:async(Y,H)=>{let X=$.chatIdForSession(Y);if(!H||X!==H){let G=`临时群 chat_id 已变化: expected=${H||"-"} bound=${X??"-"}`;return $.log(`temp-session: disband identity rejected "${Y}": ${G}`),{ok:!1,error:`${G};未执行停止或删群`}}if(!$.hasTempSessionLease(Y,H)){let G=`群 ${H} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Y}": ${G}`),{ok:!1,error:`${G};未执行停止或删群`}}let V=$.registry.get(X);try{if(V)await V.stop("bye 解散",{announce:!1})}catch(G){let K=F0(G);return $.log(`temp-session: stop before disband "${Y}" failed: ${K}`),{ok:!1,error:`${K};无法确认 Session 已停止,未执行删群`}}let W;try{let G=await $.disbandChatForSessionExact(Y,X);W=MX(Y,X,G)}catch(G){let K=F0(G);return $.log(`temp-session: disband "${Y}" failed: ${K}`),{ok:!1,error:`${K};临时群/session 仍保留`}}try{return $.registry.delete(W),V?.dispose(),$.clearSessionConversationState(Y),{ok:!0}}catch(G){let K=F0(G);return $.log(`temp-session: local cleanup after disband "${Y}" failed: ${K}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${K}`}}}}}var OX=k(()=>{T1()});var dj={};import*as Q2 from"@larksuiteoapi/node-sdk";import{chmodSync as Mj,existsSync as b3,mkdirSync as Rj,readFileSync as Oj,unlinkSync as Q8,writeFileSync as Tj}from"node:fs";import{dirname as Ej}from"node:path";function Y2($,Z){if(L1=Math.max(L1,Z),Z8)return Z8;f3=!0,o2.close(),w3=v3();try{R2(w3)}catch(J){z(`shutdown alive marker write failed: ${J}`),L1=1}return Z8=(async()=>{z(`${$}: staged shutdown begin sessions=${J2.size}`);try{let J=(async()=>{return await AX(()=>[...o2.pending(),...xX]),await Promise.allSettled([...[...J2.values()].map((X)=>X.stop(`daemon ${$}`,{announce:!1}))])})(),Q=null,Y=new Promise((X)=>{Q=setTimeout(()=>X("deadline"),EX)}),H=await Promise.race([J.then((X)=>{for(let V of X)if(V.status==="rejected")L1=1,z(`shutdown session stop failed: ${V.reason}`);return"stopped"}),Y]);if(Q)clearTimeout(Q);if(H==="deadline")L1=1,z(`${$}: shutdown deadline ${EX}ms reached; forcing exit`);else z(`${$}: all sessions stopped`)}catch(J){z(`${$}: staged shutdown failed: ${J}`),L1=1}finally{NX(),process.exit(L1)}})(),Z8}function yX($){return DX(xX,$)}function CX($,Z="ws"){if(f3)return z(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Q=kj.accept($);if(!Q.accepted)return z(`${Z}: reject inbound message${J?"":" without chat_id"}: actor ${Q.reason}`),!1;return Q.completion.catch((Y)=>{z(`${Z}: handleMessage rejected chat=${J.slice(0,8)}…: ${Y}`)}),!0}function v3(){let $=new Set;for(let Z of J2.values())if(Z.shouldRevive())$.add(Z.sessionName);for(let Z of n2)$.add(Z);return[...$]}function J8(){R2(v3())}function SX($,Z){return h3.sessionFor($,Z)}async function xj($){return await h3.createTempSession($)}async function yj($,Z){return await h3.disbandTempSession($,Z)}async function Cj(){let $=[...new Set(b6())];if($.length===0)return;n2=new Set($),z(`revive: ${$.length} session(s) marked alive on shutdown: ${$.join(", ")}`);try{await Promise.all($.map(async(Z)=>{let J=h1(Z);if(!J){z(`revive: no chatId binding for "${Z}", skip`),n2.delete(Z),J8();return}let Q=SX(J,Z);try{if(await Q.restart(!0))z(`revive: spawned "${Z}" (chat ${J.slice(0,8)}…)`);else z(`revive: "${Z}" did not start`)}catch(Y){z(`revive: restart "${Z}" failed: ${Y}`)}finally{n2.delete(Z),J8()}}))}finally{n2.clear(),J8()}}function Sj($){let Z=[],J=[],Q=[],Y=typeof $?.title==="string"?$.title.trim():"";if(Y)Q.push(`# ${Y}`);let H=Array.isArray($?.content)?$.content:[];for(let X of H){if(!Array.isArray(X))continue;let V=[];for(let G of X){if(!G||typeof G!=="object")continue;switch(G.tag){case"text":{let K=String(G.text??""),_=Array.isArray(G.style)?G.style:[];if(_.includes("bold"))K=`**${K}**`;if(_.includes("italic"))K=`*${K}*`;if(_.includes("lineThrough")||_.includes("strikethrough"))K=`~~${K}~~`;V.push(K);break}case"a":{let K=String(G.href??""),_=String(G.text??K);V.push(`[${_}](${K})`);break}case"at":{let K=String(G.user_name??G.user_id??"");V.push(`@${K}`);break}case"code_inline":V.push(`\`${String(G.text??"")}\``);break;case"hr":V.push("---");break;case"img":if(G.image_key)Z.push(String(G.image_key));break;case"media":if(G.file_key)J.push({key:String(G.file_key),name:G.file_name});break;case"emotion":break;default:if(typeof G.text==="string")V.push(G.text)}}let W=V.join("");if(W.trim())Q.push(W)}return{markdown:Q.join(`
417
419
 
418
- `),imageKeys:Z,fileKeys:J}}async function yB($,Z=Date.now()){let J=$?.message;if(!J)return;let Y=($?.sender?.sender_id??$?.event?.sender?.sender_id??J?.sender?.sender_id)?.open_id??"",H=J.message_id;if(H&&Z2.has(H))return;if(H){if(Z2.add(H),Z2.size>200){let D=[...Z2];Z2.clear();for(let F of D.slice(-100))Z2.add(F)}}let V=Number(J.create_time??0);if(KV(V,Z,kB)){if(G(`drop stale message ${H} ageAtReceipt=${Math.round((Z-V)/1000)}s`),H)R$(H,"CrossMark");return}let X=J.chat_id,W={};try{W=JSON.parse(J.content??"{}")}catch{}let z=J.message_type==="text"?W.text??"":"";if(typeof z==="string"&&z.startsWith("[DEBUG]")){try{PB(Z4,JSON.stringify({chat_id:X,sender_open_id:Y,seeded_at:new Date().toISOString(),seeded_msg_id:H??""},null,2)),G(`debug: seeded inject context chat=${X.slice(0,8)}… sender=${Y.slice(0,8)}…`)}catch(F){G(`debug: seed context failed: ${F}`)}let D=z.slice(7);W.text=D,J.content=JSON.stringify(W)}let K=Y$.get(X);if(!K)await O2(),K=Y$.get(X);if(!K)K=await h8(X)??void 0;if(!K){G(`unknown chat ${X}, dropping message`),await O(X,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let _=y2(K);S1(_,X);let j=xV(X,_),B={};try{B=JSON.parse(J.content??"{}")}catch{}let L=J.message_type,P="",A=[];if(L==="text")P=(B.text??"").trim();else if(L==="post"){let D=TB(B);P=D.markdown.trim();for(let F of D.imageKeys){let y=await T2(J.message_id,F,"image");if(y)A.push(y)}for(let F of D.fileKeys){let y=await T2(J.message_id,F.key,"file",F.name);if(y)A.push(y)}}if(L==="text"&&P){if(await j.runCommand(P,Y))return}if(L==="text"&&P&&await j.consumeModelCustomMessage(P,Y))return;if(L==="text"&&P&&j.hasPendingAsk()){await j.onAskMessageAnswer(P,Y,H??"");return}let R=qV(L,B);if(R){let D=await T2(J.message_id,R.key,R.type,R.name);if(!D){await O(X,_V(L));return}if(A.push(D),!P&&R.displayText)P=R.displayText}if(!P&&A.length===0){G(`drop empty message ${H} type=${L}`);return}if(await j.onMultiMessageInbound(P,A,Y,H??""))return;await j.onUserMessage(P||"(empty)",A,Y,H??"")}function Q6($){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:"启用账号",consult_identity_add:"添加评审身份",consult_identity_role:"选择评审角色",consult_identity_toggle:"启停评审身份",consult_identity_delete:"删除评审身份",consult_identity_delete_confirm:"确认删除评审身份",consult_identity_page:"评审身份翻页",consult_identity_back:"返回评审身份列表",notify_callback:"通知反馈"}[$]??$}function EB($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function H$($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function D1($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function v$($){return H$($.card?f$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok)}async function P1($,Z){if(!$){G(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await N($,Z))G(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function xB($,Z){let J=String($?.action?.value?.kind??"unknown"),Q=Q6(J),Y=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),H=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),V=EB(Z),X=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(V&&H)try{await W0(H,V);return}catch(B){G(`card-action: ${J} original-card update failed: ${B instanceof Error?B.message:B}`),await P1(Y,`⚠️ ${Q}已处理,但原卡更新失败。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(V){await P1(Y,`⚠️ ${Q}已处理,但回调缺少原卡 message_id,无法更新。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let W=Z?.toast,z=typeof W?.content==="string"&&W.content.trim()?W.content.trim():`${Q}已完成`,K=J==="permission"&&String($?.action?.value?.decision??"")==="deny",_=Z?.__businessOk===!1||W?.type==="error"&&!K;if(!_&&new Set(["permission","ask","token_source_enable"]).has(J))return;await P1(Y,`${_?"❌":"✅"} ${Q}: ${z}`)}async function NB($,Z){let J=String($?.action?.value?.kind??"unknown"),Q=Z instanceof Error?Z.message:String(Z);await P1(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${Q6(J)}失败: ${Q}`)}function bB($){return CB.accept($)}async function SB($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Q=$?.context?.open_chat_id??"",Y=$?.operator?.open_id??"";if(J.kind==="notify_callback")return await wB(J,Q,Y);let H=J2.get(Q);if(!H)return H$({toast:{type:"error",content:"会话不存在,请先发消息启动"}},!1);switch(J.kind){case"permission":{let V=String(J.decision??"");if(!["allow","allow_always","deny"].includes(V))return{toast:{type:"error",content:"无效的权限决定"}};let X=await H.onPermissionDecision(J.request_id,V,Y);return H$({toast:{type:X.ok?V==="deny"?"error":"success":"error",content:X.message}},X.ok)}case"menu":{let V=Number(J.choice??-1);try{if(!Number.isInteger(V)||V<0)throw Error("无效的菜单选项");return await H.onUserMessage(`(menu choice ${V+1})`),H$(f$(N0({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${V+1} 项`,ok:!0})),!0)}catch(X){let W=X instanceof Error?X.message:String(X);return H$(f$(N0({title:"\uD83D\uDCCB 菜单选择",message:W,ok:!1})),!1)}}case"provider_select":{let V=await H.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return v$(V)}case"model_select":{let V=await H.onModelSelect(String(J.model??""),String(J.panel_id??""),Y,J);return v$(V)}case"model_custom_prompt":{let V=await H.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return v$(V)}case"model_panel_cancel":{let V=await H.onModelPanelCancel(String(J.panel_id??""));return v$(V)}case"model_effort_select":{let V=await H.onModelEffortSelect(String(J.model??""),String(J.effort??""),String(J.panel_id??""),Y,String(J.provider??""));return v$(V)}case"ask":{if(J.custom){let W=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",z=await H.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,W,Y);return H$({toast:{type:z?"success":"error",content:z?"已回答":W.trim()?"问题已失效或答案未被接受":"请输入答案"}},z)}let V=await H.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Y);return H$({toast:{type:V?"success":"error",content:V?"已回答":"问题已失效或选项无效"}},V)}case"worktree_disband":{let V=await H.onWorktreeDisband(String(J.slug??""));return H$(f$(V.card),V.ok)}case"temp_fork_select":{let V=await H.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Y);return H$(V.replaceCard===!1?{toast:{type:"error",content:V.message}}:f$(N0({title:"\uD83D\uDD31 会话分叉",message:V.message,ok:V.ok})),V.ok)}case"temp_back_select":{let V=await H.onBackSelect(String(J.panel_id??""),String(J.choice_id??""),Y);return H$(V.replaceCard===!1?{toast:{type:"error",content:V.message}}:f$(N0({title:"⏪ 会话回滚",message:V.message,ok:V.ok})),V.ok)}case"temp_resume_select":{let V=await H.onResumeSelect(String(J.panel_id??""),String(J.choice_id??""),Y);if(V.replaceCard===!1)return H$({toast:{type:"error",content:V.message}},V.ok);if(!V.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return H$(f$(M7({...V.resumePresentation,message:V.message,ok:V.ok})),V.ok,V.message)}case"tasklist_enable":{let V=await H.onTasklistEnable();return H$(f$(V.card),V.ok)}case"tasklist_delete_prompt":{let V=H.onTasklistDeletePrompt(String(J.guid??""));return H$(f$(V.card),V.ok)}case"tasklist_delete_confirm":{let V=await H.onTasklistDeleteConfirm(String(J.guid??""));return H$(f$(V.card),V.ok)}case"token_source_enable":{let{onTokenSourceEnable:V}=await Promise.resolve().then(() => (Z5(),$5));return await V(H,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"consult_identity_add":return v$(H.onConsultIdentityAdd(String(J.panel_id??""),String(J.identity_id??""),Y));case"consult_identity_role":return v$(H.onConsultIdentityRole(String(J.panel_id??""),String(J.identity_id??""),String(J.role??""),Y));case"consult_identity_toggle":return v$(H.onConsultIdentityToggle(String(J.panel_id??""),String(J.preset_id??""),Y));case"consult_identity_delete":return v$(H.onConsultIdentityDelete(String(J.panel_id??""),String(J.preset_id??""),Y));case"consult_identity_delete_confirm":return v$(H.onConsultIdentityDeleteConfirm(String(J.panel_id??""),String(J.preset_id??""),Y));case"consult_identity_page":return v$(H.onConsultIdentityPage(String(J.panel_id??""),J.page,Y));case"consult_identity_back":return v$(H.onConsultIdentityBack(String(J.panel_id??""),Y))}return{toast:{type:"info",content:"unknown action"}}}async function wB($,Z,J){let Q=String($?.notify_id??""),Y=String($?.button_id??"");if(!Q)return{toast:{type:"error",content:"回调缺少 notify_id"}};let H=r9(Q);if(!H)return G(`notify-callback: notify_id=${Q.slice(0,12)}… not found (expired or pre-restart)`),{toast:{type:"error",content:"通知已过期或已移除"}};if(H.unknownAt)return D1(H,H$({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${H.unknownReason?`: ${H.unknownReason}`:""}`}},!0));if(H.resolvedAt)return D1(H,{toast:{type:"info",content:"已处理过"}});if(AH(Q))return D1(H,{toast:{type:"info",content:"处理中…"}});let V=H.buttons.find((z)=>z.id===Y);if(!V)return G(`notify-callback: notify_id=${Q.slice(0,12)}… unknown button_id="${Y}"`),D1(H,H$({toast:{type:"error",content:"未知按钮"}},!1));if(!H.callbackUrl){try{U5(H.notifyId,V.id,J)}catch(z){return D1(H,H$({toast:{type:"error",content:`保存反馈结果失败: ${z instanceof Error?z.message:z}`}},!1))}return G(`notify-callback: notify_id=${Q.slice(0,12)}… resolved button="${Y}" by=${J.slice(0,8)}… (no callback, pull/display)`),D1(H,{...f$(t9(H,{status:"done",buttonId:V.id,text:V.text,operatorOpenId:J}))})}UH(H.notifyId);let X=yV(fB(H,V,J));X.catch((z)=>{G(`notify-callback: notify_id=${H.notifyId.slice(0,12)}… phase-2 rejected: ${z instanceof Error?z.message:z}`)});let W=X.then((z)=>z==="retry"?"retry":"complete").catch(()=>"retry");return D1(H,{toast:{type:"info",content:`⏳ 已选择:${V.text} · 推送中…`},__cardActionCompletion:W})}async function fB($,Z,J){try{let Q=t9($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await W0($.messageId,Q)}catch(X){G(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${X instanceof Error?X.message:X}`)}let Y=await kH($,Z,J),H=Y.ok?"complete":"retry",V;if(Y.ok){let X=TH($.notifyId,Z.id,J);if(X.state==="complete")V={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Y.reply};else{H="unknown",V={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 P1($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${X.detail}`)}catch(W){G(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${W instanceof Error?W.message:W}`)}}}else V={status:"failed",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:Y.detail};try{let X=t9($,V);await W0($.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 P1($.chatId,`⚠️ 通知反馈${H==="retry"?"失败且结果卡更新失败,可重新点击":"已执行,但结果卡更新失败"}: ${X instanceof Error?X.message:X}`)}catch(W){G(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${W instanceof Error?W.message:W}`)}}return G(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${H==="complete"?"delivered":H==="unknown"?"unknown/non-retryable":`failed: ${Y.detail}`} by=${J.slice(0,8)}…`),H}finally{MH($.notifyId)}}function C5($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function vB(){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(b5(v0))J6(v0)}catch{}try{Bun.serve({unix:v0,fetch:async($)=>{if($.method!=="POST")return new Response("use POST",{status:405});if(w5)return new Response("daemon shutdown in progress",{status:503});let Z={};try{Z=await $.json()}catch{return new Response("bad json",{status:400})}if(!b5(Z4))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let J={};try{J=JSON.parse(DB(Z4,"utf8"))}catch(X){return new Response(`ctx read failed: ${X}`,{status:500})}let Q=String(Z.text??"");if(!Q)return new Response("text required",{status:400});let Y=`【自动化测试】:${Q}`,H=await O(J.chat_id,Y);if(!H)return new Response("sendText failed — see daemon log",{status:502});let V={sender:{sender_id:{open_id:J.sender_open_id}},message:{message_id:H,chat_id:J.chat_id,message_type:"text",content:JSON.stringify({text:Q}),create_time:String(Date.now())}};if(G(`debug: inject text=${JSON.stringify(Q).slice(0,80)} msg_id=${H}`),!EV(V,"debug"))return new Response("daemon shutdown in progress",{status:503});return new Response(JSON.stringify({ok:!0,msg_id:H}),{headers:{"content-type":"application/json"}})}});try{BB(v0,384)}catch{}G(`debug: inject socket listening at ${v0}`)}catch($){G(`debug: socket bind failed: ${$}`)}}async function hB(){G(`lodestar-daemon: pid ${process.pid} starting`);let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (s7(),iQ));$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (A$(),I3));Z(),P8(),U8(),M8(),O8(),y8(),await O2(),setInterval(()=>{O2()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (X5(),V5));try{await J()}catch(k){G(`tasklist deletion reconcile failed: ${k instanceof Error?k.message:k}`)}let Q,Y=Date.now(),H=0,V=!1,X=null,W=1500,z=90000,K=600000,_=3,j=null,B=0,L="",P=!1,A=(k)=>{G(`[ws] rebuild requested before WS init — ${k}`)},R=(k,u=0,p=!1)=>{let $$=Date.now()+u;if(j){if(P||=p,$$>=B){G(`[ws] rebuild already scheduled — ${k}`);return}clearTimeout(j)}B=$$,L=k,P=p,j=setTimeout(()=>{let o=L,A0=P;j=null,B=0,L="",P=!1,A(o,A0)},u)},D={error:(k)=>G(`[ws-sdk error] ${C5(k)}`),warn:(k)=>{let u=C5(k);if(G(`[ws-sdk warn] ${u}`),u.includes("no pong/inbound"))R("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Y<K)},info:(k)=>G(`[ws-sdk] ${C5(k)}`),debug:(k)=>{},trace:(k)=>{}},F=new Q2.EventDispatcher({}),y=()=>{if(Y=Date.now(),H=0,X)clearTimeout(X),X=null};F.register({"im.message.receive_v1":async(k)=>{if(y(),!EV(k))throw Error("daemon shutdown in progress")}}),F.register({"card.action.trigger":async(k)=>{return y(),bB(k)}});let C=()=>new Q2.WSClient({appId:S.feishu.app_id,appSecret:S.feishu.app_secret,loggerLevel:Q2.LoggerLevel.info,logger:D,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>G("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>m(),onError:(k)=>A(`SDK onError: ${k?.message??k}`)});A=(k,u=!1)=>{if(V){G(`[ws] rebuild skipped (already rebuilding) — ${k}`);return}if(j)clearTimeout(j),j=null,B=0;V=!0,H++,G(`[ws] rebuild #${H} (fresh WSClient) — ${k}`);let p=Q;try{p?.close({force:!0})}catch($$){G(`[ws] rebuild: old close failed: ${$$}`)}if(Q=C(),Q.start({eventDispatcher:F}).catch(($$)=>{G(`[ws] rebuild start failed: ${$$}`),R(`fresh client start failed: ${$$}`,W,u)}),V=!1,u)x()};let x=()=>{if(X)clearTimeout(X);let k=Date.now();X=setTimeout(()=>{if(X=null,Y>=k){H=0;return}if(H>=_){G(`[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"),H=0;return}A(`verify: no event ${Math.round((Date.now()-k)/1000)}s after rebuild`,!0)},z)},m=()=>{let k=Date.now()-Y<K;G("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${k})`),H=0,R("post-reconnect precaution",W,k)};Q=C(),Q.start({eventDispatcher:F}).catch((k)=>{G(`[ws] initial start failed: ${k}`),R(`initial start failed: ${k}`,W,!1)}),G(`lodestar-daemon: WS start requested, watching ${Y$.size} groups`);let g=15000,f=2,T=0;setInterval(()=>{let{state:k}=Q.getConnectionStatus();if(k==="connected"){T=0;return}if(k==="failed"||k==="idle"){T=0,A(`watchdog: state=${k}`);return}if(T++,G(`[ws] watchdog: state=${k} (${T}/${f})`),T>=f)T=0,A(`watchdog: stuck in '${k}' ~${Math.round(g*f/1000)}s`)},g),vB(),RH(),CH({bind:S.notify.bind,port:S.notify.port,extraHandler:(k,u,p)=>ZV(k,u,p,{service:TV,authorize:($$)=>{for(let o of J2.values())if(o.acceptsConsultCapability($$))return o;return null}})}),zV(),vH(),YV(),await OB()}var MV=!1,w5=!1,$6=null,L1=0,S5=null,RV=15000,OV=()=>{if(MV)return;MV=!0;try{let $=S5??f5();if(R2($),$.length>0)G(`alive marker: [${$.join(", ")}]`)}catch($){G(`alive marker write failed: ${$}`)}try{J6(k$)}catch{}try{J6(v0)}catch{}},J2,TV,n2,o2,AB,kV,UB,v5,kB=30000,Z2,CB;var NV=E(()=>{LH();n();w$();M5();R5();R5();hH();aH();JV();HV();GV();y$();w();D$();_6();PV();UV();{let $=J4(k$);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(b5(k$))try{J6(k$)}catch{}}LB(FB(k$),{recursive:!0});l5(k$);process.on("exit",OV);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",($)=>{G(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),Y2("unhandledRejection",1)});process.on("uncaughtException",($)=>{G(`uncaughtException: ${$.stack??$.message}`),Y2("uncaughtException",1)});J2=new Map,TV=new k5,n2=new Set,o2=new x5,AB=new N5(30000),kV=new Set,UB=LV({actor:o2,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>yB($,Z)});v5=AV({registry:J2,createSession:($,Z)=>new j1($,Z,{onLifecycleChange:Z6,onCreateTempSession:MB,onDisbandTempSession:RB,onCancelConsultRuns:(J,Q,Y)=>TV.cancelSessionRuns(J,Q,Y)}),ensureChatForSession:w8,disbandChatForSessionExact:v8,chatIdForSession:h1,clearSessionConversationState:C8,registerTempSessionLease:F8,hasTempSessionLease:A8,replaceTurnAnchors:C$,runExclusive:($,Z)=>o2.enqueue($,Z),log:G});Z2=new Set;CB=DV({actor:o2,deduper:AB,scope:($)=>{if(String($?.action?.value?.kind??"").startsWith("consult_identity_"))return"__consult_identities_global__";return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:SB,present:xB,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");G(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await NB($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");G(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await P1(String($?.context?.open_chat_id??""),`⚠️ ${Q6(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:($)=>{yV($)},onBackgroundError:($)=>{G(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${Q6(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}})}});hB().catch(($)=>{G(`boot fatal: ${$}`),Y2("boot fatal",1)})});D$();_6();import{existsSync as CV,unlinkSync as IB}from"node:fs";var d$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function cB(){if(!CV(L$)){if(process.stdin.isTTY){console.log(),console.log(`${d$.bold}${d$.yellow}Lodestar: 未找到配置, 启动安装向导...${d$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => ($3(),e5));await Z();return}console.error(`${d$.red}Lodestar: 未找到配置 ${L$}${d$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${d$.green}lodestar-setup${d$.reset} 完成首次配置 (或直接运行 ${d$.green}lodestar-daemon${d$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=J4(k$);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(` • 误判 / 已经死了: 手删 ${k$} 后再跑`),process.exit(1);if(CV(k$))try{IB(k$)}catch{}await Promise.resolve().then(() => (NV(),gB))}cB().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});
420
+ `),imageKeys:Z,fileKeys:J}}async function wj($,Z=Date.now()){let J=$?.message;if(!J)return;let Y=($?.sender?.sender_id??$?.event?.sender?.sender_id??J?.sender?.sender_id)?.open_id??"",H=J.message_id;if(H&&Z2.has(H))return;if(H){if(Z2.add(H),Z2.size>200){let D=[...Z2];Z2.clear();for(let F of D.slice(-100))Z2.add(F)}}let X=Number(J.create_time??0);if(BX(X,Z,bj)){if(z(`drop stale message ${H} ageAtReceipt=${Math.round((Z-X)/1000)}s`),H)R$(H,"CrossMark");return}let V=J.chat_id,W={};try{W=JSON.parse(J.content??"{}")}catch{}let G=J.message_type==="text"?W.text??"":"";if(typeof G==="string"&&G.startsWith("[DEBUG]")){try{Tj(Z4,JSON.stringify({chat_id:V,sender_open_id:Y,seeded_at:new Date().toISOString(),seeded_msg_id:H??""},null,2)),z(`debug: seeded inject context chat=${V.slice(0,8)}… sender=${Y.slice(0,8)}…`)}catch(F){z(`debug: seed context failed: ${F}`)}let D=G.slice(7);W.text=D,J.content=JSON.stringify(W)}let K=Y$.get(V);if(!K)await O2(),K=Y$.get(V);if(!K)K=await I6(V)??void 0;if(!K){z(`unknown chat ${V}, dropping message`),await O(V,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let _=N2(K);b1(_,V);let B=SX(V,_),j={};try{j=JSON.parse(J.content??"{}")}catch{}let L=J.message_type,A="",P=[];if(L==="text")A=(j.text??"").trim();else if(L==="post"){let D=Sj(j);A=D.markdown.trim();for(let F of D.imageKeys){let N=await T2(J.message_id,F,"image");if(N)P.push(N)}for(let F of D.fileKeys){let N=await T2(J.message_id,F.key,"file",F.name);if(N)P.push(N)}}if(L==="text"&&A){if(await B.runCommand(A,Y))return}if(L==="text"&&A&&await B.consumeModelCustomMessage(A,Y))return;if(L==="text"&&A&&B.hasPendingAsk()){await B.onAskMessageAnswer(A,Y,H??"");return}let R=LX(L,j);if(R){let D=await T2(J.message_id,R.key,R.type,R.name);if(!D){await O(V,jX(L));return}if(P.push(D),!A&&R.displayText)A=R.displayText}if(!A&&P.length===0){z(`drop empty message ${H} type=${L}`);return}if(await B.onMultiMessageInbound(A,P,Y,H??""))return;await B.onUserMessage(A||"(empty)",P,Y,H??"")}function Y8($){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:"启用账号",consult_identity_add:"添加评审身份",consult_identity_role:"选择评审角色",consult_identity_toggle:"启停评审身份",consult_identity_delete:"删除评审身份",consult_identity_delete_confirm:"确认删除评审身份",consult_identity_page:"评审身份翻页",consult_identity_back:"返回评审身份列表",notify_callback:"通知反馈"}[$]??$}function fj($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function H$($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function D1($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function v$($){return H$($.card?f$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok)}async function A1($,Z){if(!$){z(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await y($,Z))z(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function vj($,Z){let J=String($?.action?.value?.kind??"unknown"),Q=Y8(J),Y=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),H=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),X=fj(Z),V=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(X&&H)try{await W0(H,X);return}catch(j){z(`card-action: ${J} original-card update failed: ${j instanceof Error?j.message:j}`),await A1(Y,`⚠️ ${Q}已处理,但原卡更新失败。${V}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(X){await A1(Y,`⚠️ ${Q}已处理,但回调缺少原卡 message_id,无法更新。${V}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let W=Z?.toast,G=typeof W?.content==="string"&&W.content.trim()?W.content.trim():`${Q}已完成`,K=J==="permission"&&String($?.action?.value?.decision??"")==="deny",_=Z?.__businessOk===!1||W?.type==="error"&&!K;if(!_&&new Set(["permission","ask","token_source_enable"]).has(J))return;await A1(Y,`${_?"❌":"✅"} ${Q}: ${G}`)}async function hj($,Z){let J=String($?.action?.value?.kind??"unknown"),Q=Z instanceof Error?Z.message:String(Z);await A1(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${Y8(J)}失败: ${Q}`)}function gj($){return Ij.accept($)}async function cj($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Q=$?.context?.open_chat_id??"",Y=$?.operator?.open_id??"";if(J.kind==="notify_callback")return await mj(J,Q,Y);let H=J2.get(Q);if(!H)return H$({toast:{type:"error",content:"会话不存在,请先发消息启动"}},!1);switch(J.kind){case"permission":{let X=String(J.decision??"");if(!["allow","allow_always","deny"].includes(X))return{toast:{type:"error",content:"无效的权限决定"}};let V=await H.onPermissionDecision(J.request_id,X,Y);return H$({toast:{type:V.ok?X==="deny"?"error":"success":"error",content:V.message}},V.ok)}case"menu":{let X=Number(J.choice??-1);try{if(!Number.isInteger(X)||X<0)throw Error("无效的菜单选项");return await H.onUserMessage(`(menu choice ${X+1})`),H$(f$(x0({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${X+1} 项`,ok:!0})),!0)}catch(V){let W=V instanceof Error?V.message:String(V);return H$(f$(x0({title:"\uD83D\uDCCB 菜单选择",message:W,ok:!1})),!1)}}case"provider_select":{let X=await H.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return v$(X)}case"model_select":{let X=await H.onModelSelect(String(J.model??""),String(J.panel_id??""),Y,J);return v$(X)}case"model_custom_prompt":{let X=await H.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return v$(X)}case"model_panel_cancel":{let X=await H.onModelPanelCancel(String(J.panel_id??""));return v$(X)}case"model_effort_select":{let X=await H.onModelEffortSelect(String(J.model??""),String(J.effort??""),String(J.panel_id??""),Y,String(J.provider??""));return v$(X)}case"ask":{if(J.custom){let W=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",G=await H.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,W,Y);return H$({toast:{type:G?"success":"error",content:G?"已回答":W.trim()?"问题已失效或答案未被接受":"请输入答案"}},G)}let X=await H.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Y);return H$({toast:{type:X?"success":"error",content:X?"已回答":"问题已失效或选项无效"}},X)}case"worktree_disband":{let X=await H.onWorktreeDisband(String(J.slug??""));return H$(f$(X.card),X.ok)}case"temp_fork_select":{let X=await H.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Y);return H$(X.replaceCard===!1?{toast:{type:"error",content:X.message}}:f$(x0({title:"\uD83D\uDD31 会话分叉",message:X.message,ok:X.ok})),X.ok)}case"temp_back_select":{let X=await H.onBackSelect(String(J.panel_id??""),String(J.choice_id??""),Y);return H$(X.replaceCard===!1?{toast:{type:"error",content:X.message}}:f$(x0({title:"⏪ 会话回滚",message:X.message,ok:X.ok})),X.ok)}case"temp_resume_select":{let X=await H.onResumeSelect(String(J.panel_id??""),String(J.choice_id??""),Y);if(X.replaceCard===!1)return H$({toast:{type:"error",content:X.message}},X.ok);if(!X.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return H$(f$(R7({...X.resumePresentation,message:X.message,ok:X.ok})),X.ok,X.message)}case"tasklist_enable":{let X=await H.onTasklistEnable();return H$(f$(X.card),X.ok)}case"tasklist_delete_prompt":{let X=H.onTasklistDeletePrompt(String(J.guid??""));return H$(f$(X.card),X.ok)}case"tasklist_delete_confirm":{let X=await H.onTasklistDeleteConfirm(String(J.guid??""));return H$(f$(X.card),X.ok)}case"token_source_enable":{let{onTokenSourceEnable:X}=await Promise.resolve().then(() => (J3(),Z3));return await X(H,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"consult_identity_add":return v$(H.onConsultIdentityAdd(String(J.panel_id??""),String(J.identity_id??""),Y));case"consult_identity_role":return v$(H.onConsultIdentityRole(String(J.panel_id??""),String(J.identity_id??""),String(J.role??""),Y));case"consult_identity_toggle":return v$(H.onConsultIdentityToggle(String(J.panel_id??""),String(J.preset_id??""),Y));case"consult_identity_delete":return v$(H.onConsultIdentityDelete(String(J.panel_id??""),String(J.preset_id??""),Y));case"consult_identity_delete_confirm":return v$(H.onConsultIdentityDeleteConfirm(String(J.panel_id??""),String(J.preset_id??""),Y));case"consult_identity_page":return v$(H.onConsultIdentityPage(String(J.panel_id??""),J.page,Y));case"consult_identity_back":return v$(H.onConsultIdentityBack(String(J.panel_id??""),Y))}return{toast:{type:"info",content:"unknown action"}}}async function mj($,Z,J){let Q=String($?.notify_id??""),Y=String($?.button_id??"");if(!Q)return{toast:{type:"error",content:"回调缺少 notify_id"}};let H=t9(Q);if(!H)return z(`notify-callback: notify_id=${Q.slice(0,12)}… not found (expired or pre-restart)`),{toast:{type:"error",content:"通知已过期或已移除"}};if(H.unknownAt)return D1(H,H$({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${H.unknownReason?`: ${H.unknownReason}`:""}`}},!0));if(H.resolvedAt)return D1(H,{toast:{type:"info",content:"已处理过"}});if(RH(Q))return D1(H,{toast:{type:"info",content:"处理中…"}});let X=H.buttons.find((G)=>G.id===Y);if(!X)return z(`notify-callback: notify_id=${Q.slice(0,12)}… unknown button_id="${Y}"`),D1(H,H$({toast:{type:"error",content:"未知按钮"}},!1));if(!H.callbackUrl){try{M3(H.notifyId,X.id,J)}catch(G){return D1(H,H$({toast:{type:"error",content:`保存反馈结果失败: ${G instanceof Error?G.message:G}`}},!1))}return z(`notify-callback: notify_id=${Q.slice(0,12)}… resolved button="${Y}" by=${J.slice(0,8)}… (no callback, pull/display)`),D1(H,{...f$(s9(H,{status:"done",buttonId:X.id,text:X.text,operatorOpenId:J}))})}OH(H.notifyId);let V=yX(uj(H,X,J));V.catch((G)=>{z(`notify-callback: notify_id=${H.notifyId.slice(0,12)}… phase-2 rejected: ${G instanceof Error?G.message:G}`)});let W=V.then((G)=>G==="retry"?"retry":"complete").catch(()=>"retry");return D1(H,{toast:{type:"info",content:`⏳ 已选择:${X.text} · 推送中…`},__cardActionCompletion:W})}async function uj($,Z,J){try{let Q=s9($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await W0($.messageId,Q)}catch(V){z(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${V instanceof Error?V.message:V}`)}let Y=await xH($,Z,J),H=Y.ok?"complete":"retry",X;if(Y.ok){let V=kH($.notifyId,Z.id,J);if(V.state==="complete")X={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Y.reply};else{H="unknown",X={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:V.detail},z(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${V.detail}`);try{await A1($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${V.detail}`)}catch(W){z(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${W instanceof Error?W.message:W}`)}}}else X={status:"failed",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:Y.detail};try{let V=s9($,X);await W0($.messageId,V)}catch(V){z(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${V instanceof Error?V.message:V}`);try{await A1($.chatId,`⚠️ 通知反馈${H==="retry"?"失败且结果卡更新失败,可重新点击":"已执行,但结果卡更新失败"}: ${V instanceof Error?V.message:V}`)}catch(W){z(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${W instanceof Error?W.message:W}`)}}return z(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${H==="complete"?"delivered":H==="unknown"?"unknown/non-retryable":`failed: ${Y.detail}`} by=${J.slice(0,8)}…`),H}finally{TH($.notifyId)}}function S3($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function pj(){if(process.platform==="win32"){z("debug: inject socket skipped on Windows (dev-only feature)");return}if(typeof Bun>"u"){z("debug: inject socket skipped (Bun runtime only — npm/Node build does not include it)");return}try{if(b3(f0))Q8(f0)}catch{}try{Bun.serve({unix:f0,fetch:async($)=>{if($.method!=="POST")return new Response("use POST",{status:405});if(f3)return new Response("daemon shutdown in progress",{status:503});let Z={};try{Z=await $.json()}catch{return new Response("bad json",{status:400})}if(!b3(Z4))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let J={};try{J=JSON.parse(Oj(Z4,"utf8"))}catch(V){return new Response(`ctx read failed: ${V}`,{status:500})}let Q=String(Z.text??"");if(!Q)return new Response("text required",{status:400});let Y=`【自动化测试】:${Q}`,H=await O(J.chat_id,Y);if(!H)return new Response("sendText failed — see daemon log",{status:502});let X={sender:{sender_id:{open_id:J.sender_open_id}},message:{message_id:H,chat_id:J.chat_id,message_type:"text",content:JSON.stringify({text:Q}),create_time:String(Date.now())}};if(z(`debug: inject text=${JSON.stringify(Q).slice(0,80)} msg_id=${H}`),!CX(X,"debug"))return new Response("daemon shutdown in progress",{status:503});return new Response(JSON.stringify({ok:!0,msg_id:H}),{headers:{"content-type":"application/json"}})}});try{Mj(f0,384)}catch{}z(`debug: inject socket listening at ${f0}`)}catch($){z(`debug: socket bind failed: ${$}`)}}async function lj(){z(`lodestar-daemon: pid ${process.pid} starting`);let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (e7(),oQ));$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (P$(),c5));Z(),F6(),M6(),R6(),T6(),k6(),await O2(),setInterval(()=>{O2()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (W3(),V3));try{await J()}catch(E){z(`tasklist deletion reconcile failed: ${E instanceof Error?E.message:E}`)}let Q,Y=Date.now(),H=0,X=!1,V=null,W=1500,G=90000,K=600000,_=3,B=null,j=0,L="",A=!1,P=(E)=>{z(`[ws] rebuild requested before WS init — ${E}`)},R=(E,u=0,p=!1)=>{let $$=Date.now()+u;if(B){if(A||=p,$$>=j){z(`[ws] rebuild already scheduled — ${E}`);return}clearTimeout(B)}j=$$,L=E,A=p,B=setTimeout(()=>{let o=L,P0=A;B=null,j=0,L="",A=!1,P(o,P0)},u)},D={error:(E)=>z(`[ws-sdk error] ${S3(E)}`),warn:(E)=>{let u=S3(E);if(z(`[ws-sdk warn] ${u}`),u.includes("no pong/inbound"))R("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Y<K)},info:(E)=>z(`[ws-sdk] ${S3(E)}`),debug:(E)=>{},trace:(E)=>{}},F=new Q2.EventDispatcher({}),N=()=>{if(Y=Date.now(),H=0,V)clearTimeout(V),V=null};F.register({"im.message.receive_v1":async(E)=>{if(N(),!CX(E))throw Error("daemon shutdown in progress")}}),F.register({"card.action.trigger":async(E)=>{return N(),gj(E)}});let C=()=>new Q2.WSClient({appId:b.feishu.app_id,appSecret:b.feishu.app_secret,loggerLevel:Q2.LoggerLevel.info,logger:D,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>z("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>m(),onError:(E)=>P(`SDK onError: ${E?.message??E}`)});P=(E,u=!1)=>{if(X){z(`[ws] rebuild skipped (already rebuilding) — ${E}`);return}if(B)clearTimeout(B),B=null,j=0;X=!0,H++,z(`[ws] rebuild #${H} (fresh WSClient) — ${E}`);let p=Q;try{p?.close({force:!0})}catch($$){z(`[ws] rebuild: old close failed: ${$$}`)}if(Q=C(),Q.start({eventDispatcher:F}).catch(($$)=>{z(`[ws] rebuild start failed: ${$$}`),R(`fresh client start failed: ${$$}`,W,u)}),X=!1,u)x()};let x=()=>{if(V)clearTimeout(V);let E=Date.now();V=setTimeout(()=>{if(V=null,Y>=E){H=0;return}if(H>=_){z(`[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"),H=0;return}P(`verify: no event ${Math.round((Date.now()-E)/1000)}s after rebuild`,!0)},G)},m=()=>{let E=Date.now()-Y<K;z("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${E})`),H=0,R("post-reconnect precaution",W,E)};Q=C(),Q.start({eventDispatcher:F}).catch((E)=>{z(`[ws] initial start failed: ${E}`),R(`initial start failed: ${E}`,W,!1)}),z(`lodestar-daemon: WS start requested, watching ${Y$.size} groups`);let I=15000,f=2,T=0;setInterval(()=>{let{state:E}=Q.getConnectionStatus();if(E==="connected"){T=0;return}if(E==="failed"||E==="idle"){T=0,P(`watchdog: state=${E}`);return}if(T++,z(`[ws] watchdog: state=${E} (${T}/${f})`),T>=f)T=0,P(`watchdog: stuck in '${E}' ~${Math.round(I*f/1000)}s`)},I),pj(),EH(),wH({bind:b.notify.bind,port:b.notify.port,extraHandler:(E,u,p)=>YX(E,u,p,{service:kX,authorize:($$)=>{for(let o of J2.values())if(o.acceptsConsultCapability($$))return o;return null}})}),_X(),gH(),VX(),await Cj()}var TX=!1,f3=!1,Z8=null,L1=0,w3=null,EX=15000,NX=()=>{if(TX)return;TX=!0;try{let $=w3??v3();if(R2($),$.length>0)z(`alive marker: [${$.join(", ")}]`)}catch($){z(`alive marker write failed: ${$}`)}try{Q8(E$)}catch{}try{Q8(f0)}catch{}},J2,kX,n2,o2,Nj,xX,kj,h3,bj=30000,Z2,Ij;var bX=k(()=>{FH();n();w$();R3();O3();O3();cH();sH();HX();WX();qX();N$();w();D$();q8();UX();OX();{let $=J4(E$);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(b3(E$))try{Q8(E$)}catch{}}Rj(Ej(E$),{recursive:!0});d3(E$);process.on("exit",NX);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",($)=>{z(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),Y2("unhandledRejection",1)});process.on("uncaughtException",($)=>{z(`uncaughtException: ${$.stack??$.message}`),Y2("uncaughtException",1)});J2=new Map,kX=new N3,n2=new Set,o2=new y3,Nj=new C3(30000),xX=new Set,kj=FX({actor:o2,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>wj($,Z)});h3=RX({registry:J2,createSession:($,Z)=>new B1($,Z,{onLifecycleChange:J8,onCreateTempSession:xj,onDisbandTempSession:yj,onCancelConsultRuns:(J,Q,Y)=>kX.cancelSessionRuns(J,Q,Y)}),ensureChatForSession:f6,disbandChatForSessionExact:h6,chatIdForSession:h1,clearSessionConversationState:S6,registerTempSessionLease:P6,hasTempSessionLease:U6,replaceTurnAnchors:C$,runExclusive:($,Z)=>o2.enqueue($,Z),log:z});Z2=new Set;Ij=PX({actor:o2,deduper:Nj,scope:($)=>{if(String($?.action?.value?.kind??"").startsWith("consult_identity_"))return"__consult_identities_global__";return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:cj,present:vj,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");z(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await hj($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");z(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await A1(String($?.context?.open_chat_id??""),`⚠️ ${Y8(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:($)=>{yX($)},onBackgroundError:($)=>{z(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${Y8(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}})}});lj().catch(($)=>{z(`boot fatal: ${$}`),Y2("boot fatal",1)})});D$();q8();import{existsSync as wX,unlinkSync as ij}from"node:fs";var i$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function nj(){if(!wX(L$)){if(process.stdin.isTTY){console.log(),console.log(`${i$.bold}${i$.yellow}Lodestar: 未找到配置, 启动安装向导...${i$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (Z5(),$5));await Z();return}console.error(`${i$.red}Lodestar: 未找到配置 ${L$}${i$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${i$.green}lodestar-setup${i$.reset} 完成首次配置 (或直接运行 ${i$.green}lodestar-daemon${i$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=J4(E$);if($.state==="exit")console.error(`${i$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${i$.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(` • 误判 / 已经死了: 手删 ${E$} 后再跑`),process.exit(1);if(wX(E$))try{ij(E$)}catch{}await Promise.resolve().then(() => (bX(),dj))}nj().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});