@evandu/super-pi 0.1.2 → 0.1.3

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.
@@ -40,4 +40,4 @@ pi list
40
40
  pi update npm:@evandu/super-pi
41
41
 
42
42
  # 独立启动(无需 Pi 环境)
43
- npx @evandu/super-pi`})})]}),(0,j.jsxs)(`div`,{className:`help-card`,children:[(0,j.jsx)(`h4`,{children:`🎯 键盘快捷键`}),(0,j.jsxs)(`div`,{className:`help-command-table`,children:[(0,j.jsxs)(`div`,{className:`cmd-row`,children:[(0,j.jsx)(`code`,{children:`Enter`}),(0,j.jsx)(`span`,{children:`发送对话消息`})]}),(0,j.jsxs)(`div`,{className:`cmd-row`,children:[(0,j.jsx)(`code`,{children:`Shift + Enter`}),(0,j.jsx)(`span`,{children:`输入框内换行`})]}),(0,j.jsxs)(`div`,{className:`cmd-row`,children:[(0,j.jsx)(`code`,{children:`Esc`}),(0,j.jsx)(`span`,{children:`快速关闭当前顶层弹窗(使用指南、设置、工作区选择器等)`})]})]})]})]})}function ht(){return(0,j.jsx)(`div`,{className:`help-section-group`,children:(0,j.jsxs)(`div`,{className:`help-card`,children:[(0,j.jsx)(`h4`,{children:`🎨 4 款内置专业高对比度主题`}),(0,j.jsxs)(`div`,{className:`help-theme-list`,children:[(0,j.jsxs)(`div`,{className:`help-theme-item`,children:[(0,j.jsx)(`strong`,{children:`🌙 Midnight(午夜冷蓝)`}),(0,j.jsx)(`p`,{children:`深邃冷调分层界面,对比度鲜明,非常适合长时间夜间专注编程。`})]}),(0,j.jsxs)(`div`,{className:`help-theme-item`,children:[(0,j.jsx)(`strong`,{children:`⬛ Slate(中性石墨)`}),(0,j.jsx)(`p`,{children:`经典低饱和中性灰度质感,克制沉稳,专业工程界面的默认首选。`})]}),(0,j.jsxs)(`div`,{className:`help-theme-item`,children:[(0,j.jsx)(`strong`,{children:`🌊 Ocean(深海冷灰)`}),(0,j.jsx)(`p`,{children:`冷调浅蓝灰阶设计,边界轮廓清晰分明,视觉感受轻盈柔和。`})]}),(0,j.jsxs)(`div`,{className:`help-theme-item`,children:[(0,j.jsx)(`strong`,{children:`☀️ Dawn(破晓暖色)`}),(0,j.jsx)(`p`,{children:`清爽明亮浅色主题,适合白天自然光线充足环境下的阅读与工作。`})]})]}),(0,j.jsxs)(`p`,{className:`help-hint`,children:[`可在左侧栏底部的 `,(0,j.jsx)(`strong`,{children:`⚙ 设置`}),` 中一键切换主题,设置会自动持久化保存在本地。`]})]})})}var gt=`super-pi.theme`,_t=[{id:`midnight`,name:`午夜`,blurb:`冷暗调鸭的分层画面,适合长时间。`},{id:`slate`,name:`石板`,blurb:`低饱和的冷调,对视觉负荷最少。`},{id:`ocean`,name:`晴空`,blurb:`浅色的界面清澈,适合天天明亮的环境。`},{id:`dawn`,name:`黎明`,blurb:`温暖低调的纸感柔和,适合大量阅读文档。`}],vt=`midnight`,yt=e=>typeof e==`string`&&_t.some(t=>t.id===e);function bt(){try{let e=window.localStorage.getItem(gt);if(!e)return vt;let t=JSON.parse(e),n=typeof t==`string`?t:t?.id;return yt(n)?n:vt}catch{return vt}}function xt(e){document.documentElement.setAttribute(`data-theme`,e);try{window.localStorage.setItem(gt,JSON.stringify({id:e,version:1}))}catch{}}function St(){let[e,t]=(0,l.useState)(vt);return(0,l.useEffect)(()=>{t(bt());let e=e=>{if(e.key===`super-pi.theme`&&e.newValue)try{let n=JSON.parse(e.newValue),r=typeof n==`string`?n:n?.id;yt(r)&&(document.documentElement.setAttribute(`data-theme`,r),t(r))}catch{}};return window.addEventListener(`storage`,e),()=>window.removeEventListener(`storage`,e)},[]),{theme:e,setTheme:(0,l.useCallback)(e=>{xt(e),t(e)},[])}}function Ct({theme:e,onChooseTheme:t,onClose:n}){let r=_t.find(t=>t.id===e);return(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`div`,{className:`settings-scope`,children:`主题只影响这台设备的显示,不改变任何内容;切换立即生效。`}),_t.length===0?(0,j.jsx)(`div`,{className:`theme-empty`,"data-theme-empty":`1`,children:`没有可用的主题。界面将继续使用默认配色,你可以在主题文件恢复后重试。`}):(0,j.jsx)(`div`,{className:`theme-options`,role:`radiogroup`,"aria-label":`主题`,children:_t.map(n=>{let r=n.id===e;return(0,j.jsxs)(`button`,{type:`button`,className:`theme-option`,role:`radio`,"aria-checked":r,"aria-pressed":r,"data-theme-option":n.id,"data-theme-current":r?`1`:`0`,onClick:()=>t(n.id),children:[(0,j.jsxs)(`span`,{className:`theme-preview`,"data-preview":n.id,"aria-hidden":`true`,children:[(0,j.jsx)(`span`,{className:`theme-preview-rail`}),(0,j.jsxs)(`span`,{className:`theme-preview-body`,children:[(0,j.jsx)(`span`,{className:`theme-preview-line`}),(0,j.jsx)(`span`,{className:`theme-preview-line dim`}),(0,j.jsx)(`span`,{className:`theme-preview-line accent`}),(0,j.jsx)(`span`,{className:`theme-preview-panel`})]})]}),(0,j.jsxs)(`span`,{className:`theme-option-name`,children:[n.name,(0,j.jsx)(`small`,{children:n.id}),r&&(0,j.jsx)(`span`,{className:`theme-option-current`,children:`当前 ✓`})]}),(0,j.jsx)(`span`,{className:`theme-option-blurb`,children:n.blurb})]},n.id)})}),(0,j.jsx)(`div`,{className:`picker-actions`,children:(0,j.jsx)(`button`,{type:`button`,className:`picker-cancel`,"data-theme-close":`1`,onClick:n,children:`完成`})}),(0,j.jsxs)(`div`,{className:`settings-scope theme-current-line`,children:[`当前:`,r?`${r.name}(${r.id})`:`默认`]})]})}var wt=[{id:`appearance`,label:`外观`,render:Ct}],Tt=wt[0]?.id;function Et({theme:e,onChooseTheme:t,onClose:n}){let[r,i]=(0,l.useState)(Tt);(0,l.useEffect)(()=>{let e=e=>{e.key===`Escape`&&!e.defaultPrevented&&n()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[n]);let a=wt.find(e=>e.id===r)??wt[0];return(0,j.jsx)(`div`,{className:`overlay`,onClick:n,children:(0,j.jsxs)(`div`,{className:`picker settings-window`,"data-theme-dialog":`1`,"data-settings-window":`1`,onClick:e=>e.stopPropagation(),children:[(0,j.jsx)(`div`,{className:`settings-window-head`,children:(0,j.jsx)(`h2`,{children:`设置`})}),(0,j.jsxs)(`div`,{className:`settings-window-body`,children:[(0,j.jsxs)(`nav`,{className:`settings-nav`,role:`tablist`,"aria-orientation":`vertical`,"aria-label":`设置分类`,"data-settings-nav":`1`,children:[(0,j.jsx)(`div`,{className:`settings-nav-label`,children:`分类`}),wt.map(e=>(0,j.jsx)(`button`,{type:`button`,id:`settings-tab-${e.id}`,className:`settings-category`,role:`tab`,"aria-selected":e.id===a?.id,"aria-controls":`settings-panel`,tabIndex:e.id===a?.id?0:-1,"data-settings-category":e.id,onClick:()=>i(e.id),children:e.label},e.id))]}),a&&(0,j.jsxs)(`div`,{className:`settings-panel`,id:`settings-panel`,role:`tabpanel`,"aria-labelledby":`settings-tab-${a.id}`,"data-settings-panel":a.id,children:[(0,j.jsx)(`h3`,{className:`settings-panel-title`,"data-settings-panel-title":a.id,children:a.label}),a.render({theme:e,onChooseTheme:t,onClose:n})]})]})]})})}var Dt=[{kind:`calculator`,name:`计算器`,glyph:`∑`,blurb:`算术表达式,四则运算与乘方。除零会明确报错。`},{kind:`timestamp`,name:`时间戳`,glyph:`◷`,blurb:`Unix 时间戳与日期互转,本地计算,不联网。`}],Ot=[{id:`preset_calculator`,kind:`calculator`,name:`计算器`,glyph:`∑`}],kt=40,At=2048,jt=`super-pi:tools:v1`;function Mt(e){return typeof e==`string`?e.replace(/\s+/g,` `).trim().slice(0,kt):``}function Nt(e){let t=e.trim();if(!t)return{ok:!1,reason:`请填写网址。`};if(t.length>At)return{ok:!1,reason:`网址太长了,请控制在 ${At} 个字符以内。`};let n=h(t);return n?{ok:!0,url:n}:{ok:!1,reason:`这个网址不是允许的协议。只支持 http / https / mailto 开头的网址。`}}function Pt(e){if(!e)return[];let t;try{t=JSON.parse(e)}catch{return[]}if(!Array.isArray(t))return[];let n=[],r=new Set;for(let e of t){if(typeof e!=`object`||!e)continue;let t=e,i=t.kind;if(typeof i!=`string`||i!==`calculator`&&i!==`timestamp`&&i!==`link`)continue;let a=Mt(t.name);if(!a)continue;let o=typeof t.glyph==`string`&&t.glyph.trim()?t.glyph.trim().slice(0,4):``;if(!o)continue;let s=typeof t.id==`string`&&t.id.trim()?t.id.trim().slice(0,64):``;if(s&&!r.has(s)){if(i===`link`){let e=h(typeof t.url==`string`?t.url:``);if(!e)continue;r.add(s),n.push({id:s,kind:`link`,name:a,glyph:o,url:e})}else if(r.add(s),n.push({id:s,kind:i,name:a,glyph:o}),n.length>=32)break}}return n}function Ft(e){return JSON.stringify(e.map(e=>e.kind===`link`?{...e}:{id:e.id,kind:e.kind,name:e.name,glyph:e.glyph}))}function It(e,t){let n=e===`link`?`link`:`preset_${e}`,r=typeof globalThis<`u`?globalThis.crypto:void 0,i=typeof r?.randomUUID==`function`?r.randomUUID().slice(0,8):``;i||=Math.random().toString(36).slice(2,10);let a=`${n}_${i}`,o=1;for(;t.includes(a);)a=`${n}_${i}_${o}`,o+=1;return a}function Lt(e,t){if(e.some(e=>e.kind===t))return e.slice();let n=Dt.find(e=>e.kind===t);return n?[...e,{id:It(t,e.map(e=>e.id)),kind:t,name:n.name,glyph:n.glyph}]:e.slice()}function Rt(e,t){return e.filter(e=>e.id!==t)}var zt=e=>({ok:!1,reason:e}),Bt=`除数不能为 0:除以零没有结果,请换一个非零的除数。`,Vt=new Set([`/`,`%`]),Ht=e=>e!==void 0&&e>=`0`&&e<=`9`,Ut=e=>e!==void 0&&/\s/.test(e);function Wt(e){for(;Ut(e.source[e.at]);)e.at+=1}function Gt(e){let t=e.at,n=0;for(;Ht(e.source[e.at]);)e.at+=1,n+=1;if(e.source[e.at]===`.`)for(e.at+=1;Ht(e.source[e.at]);)e.at+=1,n+=1;if(!n)return e.at=t,zt(`「${e.source[t]}」不是有效的数字。`);let r=Number(e.source.slice(t,e.at));return Number.isFinite(r)?{ok:!0,value:r}:zt(`数字太长了,无法表示。`)}function Kt(e){Wt(e);let t=e.source[e.at];if(t===void 0)return zt(`算式不完整:末尾还缺一个数字或右括号。`);if(t===`(`){e.at+=1;let t=Yt(e);return t.ok?(Wt(e),e.source[e.at]===`)`?(e.at+=1,t):zt(`括号不匹配:少了一个右括号「)」。`)):t}return Ht(t)||t===`.`?Gt(e):zt(`无法识别的字符「${t}」。`)}function qt(e){let t=Kt(e);if(!t.ok||(Wt(e),e.source[e.at]!==`^`))return t;e.at+=1;let n=L(e);if(!n.ok)return n;let r=t.value**n.value;return Number.isFinite(r)?{ok:!0,value:r}:zt(`结果超出了可计算的数值范围。`)}function L(e){Wt(e);let t=e.source[e.at];if(t!==`+`&&t!==`-`)return qt(e);e.at+=1;let n=L(e);if(!n.ok)return n;let r=t===`-`?-n.value:n.value;return Number.isFinite(r)?{ok:!0,value:r}:zt(`结果超出了可计算的数值范围。`)}function Jt(e){let t=L(e);if(!t.ok)return t;for(;;){Wt(e);let n=e.source[e.at];if(n!==`*`&&!Vt.has(n))return t;e.at+=1;let r=L(e);if(!r.ok)return r;if(Vt.has(n)&&r.value===0)return zt(Bt);let i=n===`*`?t.value*r.value:n===`%`?t.value%r.value:t.value/r.value;if(!Number.isFinite(i))return zt(`结果超出了可计算的数值范围。`);t={ok:!0,value:i}}}function Yt(e){let t=Jt(e);if(!t.ok)return t;for(;;){Wt(e);let n=e.source[e.at];if(n!==`+`&&n!==`-`)return t;e.at+=1;let r=Jt(e);if(!r.ok)return r;let i=n===`+`?t.value+r.value:t.value-r.value;if(!Number.isFinite(i))return zt(`结果超出了可计算的数值范围。`);t={ok:!0,value:i}}}function Xt(e){let t=e.trim();if(!t)return zt(`请输入算式。`);if(t.length>200)return zt(`算式太长了,请控制在 200 个字符以内。`);let n={source:t,at:0},r=Yt(n);return r.ok?(Wt(n),n.at===t.length?Number.isFinite(r.value)?r:zt(`结果不是有限数字。`):zt(`「${t[n.at]}」后面的内容无法识别,请检查是否漏了运算符。`)):r}function Zt(e){return String(!Number.isFinite(e)||Number.isInteger(e)&&Math.abs(e)<1e21?e:Number(e.toPrecision(12)))}function Qt(e){let t=e.trim();if(!t)return{ok:!1,reason:`请输入时间戳或日期。`};if(/^\d+$/.test(t)){let e=Number(t);if(!Number.isFinite(e))return{ok:!1,reason:`这个数字太大,无法表示。`};let n=t.length<=11?e*1e3:e;return!Number.isFinite(n)||Math.abs(n)>864e13?{ok:!1,reason:`这个时间戳超出了日期能表示的范围。`}:{ok:!0,ms:n}}let n=Date.parse(t);return Number.isNaN(n)?{ok:!1,reason:`看不懂这个日期。试试 1757000000、2026-10-08 或 2026-10-08T09:00:00。`}:{ok:!0,ms:n}}var $t=e=>String(Math.abs(e)).padStart(2,`0`);function en(e){let t=new Date(e);return Number.isNaN(t.getTime())?null:{local:`${t.getFullYear()}-${$t(t.getMonth()+1)}-${$t(t.getDate())} ${$t(t.getHours())}:${$t(t.getMinutes())}:${$t(t.getSeconds())}`,iso:t.toISOString(),seconds:String(Math.floor(e/1e3)),milliseconds:String(e)}}var tn={workspaces:[],conversations:[],subagentRuns:[],queuedMessages:[]},nn=e=>{if(typeof e!=`string`||e.length===0)return``;let t=new Date(e);return Number.isNaN(t.getTime())?``:new Intl.DateTimeFormat(`zh-CN`,{hour:`2-digit`,minute:`2-digit`}).format(t)},rn=6e4,an=60*rn,on=24*an,sn=7*on,cn=30*on,ln=365*on,un=(e,t)=>{let n=new Date(e);if(Number.isNaN(n.getTime()))return``;let r=t-n.getTime();return r<3e4?`now`:r<an?`${Math.max(1,Math.floor(r/rn))}m ago`:r<on?`${Math.floor(r/an)}h ago`:r<sn?`${Math.floor(r/on)}d ago`:r<cn?`${Math.floor(r/sn)}w ago`:r<ln?`${Math.floor(r/cn)}mo ago`:`${Math.floor(r/ln)}y ago`},dn=(e,t)=>e.updatedAt<t.updatedAt?1:e.updatedAt>t.updatedAt?-1:0,fn=(e,t)=>{let n=e.archivedAt??``,r=t.archivedAt??``;return n<r?1:n>r?-1:0},pn=e=>{if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?``:`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`},mn=1e3,hn=3e4,gn=async e=>{try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}let t=document.createElement(`textarea`);t.value=e,t.setAttribute(`readonly`,``),t.style.cssText=`position:fixed;top:0;left:0;width:1px;height:1px;padding:0;border:0;opacity:0;pointer-events:none`,document.body.appendChild(t);try{return t.select(),t.setSelectionRange(0,t.value.length),document.execCommand(`copy`)}catch{return!1}finally{t.remove()}},_n={model:`模型`,thinking:`思考`,agent:`智能体`,subagent:`子智能体`},vn={model:`模型`,thinking:`思考等级`,agent:`智能体`,subagent:`子智能体`},yn={model:`选择模型`,thinking:`选择思考等级`,agent:`选择智能体`,subagent:`选择子智能体`},bn=`图文`,xn=e=>e.imageInput?bn:void 0,Sn=e=>e.normalize(`NFKD`).replace(/\p{M}/gu,``).toLowerCase(),Cn=(e,t)=>{let n=Sn(t.trim());return n?e.filter(e=>Sn(`${e.label} ${e.detail??``} ${e.badge??``}`).includes(n)):e};function wn({onClose:e,onCreate:t}){let[n,r]=(0,l.useState)(),[i,a]=(0,l.useState)(!0),[o,s]=(0,l.useState)(),[c,u]=(0,l.useState)(``),d=async e=>{a(!0),s(void 0);try{let t=await fetch(`/api/fs/dirs${e?`?path=${encodeURIComponent(e)}`:``}`),n=await t.json();if(!t.ok)throw Error(n.error??`HTTP ${t.status}`);r(n),u(n.suggestedName)}catch(e){s(e instanceof Error?e.message:`目录加载失败`)}finally{a(!1)}};return(0,l.useEffect)(()=>{d()},[]),(0,l.useEffect)(()=>{let t=t=>{t.key===`Escape`&&e()};return window.addEventListener(`keydown`,t),()=>window.removeEventListener(`keydown`,t)},[e]),(0,j.jsx)(`div`,{className:`overlay`,onClick:e,children:(0,j.jsxs)(`div`,{className:`picker`,onClick:e=>e.stopPropagation(),children:[(0,j.jsx)(`h2`,{children:`选择工作区目录`}),(0,j.jsx)(`div`,{className:`picker-path`,children:n?.path??(i?`加载中…`:`—`)}),(0,j.jsxs)(`div`,{className:`picker-list`,children:[i&&(0,j.jsx)(`div`,{className:`picker-status`,children:`加载中…`}),!i&&o&&(0,j.jsxs)(`div`,{className:`picker-error`,children:[o,(0,j.jsx)(`button`,{onClick:()=>void d(n?.path),children:`重试`})]}),!i&&!o&&n?.parent&&(0,j.jsx)(`button`,{className:`picker-dir`,onClick:()=>void d(n.parent??void 0),children:`📁 ..`}),!i&&!o&&n?.entries.map(e=>(0,j.jsxs)(`button`,{className:`picker-dir`,onClick:()=>void d(e.path),children:[`📁 `,e.name]},e.path)),!i&&!o&&n&&n.entries.length===0&&(0,j.jsx)(`div`,{className:`picker-status`,children:`此目录下没有子目录`}),!i&&!o&&n?.truncated&&(0,j.jsx)(`div`,{className:`picker-status`,children:`目录过多,仅显示前 2000 项`})]}),(0,j.jsxs)(`label`,{className:`picker-name`,children:[`名称`,(0,j.jsx)(`input`,{value:c,onChange:e=>u(e.target.value),placeholder:`工作区名称`})]}),(0,j.jsxs)(`div`,{className:`picker-actions`,children:[(0,j.jsx)(`button`,{className:`picker-cancel`,onClick:e,children:`取消`}),(0,j.jsx)(`button`,{className:`picker-ok`,disabled:!c.trim()||i||!!o||!n,onClick:()=>n&&t(c.trim(),n.path),children:`使用这个目录`})]})]})})}var Tn={timeout:`扩展提问超时,已取消`,aborted:`运行已停止,扩展提问已取消`,expired:`运行已结束,扩展提问已取消`},En=10;function Dn(e,t){if(!t)return`正在从 Pi 读取${e}列表…`;if(t.source!==`pi`)return`读取 Pi ${e}列表失败:${t.error??`未知原因`}`}function On(e){if(!e)return`正在读取 agent 列表…`;if(e.source!==`directory`)return`读取 agent 列表失败:${e.error??`未知原因`}`;if(e.problems.length)return`${e.problems.length} 个 agent 文件无法使用:${e.problems.map(e=>e.file).join(`、`)}`;if(!e.agents.length)return`${e.directory} 下没有 primary agent`}var kn=e=>Math.abs(e)<1e3?String(e):`${(e/1e3).toFixed(1).replace(/\.0$/,``)}k`;function An(e){if(e===void 0||!Number.isFinite(e))return``;let t=Math.max(0,e);return t<1e3?`${Math.round(t)}ms`:t<6e4?`${(t/1e3).toFixed(1)}s`:`${Math.floor(t/6e4)}分${Math.round(t%6e4/1e3)}秒`}var jn={dispatch:`派发时(子进程还没起来)`,prompt:`派活时(Pi 拒收了任务)`,turn:`生成回答时`,tool:`调用工具时`,settle:`收尾时`};function Mn({call:e,index:t,expanded:n,onToggle:r}){let i=e.args??[];return(0,j.jsxs)(`div`,{className:`call-block call-block-${e.status??`running`}`,"data-call-block":t,"data-call-tool":e.label,"data-call-detail":e.detail??void 0,"data-call-status":e.status??`running`,"data-call-expanded":n?`true`:`false`,"data-call-arg-count":i.length,children:[(0,j.jsx)(`button`,{type:`button`,className:`call-fold-edge`,"data-call-fold-edge":t,"aria-expanded":n,"aria-label":`${n?`折叠`:`展开`} ${e.label} 调用`,title:n?`折叠这次调用`:`展开这次调用`,onClick:r}),(0,j.jsxs)(`div`,{className:`call-head-row`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`call-head`,"data-call-head":t,"aria-expanded":n,onClick:r,children:[(0,j.jsx)(`span`,{className:`call-chevron`,"aria-hidden":`true`,children:n?`▾`:`▸`}),(0,j.jsx)(`span`,{className:`call-glyph`,"aria-hidden":`true`,children:e.status===`error`?`✕`:e.status===`ok`?`✓`:`·`}),(0,j.jsx)(`span`,{className:`call-label`,children:e.label}),e.detail&&(0,j.jsx)(`span`,{className:`call-detail`,title:e.detail,children:e.detail}),e.durationMs!==void 0&&(0,j.jsx)(`span`,{className:`call-duration`,children:An(e.durationMs)})]}),n&&(0,j.jsx)(`button`,{type:`button`,className:`call-fold-top`,"data-call-fold-top":t,onClick:r,children:`收起`})]}),n&&(0,j.jsx)(`div`,{className:`call-args`,"data-call-args":i.length,children:i.length===0?(0,j.jsx)(`div`,{className:`call-arg call-arg-empty`,"data-call-arg-empty":t,children:`(这次调用没有可显示的参数)`}):i.map(e=>(0,j.jsxs)(`div`,{className:`call-arg`,"data-call-arg":e.key,"data-call-arg-value":e.value,children:[(0,j.jsx)(`span`,{className:`call-arg-key`,children:e.key}),(0,j.jsx)(`span`,{className:`call-arg-value`,title:e.value,children:e.value})]},e.key))})]})}function Nn({run:e,name:t,expanded:n,onToggle:r,onStop:i}){let a=e.toolCalls??[],o=n?a:a.slice(-10),s=a.length-o.length,c=e.status===`running`,u=e.output??``,d=e.dispatchedBy===`model`,[f,p]=(0,l.useState)(0);(0,l.useEffect)(()=>{if(!c)return;p(Date.now());let e=window.setInterval(()=>p(Date.now()),200);return()=>window.clearInterval(e)},[c,e.startedAt]);let m=Date.parse(e.startedAt),h=c&&f>0&&Number.isFinite(m)?f-m:void 0,g=[...a].reverse().find(e=>e.status===void 0)?.label;return(0,j.jsxs)(`article`,{className:`subagent-card subagent-${e.status}${d?` subagent-by-model`:``}`,"data-subagent-card":e.id,"data-subagent-status":e.status,"data-subagent-agent":e.agentId,"data-subagent-tools":a.length,"data-subagent-dispatched-by":d?`model`:`human`,children:[(0,j.jsxs)(`div`,{className:`subagent-head`,children:[(0,j.jsx)(`span`,{className:`subagent-badge`,children:`子智能体`}),d&&(0,j.jsxs)(`span`,{className:`subagent-source`,"data-subagent-source":`model`,title:`primary 模型自己决定派这个子智能体去干活`,children:[(0,j.jsx)(`span`,{className:`subagent-source-glyph`,"aria-hidden":`true`,children:`⚡`}),`模型自主派发`]}),(0,j.jsx)(`strong`,{className:`subagent-name`,"data-subagent-name":`1`,children:t||e.agentId}),(0,j.jsx)(`span`,{className:`subagent-status`,"data-subagent-status-text":`1`,children:c?`运行中`:e.status===`completed`?`已完成`:e.status===`stopped`?`已停止`:`失败`}),c?h!==void 0&&(0,j.jsxs)(`span`,{className:`subagent-clock`,"data-subagent-elapsed":`1`,"data-subagent-elapsed-ms":h,children:[`已运行 `,An(h)]}):e.durationMs!==void 0&&(0,j.jsxs)(`span`,{className:`subagent-duration`,"data-subagent-duration":`1`,"data-subagent-duration-ms":e.durationMs,children:[`用时 `,An(e.durationMs)]}),c&&(0,j.jsx)(`button`,{type:`button`,className:`subagent-stop`,"data-subagent-stop":e.id,onClick:i,children:`停止`})]}),c&&e.activity&&(0,j.jsxs)(`div`,{className:`subagent-activity`,"data-subagent-activity":e.activity.kind,"data-subagent-activity-at":e.activity.at,children:[(0,j.jsx)(`span`,{className:`subagent-activity-dot`,"aria-hidden":`true`}),e.activity.kind===`tool`?`正在调用 ${e.activity.label??`工具`}`:`正在思考…`]}),(0,j.jsxs)(`div`,{className:`subagent-task`,"data-subagent-task":`1`,children:[d&&(0,j.jsx)(`span`,{className:`subagent-task-source`,"data-subagent-model-task":`1`,children:`模型给的任务`}),e.task]}),(0,j.jsx)(`div`,{className:`subagent-output`,"data-subagent-output":`1`,"data-live-length":u.length,children:u||(c?`…`:e.outputTruncated?`(已按 50 KB 上限截断,浏览器仍收到完整内容)`:`(没有输出)`)}),e.failure&&(0,j.jsxs)(`div`,{className:`subagent-failure`,"data-subagent-failure":`1`,"data-subagent-failure-stage":e.failure.stage,children:[(0,j.jsx)(`span`,{className:`subagent-failure-label`,children:`卡在`}),(0,j.jsx)(`span`,{className:`subagent-failure-stage`,"data-subagent-failure-text":`1`,children:jn[e.failure.stage]}),e.failure.stage===`tool`&&g&&(0,j.jsxs)(`span`,{className:`subagent-failure-tool`,"data-subagent-failure-tool":`1`,children:[`· 正在跑 `,g]}),a.length>0&&(0,j.jsxs)(`span`,{className:`subagent-failure-progress`,children:[`· 死前已尝试 `,a.length,` 次工具调用`]})]}),e.error&&(0,j.jsx)(`div`,{className:`subagent-error`,"data-subagent-error":`1`,children:e.error}),a.length>0&&(0,j.jsxs)(`div`,{className:`subagent-tools`,"data-subagent-tool-count":a.length,children:[s>0&&!n&&(0,j.jsxs)(`button`,{type:`button`,className:`subagent-more`,"data-subagent-hidden":s,onClick:r,children:[`… 另有 `,s,` 条工具调用`]}),o.map((e,t)=>(0,j.jsxs)(`div`,{className:`subagent-tool${e.status?` subagent-tool-${e.status}`:``}`,"data-subagent-tool":e.label,"data-subagent-tool-detail":e.detail??void 0,"data-subagent-tool-status":e.status??`running`,children:[(0,j.jsx)(`span`,{className:`subagent-tool-glyph`,"aria-hidden":`true`,children:e.status===`error`?`✕`:e.status===`ok`?`✓`:`·`}),(0,j.jsx)(`span`,{className:`subagent-tool-label`,children:e.label}),e.detail&&(0,j.jsx)(`span`,{className:`subagent-tool-detail`,title:e.detail,children:e.detail}),e.durationMs!==void 0&&(0,j.jsx)(`span`,{className:`subagent-tool-duration`,children:An(e.durationMs)})]},`${t}:${e.label}`))]}),e.usage&&(0,j.jsxs)(`div`,{className:`subagent-usage`,"data-subagent-usage":`1`,"data-subagent-turns":e.usage.turns,children:[(0,j.jsxs)(`span`,{children:[e.usage.turns,` turns`]}),(0,j.jsxs)(`span`,{children:[`↑`,kn(e.usage.input)]}),(0,j.jsxs)(`span`,{children:[`↓`,kn(e.usage.output)]}),e.usage.cacheRead>0&&(0,j.jsxs)(`span`,{children:[`cache↓`,kn(e.usage.cacheRead)]}),e.usage.cacheWrite>0&&(0,j.jsxs)(`span`,{children:[`cache↑`,kn(e.usage.cacheWrite)]}),e.usage.cost>0&&(0,j.jsxs)(`span`,{children:[`$`,e.usage.cost.toFixed(4)]})]}),a.length>10&&(0,j.jsx)(`button`,{type:`button`,className:`subagent-collapse`,"data-subagent-collapse":e.id,"aria-expanded":n,onClick:r,children:n?`收起`:`展开全部 ${a.length} 条`})]})}function Pn({items:e,pi:t,running:n,onCancel:r,onSteer:i}){let[a,o]=(0,l.useState)(!1);if(!e.length)return null;let s=e.filter(e=>e.state===`sending`);return(0,j.jsxs)(`section`,{className:`queue-dock`,"data-queue-dock":`1`,"data-queue-count":e.length,"data-queue-sending":s.length,"aria-label":`排队等待发送的消息`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`queue-dock-head`,"data-queue-collapse":`1`,"aria-expanded":!a,onClick:()=>o(e=>!e),children:[(0,j.jsx)(`span`,{className:`chevron`,children:a?`▸`:`▾`}),(0,j.jsxs)(`strong`,{children:[e.length,` 条待发送`]}),s.length>0&&(0,j.jsxs)(`span`,{className:`queue-dock-badge`,"data-queue-badge":`sending`,children:[s.length,` 条已交给 Agent`]}),a&&(0,j.jsx)(`span`,{className:`queue-dock-preview`,children:e[0].content})]}),!a&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`p`,{className:`queue-dock-note`,"data-queue-note":`steer`,children:[n?`「插队」= 当前这一批工具调用跑完就插进来,不用等整个任务结束;正在跑单个长工具时无法打断。`:`当前没有正在运行的这一轮,「插队」会等下一轮开始时发出。`,t&&t.steering.length>0&&` Pi 手上还有 ${t.steering.length} 条插队消息在等下一个工具调用边界。`]}),(0,j.jsx)(`ul`,{className:`queue-dock-list`,children:e.map((e,t)=>{let a=e.state===`sending`,o=e.content||(e.images?.length?`【图片】(${e.images.length})`:``);return(0,j.jsxs)(`li`,{className:`queue-row ${a?`queue-row-sending`:`queue-row-queued`}`,"data-queue-id":e.id,"data-queue-state":e.state,children:[(0,j.jsx)(`span`,{className:`queue-index`,"aria-hidden":`true`,children:t+1}),(0,j.jsx)(`span`,{className:`queue-text`,title:o,children:o}),(0,j.jsx)(`span`,{className:`queue-state`,"data-queue-state-label":a?`sending`:`queued`,children:a?`投递中…`:`待发送`}),a?(0,j.jsx)(`span`,{className:`queue-locked`,"data-queue-locked":e.id,children:`已交给 Agent,取消不掉`}):(0,j.jsxs)(j.Fragment,{children:[n?(0,j.jsx)(`button`,{type:`button`,className:`queue-steer`,"data-queue-steer":e.id,title:`插队:当前这一批工具调用跑完后插入,不用等整个任务结束`,"aria-label":`把「${o}」插队发送:当前这一批工具调用跑完后插入`,onClick:()=>i(e.id),children:`插队`}):(0,j.jsx)(`span`,{className:`queue-steer-idle`,"data-queue-steer-idle":e.id,title:`没有正在运行的这一轮,现在无法插队`,children:`未运行,暂不能插队`}),(0,j.jsx)(`button`,{type:`button`,className:`queue-cancel`,"data-queue-cancel":e.id,title:`取消这条排队消息,它不会被发出`,"aria-label":`取消排队消息「${o}」`,onClick:()=>r(e.id),children:`取消`})]})]},e.id)})})]})]})}function Fn({request:e,onAnswer:t}){let[n,r]=(0,l.useState)(e.prefill??``),i=e.method===`input`||e.method===`editor`,a=(0,j.jsx)(`button`,{type:`button`,className:`extui-cancel`,onClick:()=>t({cancelled:!0}),children:`取消提问`});return(0,j.jsxs)(`article`,{className:`extui-card extui-${e.method}`,"data-request-id":e.requestId,"data-method":e.method,children:[(0,j.jsxs)(`div`,{className:`extui-head`,children:[(0,j.jsx)(`span`,{className:`extui-badge`,children:`扩展提问`}),e.timeoutMs!==void 0&&(0,j.jsxs)(`span`,{className:`extui-deadline`,children:[Math.round(e.timeoutMs/1e3),`s 超时`]})]}),(0,j.jsx)(`h3`,{className:`extui-title`,children:e.title||e.method}),e.method===`confirm`&&(0,j.jsx)(`p`,{className:`extui-body`,children:e.message}),e.method===`select`&&(0,j.jsxs)(`div`,{className:`extui-options`,children:[(e.options??[]).map(e=>(0,j.jsx)(`button`,{type:`button`,className:`extui-option`,onClick:()=>t({value:e}),children:e},e)),(e.options??[]).length===0&&(0,j.jsx)(`p`,{className:`extui-body`,children:`扩展没有提供任何选项`})]}),i&&(0,j.jsxs)(`form`,{className:`extui-form`,onSubmit:e=>{e.preventDefault(),n.trim()&&t({value:n})},children:[e.method===`input`?(0,j.jsx)(`input`,{className:`extui-field`,value:n,onChange:e=>r(e.target.value),placeholder:e.placeholder??``}):(0,j.jsx)(`textarea`,{className:`extui-field`,value:n,onChange:e=>r(e.target.value)}),(0,j.jsxs)(`div`,{className:`extui-actions`,children:[(0,j.jsx)(`button`,{type:`submit`,className:`extui-primary`,disabled:!n.trim(),children:`提交`}),a]})]}),!i&&(0,j.jsxs)(`div`,{className:`extui-actions`,children:[e.method===`confirm`&&(0,j.jsx)(`button`,{type:`button`,className:`extui-primary`,onClick:()=>t({confirmed:!0}),children:`确认`}),e.method===`confirm`&&(0,j.jsx)(`button`,{type:`button`,className:`extui-no`,onClick:()=>t({confirmed:!1}),children:`拒绝`}),a]})]})}function In({initial:e,label:t,onCommit:n,onClose:r}){let[i,a]=(0,l.useState)(e),o=(0,l.useRef)(null),s=(0,l.useRef)(!1);(0,l.useEffect)(()=>{o.current?.focus(),o.current?.select()},[]);let c=!i.trim(),u=()=>{s.current=!0,r()},d=()=>{if(c)return;let t=i.trim();(t===e||n(t))&&u()};return(0,j.jsxs)(`div`,{className:`inline-edit`,"data-editing":`1`,children:[(0,j.jsx)(`input`,{ref:o,className:`inline-edit-input`,value:i,"aria-label":t,onChange:e=>a(e.target.value),onKeyDown:e=>{e.key===`Enter`?(e.preventDefault(),d()):e.key===`Escape`&&(e.preventDefault(),u())},onBlur:()=>{s.current||r()}}),(0,j.jsx)(`button`,{type:`button`,className:`inline-edit-ok`,title:`确认重命名`,"aria-label":`确认重命名`,disabled:c,onMouseDown:e=>e.preventDefault(),onClick:d,children:`✓`}),(0,j.jsx)(`button`,{type:`button`,className:`inline-edit-cancel`,title:`取消重命名`,"aria-label":`取消重命名`,onMouseDown:e=>e.preventDefault(),onClick:u,children:`✗`})]})}function Ln({kind:e,label:t,value:n,detail:r,options:i,disabled:a,note:o,onChoose:s,scope:c}){let[u,d]=(0,l.useState)(!1),[f,p]=(0,l.useState)(``),[m,h]=(0,l.useState)(0),g=(0,l.useRef)(null),_=(0,l.useRef)(null),v=(0,l.useRef)(null),y=(0,l.useRef)(null),b=(0,l.useRef)([]),x=i.find(e=>e.selected),S=Cn(i,f),C=S.length===0?-1:Math.min(Math.max(m,0),S.length-1),ee=C<0?void 0:S[C],w=(e=!1)=>{d(!1),e&&_.current?.focus()},te=()=>{p(``),h(Math.max(i.findIndex(e=>e.selected),0)),d(!0)},T=e=>h(t=>S.length?Math.min(Math.max(t+e,0),S.length-1):0);(0,l.useEffect)(()=>{if(!u)return;let e=e=>{g.current?.contains(e.target)||w()};return window.addEventListener(`mousedown`,e),()=>window.removeEventListener(`mousedown`,e)},[u]),(0,l.useEffect)(()=>{if(!u)return;let e=g.current,t=t=>{e?.contains(t.relatedTarget)||w()};return e?.addEventListener(`focusout`,t),()=>e?.removeEventListener(`focusout`,t)},[u]),(0,l.useEffect)(()=>{u&&y.current?.focus()},[u]),(0,l.useEffect)(()=>{u&&C>=0&&b.current[C]?.scrollIntoView({block:`nearest`})},[u,C]),(0,l.useLayoutEffect)(()=>{if(!u)return;let e=v.current;if(!e)return;e.style.setProperty(`--picker-nudge`,`0px`),e.style.setProperty(`--picker-drop`,`0px`);let t=e.getBoundingClientRect(),n=Math.min(window.innerWidth-8-t.right,Math.max(8-t.left,0)),r=Math.min(window.innerHeight-8-t.bottom,Math.max(8-t.top,0));e.style.setProperty(`--picker-nudge`,`${n}px`),e.style.setProperty(`--picker-drop`,`${r}px`)},[u,S.length,i.length]);let ne=e=>{u&&(e.key===`Escape`?(e.preventDefault(),w(!0)):e.key===`ArrowDown`?(e.preventDefault(),T(1)):e.key===`ArrowUp`?(e.preventDefault(),T(-1)):e.key===`Home`?(e.preventDefault(),h(0)):e.key===`End`?(e.preventDefault(),h(Math.max(S.length-1,0))):e.key===`Enter`&&(e.preventDefault(),ee&&(s(ee.key),w(!0))))},re=`picker-list-${c??e}`,E=t=>`picker-option-${c??e}-${t}`;return(0,j.jsxs)(`div`,{className:`session-picker-item session-picker-${e}`,ref:g,onKeyDown:u?ne:void 0,children:[(0,j.jsxs)(`button`,{ref:_,type:`button`,className:`session-picker-trigger`,disabled:a,"aria-haspopup":`listbox`,"aria-expanded":u,title:o??`${_n[e]}:${r?`${t} · ${r}`:t}`,"data-picker-trigger":e,"data-picker-value":n??t,"data-picker-selected":i.some(e=>e.selected),onClick:()=>u?w():te(),children:[(0,j.jsx)(`span`,{className:`session-picker-kind`,children:_n[e]}),(0,j.jsx)(`span`,{className:`session-picker-name`,children:t}),r&&(0,j.jsx)(`span`,{className:`session-picker-detail`,children:r}),(0,j.jsx)(`span`,{className:`session-picker-caret`,"aria-hidden":`true`,children:`▾`})]}),u&&(0,j.jsxs)(`div`,{className:`picker-menu`,ref:v,"data-picker-menu":e,"data-picker-highlight":C,children:[(0,j.jsxs)(`div`,{className:`picker-filter`,children:[(0,j.jsx)(`span`,{className:`picker-filter-icon`,"aria-hidden":`true`,children:`🔍`}),(0,j.jsx)(`input`,{ref:y,className:`picker-filter-input`,"data-picker-filter":e,role:`combobox`,"aria-label":`筛选${vn[e]}选项`,"aria-expanded":`true`,"aria-controls":re,"aria-autocomplete":`list`,"aria-activedescendant":ee?E(C):void 0,value:f,placeholder:`输入以筛选…`,autoComplete:`off`,spellCheck:!1,onChange:e=>{p(e.target.value),h(0)}}),f&&(0,j.jsx)(`button`,{type:`button`,className:`picker-filter-clear`,"data-picker-filter-clear":e,title:`清空筛选`,"aria-label":`清空筛选`,onMouseDown:e=>e.preventDefault(),onClick:()=>{p(``),h(0),y.current?.focus()},children:`✕`})]}),x&&!S.some(e=>e.key===x.key)&&(0,j.jsxs)(`div`,{className:`picker-current`,"data-picker-current":e,"data-picker-current-value":x.key,children:[(0,j.jsx)(`span`,{className:`picker-current-label`,children:`当前`}),(0,j.jsx)(`span`,{className:`picker-current-value`,children:x.label})]}),(0,j.jsxs)(`div`,{className:`picker-list`,role:`listbox`,id:re,"aria-label":yn[e],children:[S.map((e,t)=>(0,j.jsxs)(`button`,{id:E(t),type:`button`,role:`option`,"aria-selected":e.selected,ref:e=>{b.current[t]=e},className:`picker-option${e.selected?` selected`:``}${t===C&&!e.selected?` preview`:``}`,"data-picker-option":e.key,"data-picker-option-selected":e.selected,"data-picker-highlight":t===C,onClick:()=>{s(e.key),w(!0)},children:[e.color&&(0,j.jsx)(`span`,{className:`picker-option-swatch`,style:{background:e.color},"aria-hidden":`true`}),(0,j.jsx)(`span`,{className:`picker-option-name`,children:e.label}),e.badge&&(0,j.jsx)(`span`,{className:`picker-option-badge`,"data-picker-option-badge":e.badge,children:e.badge}),e.detail&&(0,j.jsx)(`span`,{className:`picker-option-detail`,children:e.detail}),e.selected&&(0,j.jsx)(`span`,{className:`picker-option-mark`,"aria-hidden":`true`,children:`✓`})]},e.key)),S.length===0&&(0,j.jsx)(`div`,{className:`picker-empty`,"data-picker-empty":e,children:`没有匹配「${f.trim()}」的${vn[e]}`})]})]})]})}var Rn=`__pi_default__`;function zn({workspace:e,catalog:t,agents:n,onSave:r,onRename:i,onClose:a}){let[o,s]=(0,l.useState)(e.defaultAgentId),[c,u]=(0,l.useState)(e.defaultModel),[d,f]=(0,l.useState)(e.defaultThinkingLevel);(0,l.useEffect)(()=>{let e=e=>{e.key===`Escape`&&!e.defaultPrevented&&a()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[a]);let p=t?.source===`pi`,m=[{key:Rn,label:`跟随 Pi 默认`,detail:`不为新会话指定模型`,selected:c===void 0},...(t?.models??[]).map(e=>({key:`${e.provider}/${e.modelId}`,label:e.label,detail:e.detail,badge:xn(e),selected:c?.provider===e.provider&&c.modelId===e.modelId}))],h=[{key:Rn,label:`跟随 Pi 默认`,detail:`不为新会话指定思考等级`,selected:d===void 0},...(t?.levels??[]).map(e=>({key:e,label:e,selected:e===d}))],g=e=>{if(e===Rn){u(void 0);return}let n=(t?.models??[]).find(t=>t.provider===e.split(`/`)[0]&&t.modelId===e.split(`/`)[1]);n&&u({provider:n.provider,modelId:n.modelId,label:n.label})},_=e=>f(e===Rn?void 0:e),v=[{key:Rn,label:`跟随 Pi 默认`,detail:`新会话不使用任何 agent 角色`,selected:o===void 0},...(n?.agents??[]).map(e=>({key:e.id,label:e.name,detail:e.toolSummary,color:e.color,selected:o===e.id}))];return(0,j.jsx)(`div`,{className:`overlay`,onClick:a,children:(0,j.jsxs)(`div`,{className:`picker settings-dialog`,"data-settings-dialog":`1`,onClick:e=>e.stopPropagation(),children:[(0,j.jsx)(`h2`,{children:`工作区设置`}),(0,j.jsxs)(`div`,{className:`settings-scope`,children:[e.name,` · 默认值只影响之后新建的会话,已有会话不变`]}),(0,j.jsxs)(`div`,{className:`settings-row`,children:[(0,j.jsx)(`span`,{className:`settings-label`,children:`默认智能体`}),(0,j.jsx)(Ln,{kind:`agent`,scope:`settings-agent`,label:n?.agents.find(e=>e.id===o)?.name??`跟随 Pi 默认`,value:o??Rn,detail:o?`${n?.agents.find(e=>e.id===o)?.toolSummary??``}`:void 0,options:v,disabled:!n||n.source===`unavailable`,note:On(n),onChoose:e=>s(e===Rn?void 0:e)})]}),(0,j.jsxs)(`div`,{className:`settings-row`,children:[(0,j.jsx)(`span`,{className:`settings-label`,children:`默认模型`}),(0,j.jsx)(Ln,{kind:`model`,scope:`settings-model`,label:c?.label??`跟随 Pi 默认`,value:c?`${c.provider}/${c.modelId}`:Rn,detail:c?`${c.provider}/${c.modelId}`:void 0,options:m,disabled:!p,note:Dn(`模型`,t),onChoose:g})]}),(0,j.jsxs)(`div`,{className:`settings-row`,children:[(0,j.jsx)(`span`,{className:`settings-label`,children:`思考强度`}),(0,j.jsx)(Ln,{kind:`thinking`,scope:`settings-thinking`,label:d??`跟随 Pi 默认`,value:d??Rn,options:h,disabled:!p,note:Dn(`思考等级`,t),onChoose:_})]}),(0,j.jsxs)(`div`,{className:`picker-actions`,children:[(0,j.jsx)(`button`,{type:`button`,className:`settings-rename`,"data-settings-rename":`1`,onClick:i,children:`重命名工作区`}),(0,j.jsx)(`button`,{type:`button`,className:`picker-cancel`,"data-settings-cancel":`1`,onClick:a,children:`取消`}),(0,j.jsx)(`button`,{type:`button`,className:`picker-ok`,"data-settings-save":`1`,onClick:()=>r(o,c,d),children:`保存`})]})]})})}var Bn=[{id:`main`,label:`主`,name:`主 tab`},{id:`tools`,label:`工具`,name:`工具 tab`},{id:`files`,label:`文件`,name:`文件 tab`}],Vn={pending:`未开始`,in_progress:`进行中`,completed:`已完成`},Hn={pending:`○`,in_progress:`◐`,completed:`✓`},Un={high:`高`,medium:`中`,low:`低`};function Wn(e){let t=e.filter(e=>e.status!==`completed`).length;return e.length?t?`${t} 个未完成 / 共 ${e.length} 个`:`全部完成:${e.length} 个`:`0 个待办任务`}function Gn({todo:e,index:t}){let n=e.id??`todo_${t}`;return(0,j.jsxs)(`li`,{className:`todo-item todo-${e.status}`,"data-todo-item":n,"data-todo-status":e.status,children:[(0,j.jsx)(`span`,{className:`todo-mark`,"aria-hidden":`true`,children:Hn[e.status]}),(0,j.jsx)(`span`,{className:`todo-text`,children:e.content}),(0,j.jsx)(`span`,{className:`todo-status`,"data-todo-status-text":`1`,children:Vn[e.status]}),e.priority&&(0,j.jsx)(`span`,{className:`todo-priority`,"data-todo-priority":e.priority,children:Un[e.priority]})]})}function Kn({tasks:e}){return(0,j.jsx)(`ul`,{className:`bg-list`,"data-bg-task-count":e.length,children:e.map((e,t)=>{let n=e.id||`bg_${t}`,r=e.status?.trim()||`未知状态`;return(0,j.jsxs)(`li`,{className:`bg-item`,"data-bg-task":n,"data-bg-task-status":e.status??`unknown`,children:[(0,j.jsx)(`span`,{className:`bg-title`,children:e.title?.trim()||e.id||`未命名任务 ${t+1}`}),(0,j.jsxs)(`span`,{className:`bg-meta`,children:[e.agentId?.trim()&&(0,j.jsx)(`span`,{className:`bg-agent`,"data-bg-agent":e.agentId,children:e.agentId}),(0,j.jsx)(`span`,{className:`bg-status`,children:r})]})]},n)})})}function qn({todos:e,tasks:t,collapsed:n,onToggle:r,workspaceId:i,files:a,onOpenFile:o,activeTab:s,onSelectTab:c}){return(0,j.jsx)(`div`,{className:`right-rail${n?` right-rail-collapsed`:``}`,role:`complementary`,"aria-label":`右侧栏`,"data-right-rail":`1`,"data-right-rail-collapsed":n,children:n?(0,j.jsx)(`button`,{type:`button`,className:`right-rail-open`,"data-right-rail-open":`1`,title:`展开右侧栏`,"aria-label":`展开右侧栏`,onClick:r,children:`‹`}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`right-rail-head`,children:[(0,j.jsx)(`div`,{className:`right-tabs`,role:`tablist`,"aria-label":`右侧栏 tab`,"data-right-tab-count":Bn.length,children:Bn.map(e=>(0,j.jsx)(`button`,{type:`button`,role:`tab`,id:`right-tab-${e.id}`,className:`right-tab${e.id===s?` right-tab-active`:``}`,"data-right-tab":e.id,"aria-selected":e.id===s,"aria-controls":`right-panel-${e.id}`,title:e.name,"aria-label":e.name,onClick:()=>c(e.id),children:e.label},e.id))}),(0,j.jsx)(`button`,{type:`button`,className:`right-rail-collapse`,"data-right-rail-collapse":`1`,title:`收起右侧栏(聊天区会变宽)`,"aria-label":`收起右侧栏`,onClick:r,children:`›`})]}),Bn.filter(e=>e.id===s).map(n=>(0,j.jsxs)(`div`,{className:`right-rail-body`,role:`tabpanel`,id:`right-panel-${n.id}`,"aria-labelledby":`right-tab-${n.id}`,"data-right-panel":n.id,children:[n.id===`main`&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`rail-section-head`,children:[(0,j.jsx)(`h2`,{className:`rail-section-title`,children:`待办任务`}),(0,j.jsx)(`span`,{className:`rail-section-count`,"data-todo-summary":`1`,children:Wn(e)})]}),e.length>0?(0,j.jsx)(`ol`,{className:`todo-list`,"data-todo-count":e.length,children:e.map((e,t)=>(0,j.jsx)(Gn,{todo:e,index:t},e.id??`todo_${t}`))}):(0,j.jsx)(`p`,{className:`rail-empty`,"data-todo-empty":`1`,children:`暂无待办任务。Agent 开始处理多步骤任务时,会自己把待办写到这里。`}),(0,j.jsxs)(`div`,{className:`rail-section-head`,children:[(0,j.jsx)(`h2`,{className:`rail-section-title`,children:`后台任务`}),(0,j.jsx)(`span`,{className:`rail-section-count`,"data-bg-summary":`1`,children:t.length?`${t.length} 个运行中`:`0 个`})]}),t.length>0?(0,j.jsx)(Kn,{tasks:t}):(0,j.jsx)(`p`,{className:`rail-empty`,"data-bg-empty":`1`,children:`当前没有正在运行的后台任务。`})]}),n.id===`tools`&&(0,j.jsx)(Xn,{}),n.id===`files`&&(0,j.jsx)(Qe,{workspaceId:i,files:a,onOpenFile:o})]},n.id))]})})}function Jn(){try{if(typeof window>`u`)return Ot.slice();let e=Pt(window.localStorage.getItem(jt));return window.localStorage.getItem(`super-pi:tools:v1`)===null?Ot.slice():e}catch{return Ot.slice()}}function Yn(e){try{if(typeof window>`u`)return;window.localStorage.setItem(jt,Ft(e))}catch{}}function Xn(){let[e,t]=(0,l.useState)(Jn),[n,r]=(0,l.useState)(),[i,a]=(0,l.useState)(``),[o,s]=(0,l.useState)(``),[c,u]=(0,l.useState)(),d=e.find(e=>e.id===n);return(0,l.useEffect)(()=>{Yn(e)},[e]),(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`rail-section-head`,children:[(0,j.jsx)(`h2`,{className:`rail-section-title`,children:`工具`}),(0,j.jsxs)(`span`,{className:`rail-section-count`,"data-tool-summary":`1`,children:[e.length,` 个`]})]}),e.length>0?(0,j.jsx)(`ul`,{className:`tool-grid`,"data-tool-count":e.length,children:e.map(e=>(0,j.jsxs)(`li`,{className:`tool-slot`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`tool-icon`,"data-tool-icon":e.id,"data-tool-kind":e.kind,"data-tool-state":e.id===n?`open`:`idle`,title:`打开${e.name}`,"aria-label":`打开${e.name}`,"aria-current":e.id===n?`true`:void 0,onClick:()=>r(t=>t===e.id?void 0:e.id),children:[(0,j.jsx)(`span`,{className:`tool-icon-glyph`,"aria-hidden":`true`,children:e.glyph}),(0,j.jsx)(`span`,{className:`tool-icon-name`,children:e.name})]}),e.kind===`link`&&(0,j.jsx)(`button`,{type:`button`,className:`tool-remove`,"data-tool-remove":e.id,title:`移除${e.name}`,"aria-label":`移除${e.name}`,onClick:()=>{t(t=>Rt(t,e.id)),n===e.id&&r(void 0)},children:`✕`})]},e.id))}):(0,j.jsx)(`p`,{className:`rail-empty`,"data-tool-empty":`1`,children:`还没有工具。从下面的预置列表挑一个,或者填一个自己的网址。`}),(0,j.jsx)(`div`,{className:`rail-section-head`,children:(0,j.jsx)(`h2`,{className:`rail-section-title`,children:`从预置列表添加`})}),(0,j.jsx)(`div`,{className:`tool-presets`,"data-tool-presets":Dt.length,children:Dt.map(n=>{let r=e.some(e=>e.kind===n.kind);return(0,j.jsxs)(`div`,{className:`tool-preset`,"data-tool-preset":n.kind,children:[(0,j.jsx)(`span`,{className:`tool-preset-glyph`,"aria-hidden":`true`,children:n.glyph}),(0,j.jsxs)(`span`,{className:`tool-preset-text`,children:[(0,j.jsx)(`strong`,{children:n.name}),(0,j.jsx)(`small`,{children:n.blurb})]}),(0,j.jsx)(`button`,{type:`button`,className:`tool-preset-add`,"data-tool-add-preset":n.kind,disabled:r,title:r?`${n.name}已经在工具栏里了`:`添加${n.name}`,"aria-label":r?`${n.name}已添加`:`添加${n.name}`,onClick:()=>t(e=>Lt(e,n.kind)),children:r?`已添加`:`添加`})]},n.kind)})}),(0,j.jsx)(`div`,{className:`rail-section-head`,children:(0,j.jsx)(`h2`,{className:`rail-section-title`,children:`添加网址工具`})}),(0,j.jsx)(`p`,{className:`tool-hint`,children:`填一个网址,它会变成一个图标;点开后在弹窗里用按钮在新标签页打开。网址只接受 http / https / mailto。`}),(0,j.jsx)(`input`,{className:`tool-input`,"data-tool-url-input":`1`,value:i,maxLength:2048,placeholder:`https://example.com/工具`,"aria-label":`工具网址`,onChange:e=>{a(e.target.value),u(void 0)}}),(0,j.jsx)(`input`,{className:`tool-input`,"data-tool-url-name":`1`,value:o,maxLength:40,placeholder:`名称(可留空,默认用域名)`,"aria-label":`工具名称(可选)`,onChange:e=>s(e.target.value)}),(0,j.jsx)(`button`,{type:`button`,className:`tool-url-add`,"data-tool-url-add":`1`,disabled:!i.trim(),onClick:()=>{let n=Nt(i);if(!n.ok){u(n.reason);return}if(e.length>=32){u(`工具最多 32 个,先删掉一个再加。`);return}let r=e.map(e=>e.id);t(e=>[...e,{id:It(`link`,r),kind:`link`,name:o.trim()||Zn(n.url),glyph:`↗`,url:n.url}]),a(``),s(``),u(void 0)},children:`添加网址工具`}),c&&(0,j.jsx)(`p`,{className:`tool-error`,"data-tool-error":`1`,role:`alert`,children:c}),(0,j.jsxs)(`p`,{className:`tool-hint`,"data-tool-scope-note":`1`,children:[`能自定义到哪:从上面挑预置工具,或自己填一个网址。`,(0,j.jsx)(`b`,{children:`没有开放「写一段脚本来执行」这一档`}),`——它在浏览器里等同于任意代码执行,会拿着本应用的权限跑。计算器是手写的算术解析器,不含 eval,也认不出变量名。`]}),d&&(0,j.jsx)(Qn,{tool:d,onClose:()=>r(void 0)})]})}function Zn(e){try{return new URL(e,typeof window>`u`?`http://localhost`:window.location.href).hostname||e.slice(0,30)}catch{return e.slice(0,30)}}function Qn({tool:e,onClose:t}){return(0,l.useEffect)(()=>{let e=e=>{e.key===`Escape`&&t()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]),(0,u.createPortal)((0,j.jsx)(`div`,{className:`tool-overlay`,"data-tool-overlay":e.id,onClick:e=>{e.target===e.currentTarget&&t()},children:(0,j.jsxs)(`div`,{className:`tool-dialog`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`tool-dialog-title`,"data-tool-dialog":e.id,children:[(0,j.jsxs)(`div`,{className:`tool-dialog-head`,children:[(0,j.jsxs)(`h2`,{className:`tool-dialog-title`,id:`tool-dialog-title`,children:[(0,j.jsx)(`span`,{className:`tool-dialog-glyph`,"aria-hidden":`true`,children:e.glyph}),e.name]}),(0,j.jsx)(`button`,{type:`button`,className:`tool-dialog-close`,"data-tool-close":`1`,title:`关闭(Esc)`,"aria-label":`关闭${e.name}`,onClick:t,children:`✕`})]}),(0,j.jsxs)(`div`,{className:`tool-dialog-body`,children:[e.kind===`calculator`&&(0,j.jsx)(er,{}),e.kind===`timestamp`&&(0,j.jsx)(tr,{}),e.kind===`link`&&(0,j.jsx)(nr,{tool:e})]})]})}),document.body)}function $n({image:e,onClose:t}){return(0,l.useEffect)(()=>{let e=e=>{e.key===`Escape`&&t()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]),(0,u.createPortal)((0,j.jsx)(`div`,{className:`lightbox-overlay`,"data-lightbox-overlay":`1`,onClick:e=>{e.target===e.currentTarget&&t()},children:(0,j.jsxs)(`div`,{className:`lightbox-dialog`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`lightbox-title`,"data-lightbox-dialog":`1`,children:[(0,j.jsxs)(`div`,{className:`lightbox-head`,children:[(0,j.jsx)(`h2`,{className:`lightbox-title`,id:`lightbox-title`,children:e.name||`图片大图`}),(0,j.jsx)(`button`,{type:`button`,className:`lightbox-close`,"data-lightbox-close":`1`,title:`关闭(Esc)`,"aria-label":`关闭大图`,onClick:t,children:`✕`})]}),(0,j.jsx)(`div`,{className:`lightbox-body`,children:(0,j.jsx)(`img`,{src:e.url,alt:e.name||`图片大图`,className:`lightbox-image`})})]})}),document.body)}function er(){let[e,t]=(0,l.useState)(`12 * (3 + 4)`),[n,r]=(0,l.useState)(!1),i=Xt(e),a=e=>{r(!1),t(t=>n?e:t+e)};return(0,j.jsxs)(`div`,{className:`tool-calc`,"data-tool-calc":`1`,children:[(0,j.jsx)(`input`,{className:`tool-input tool-calc-input`,"data-calc-input":`1`,value:e,maxLength:240,"aria-label":`算式`,spellCheck:!1,autoComplete:`off`,placeholder:`例如 (12 + 8) / 4`,onChange:e=>{r(!1),t(e.target.value)},onKeyDown:e=>{e.key===`Enter`&&e.preventDefault()}}),(0,j.jsx)(`div`,{className:`tool-calc-keys`,"data-calc-keys":`1`,children:[[`7`,`7`],[`8`,`8`],[`9`,`9`],[`÷`,`/`],[`(`,`(`],[`)`,`)`],[`4`,`4`],[`5`,`5`],[`6`,`6`],[`×`,`*`],[`^`,`^`],[`%`,`%`],[`1`,`1`],[`2`,`2`],[`3`,`3`],[`-`,`-`],[`←`,`back`],[`C`,`clear`],[`0`,`0`],[`.`,`.`],[`+`,`+`]].map(([e,n])=>(0,j.jsx)(`button`,{type:`button`,className:`tool-calc-key`,"data-calc-key":n,"aria-label":e===`C`?`清空`:e===`←`?`退格`:`输入 ${e}`,onClick:()=>{n===`clear`?(t(``),r(!1)):n===`back`?(t(e=>e.slice(0,-1)),r(!1)):a(n)},children:e},e))}),i.ok?(0,j.jsx)(`p`,{className:`tool-calc-result`,"data-calc-result":`1`,"data-calc-value":String(i.value),children:Zt(i.value)}):(0,j.jsx)(`p`,{className:`tool-calc-error`,"data-calc-error":`1`,role:`alert`,children:i.reason})]})}function tr(){let[e,t]=(0,l.useState)(``),n=Qt(e),r=n.ok?en(n.ms):null;return(0,j.jsxs)(`div`,{className:`tool-stamp`,"data-tool-stamp":`1`,children:[(0,j.jsx)(`input`,{className:`tool-input`,"data-stamp-input":`1`,value:e,maxLength:64,spellCheck:!1,"aria-label":`时间戳或日期`,placeholder:`1757000000 或 2026-10-08T09:00:00`,onChange:e=>t(e.target.value)}),r?(0,j.jsxs)(`dl`,{className:`tool-stamp-out`,"data-stamp-result":`1`,children:[(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`本地时间`}),(0,j.jsx)(`dd`,{"data-stamp-local":`1`,children:r.local})]}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`ISO(UTC)`}),(0,j.jsx)(`dd`,{"data-stamp-iso":`1`,children:r.iso})]}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`秒`}),(0,j.jsx)(`dd`,{"data-stamp-seconds":`1`,children:r.seconds})]}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`毫秒`}),(0,j.jsx)(`dd`,{"data-stamp-ms":`1`,children:r.milliseconds})]})]}):(0,j.jsx)(`p`,{className:`tool-stamp-error`,"data-stamp-error":`1`,role:`alert`,children:n.ok?`这个日期无法显示。`:n.reason})]})}function nr({tool:e}){return(0,j.jsxs)(`div`,{className:`tool-link`,"data-tool-link":e.id,children:[(0,j.jsx)(`p`,{className:`tool-hint`,children:`这个网址工具保存了一个地址。点下面的按钮由浏览器在新标签页打开它。`}),(0,j.jsx)(`code`,{className:`tool-link-url`,"data-tool-link-url":e.id,children:e.url}),(0,j.jsx)(`a`,{className:`tool-link-open`,"data-tool-link-open":e.id,href:e.url,target:`_blank`,rel:`noopener noreferrer`,title:e.url,children:`在新标签页打开 ↗`})]})}var rr=`(max-width: 1100px)`,ir=(e,t,n)=>Math.min(Math.max(e,t),Math.max(t,n));function ar(e,t,n){let r=Math.max(0,Math.round(n)-480),i=ir(520,180,Math.max(180,r-240)),a=ir(Math.round(e),180,i),o=ir(640,240,Math.max(240,r-a));return{sidebar:a,rail:ir(Math.round(t),240,o),sidebarMin:180,sidebarMax:i,railMin:240,railMax:o,sumCap:r}}var or=`super-pi.rail-widths.v1`;function sr(){try{if(typeof window>`u`)return{};let e=window.localStorage.getItem(or);if(e===null)return{};let t=JSON.parse(e),n=e=>typeof e==`number`&&Number.isFinite(e)&&e>0?Math.round(e):void 0;return{sidebar:n(t.sidebar),rail:n(t.rail)}}catch{return{}}}function cr(e){try{if(typeof window>`u`)return;window.localStorage.setItem(or,JSON.stringify(e))}catch{}}function lr({side:e,width:t,min:n,max:r,label:i,onWidth:a}){let[o,s]=(0,l.useState)(!1),c=e=>e.shiftKey?64:16;return(0,j.jsx)(`div`,{className:`rail-resizer rail-resizer-${e}${o?` rail-resizer-dragging`:``}`,"data-rail-resizer":e,"data-rail-resizer-dragging":o?`true`:`false`,"data-rail-resizer-width":t,role:`separator`,"aria-orientation":`vertical`,"aria-label":i,"aria-valuenow":t,"aria-valuemin":n,"aria-valuemax":r,tabIndex:0,onMouseDown:i=>{i.preventDefault(),i.currentTarget.focus();let o=i.clientX,c=t;s(!0);let l=document.body,u=l.style.cursor,d=l.style.userSelect;l.style.cursor=`col-resize`,l.style.userSelect=`none`;let f=t=>{let i=e===`left`?t.clientX-o:o-t.clientX;a(ir(c+i,n,r))},p=()=>{l.style.cursor=u,l.style.userSelect=d,s(!1),window.removeEventListener(`mousemove`,f),window.removeEventListener(`mouseup`,p)};window.addEventListener(`mousemove`,f),window.addEventListener(`mouseup`,p)},onKeyDown:i=>{let o=c(i);i.key===`ArrowLeft`?(i.preventDefault(),a(ir(e===`left`?t-o:t+o,n,r))):i.key===`ArrowRight`?(i.preventDefault(),a(ir(e===`left`?t+o:t-o,n,r))):i.key===`Home`?(i.preventDefault(),a(n)):i.key===`End`&&(i.preventDefault(),a(r))}})}function ur(){let[e,t]=(0,l.useState)(tn),[n,r]=(0,l.useState)(),[i,a]=(0,l.useState)(``),[o,s]=(0,l.useState)(!1),[c,u]=(0,l.useState)(),[d,f]=(0,l.useState)({}),[p,m]=(0,l.useState)(),[h,g]=(0,l.useState)(!1),_=(0,l.useRef)(void 0),[v,y]=(0,l.useState)({}),[b,x]=(0,l.useState)([]),[S,C]=(0,l.useState)([]),[ee,w]=(0,l.useState)(new Map),[te,T]=(0,l.useState)(new Map),[ne,re]=(0,l.useState)(),[E,ie]=(0,l.useState)(),[ae,oe]=(0,l.useState)(),[se,ce]=(0,l.useState)(),[le,ue]=(0,l.useState)(()=>typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(`(max-width: 1100px)`).matches),[de,fe]=(0,l.useState)(()=>typeof window>`u`?1440:window.innerWidth);(0,l.useEffect)(()=>{let e=()=>fe(window.innerWidth);return window.addEventListener(`resize`,e),e(),()=>window.removeEventListener(`resize`,e)},[]);let[pe,me]=(0,l.useState)(sr),he=ar(pe.sidebar??270,pe.rail??320,de);(0,l.useEffect)(()=>{cr({sidebar:he.sidebar,rail:he.rail})},[he.sidebar,he.rail]);let ge=e=>me(t=>({...t,sidebar:e})),_e=e=>me(t=>({...t,rail:e}));(0,l.useEffect)(()=>{if(typeof window>`u`||typeof window.matchMedia!=`function`)return;let e=window.matchMedia(rr),t=e=>{e.matches&&ue(!0)};return e.addEventListener(`change`,t),e.matches&&ue(!0),()=>e.removeEventListener(`change`,t)},[]);let[ve,ye]=(0,l.useState)(new Map),[be,xe]=(0,l.useState)({}),[Se,Ce]=(0,l.useState)({}),[D,O]=(0,l.useState)([]),[k,we]=(0,l.useState)(0),[Te,Ee]=(0,l.useState)(),[De,A]=(0,l.useState)(!1),Oe=(0,l.useRef)(null),Ae=(0,l.useRef)(0),je=(0,l.useRef)([]),Me=(0,l.useRef)(void 0),Ne=(0,l.useRef)(!1),[Pe,Fe]=(0,l.useState)(()=>Date.now());(0,l.useEffect)(()=>{let e=window.setInterval(()=>Fe(Date.now()),3e4);return()=>window.clearInterval(e)},[]);let Ie=(0,l.useMemo)(()=>e.conversations.filter(e=>!e.archivedAt),[e.conversations]),M=(0,l.useMemo)(()=>Ie.find(e=>e.id===n)??Ie[0],[n,Ie]);(0,l.useEffect)(()=>{Me.current=M?.id}),(0,l.useEffect)(()=>{O([])},[M?.id]);let[Le,Re]=(0,l.useState)([]),ze=Le.length>0?Le:M?[M.id]:[],Be=(0,l.useMemo)(()=>ze.map(e=>Ie.find(t=>t.id===e)).filter(e=>e!==void 0),[ze,Ie]),Ve=(0,l.useCallback)(e=>{r(e),Ge(`session`),Re(t=>t.includes(e)?t:t.length>0?[...t,e]:[...M?.id&&M.id!==e?[M.id]:[],e])},[M]),He=(0,l.useCallback)(e=>{let t=Le.indexOf(e);if(t<0)return;let n=Le.filter(t=>t!==e);if(Re(n),M?.id!==e)return;let i=n[Math.min(t,n.length-1)];i&&r(i)},[Le,M]),N=Ze(p),[Ue,We]=(0,l.useState)(Bn[0].id),[P,Ge]=(0,l.useState)(`session`);(0,l.useEffect)(()=>{P===`file`&&!N.active&&Ge(`session`)},[P,N.active]);let Ke=(0,l.useCallback)(e=>{N.setActivePath(e),Ge(`file`),We(`files`)},[N.setActivePath]),qe=(0,l.useCallback)(async e=>{await N.openFile(e),Ge(`file`)},[N.openFile]),Je=(0,l.useMemo)(()=>Be.map(e=>({id:`session:${e.id}`,rawId:e.id,kind:`session`,label:e.title,title:e.title,closable:Be.length>1||N.open.length>0})),[Be,N.open.length]),Xe=(0,l.useMemo)(()=>N.open.map(e=>({id:`file:${e.path}`,rawId:e.path,kind:`file`,label:e.name,title:e.path,closable:!0,badge:e.dirty?(0,j.jsx)(`span`,{className:`file-tab-badge`,"data-file-tab-dirty":e.path,"aria-label":`未保存`,children:`●`}):void 0})),[N.open]),Qe=(0,l.useMemo)(()=>[...Je,...Xe],[Je,Xe]),$e=P===`file`&&N.activePath?`file:${N.activePath}`:M?.id?`session:${M.id}`:void 0,et=(0,l.useCallback)(e=>{if(e.startsWith(`file:`)){let t=e.slice(5);Ke(t)}else if(e.startsWith(`session:`)){let t=e.slice(8);Ve(t)}},[Ke,Ve]),tt=(0,l.useCallback)(e=>{if(e.startsWith(`file:`)){let t=e.slice(5);N.closeFile(t),N.activePath===t&&N.open.length<=1&&Ge(`session`)}else if(e.startsWith(`session:`)){let t=e.slice(8);He(t)}},[N,He]),rt=N.active,it=M?.id;(0,l.useEffect)(()=>{it&&I({type:`conversation.select`,conversationId:it})},[it]);let F=(e,t=`info`)=>{if(!e)return;let n=++Ae.current;C(r=>[...r,{key:n,text:e,kind:t}]),je.current.push(window.setTimeout(()=>C(e=>e.filter(e=>e.key!==n)),7e3))},at=(e,t)=>{let n=e.findIndex(e=>e.id===t.id);if(n<0)return[t,...e];let r=[...e];return r[n]=t,r},ot=(e,t)=>{let n=e.findIndex(e=>e.id===t.id);if(n<0)return[t,...e];let r=[...e];return r[n]=t,r},st=(e,t)=>{if(t.blocking)x(n=>[...n.filter(n=>n.conversationId!==e||n.request.requestId!==t.requestId),{conversationId:e,request:t}]);else if(t.method===`notify`)F(t.message||t.title,t.notifyType??`info`);else if(t.method===`setStatus`){let e=t.statusKey??``;w(n=>{let r=new Map(n);return t.statusText===void 0?r.delete(e):r.set(e,t.statusText),r})}else if(t.method===`setWidget`){let e=t.widgetKey??``;T(n=>{let r=new Map(n);return t.widgetLines===void 0?r.delete(e):r.set(e,{lines:t.widgetLines,placement:t.widgetPlacement??`aboveEditor`}),r})}else t.method===`setTitle`?re(t.title):t.method===`set_editor_text`&&e===Me.current&&a(t.text??``)},ct=(e,t,n)=>{x(n=>n.filter(n=>n.conversationId!==e||n.request.requestId!==t));let r=Tn[n];r&&F(r,`warning`)};(0,l.useEffect)(()=>{let e=!1,n=0,i,a=()=>{if(e)return;let o=location.protocol===`https:`?`wss`:`ws`,c=new WebSocket(`${o}://${location.host}/ws`);_.current=c,c.onopen=()=>{e||(n=0,s(!0),c.send(JSON.stringify({type:`catalog.fetch`})),c.send(JSON.stringify({type:`agent.catalog.fetch`})),c.send(JSON.stringify({type:`subagent.catalog.fetch`})))},c.onclose=()=>{e||(Ne.current=!1,s(!1),i=window.setTimeout(a,Math.min(hn,mn*2**n++)))},c.onmessage=({data:n})=>{if(e)return;let i=JSON.parse(n);i.type===`state`?(Ne.current=!1,t(i.state),r(e=>{let t=i.state.conversations.filter(e=>!e.archivedAt);return e&&t.some(t=>t.id===e)?e:t[0]?.id}),m(e=>e&&i.state.workspaces.some(t=>t.id===e)?e:i.state.workspaces[0]?.id)):i.type===`message.delta`?t(e=>({...e,conversations:e.conversations.map(e=>e.id===i.conversationId?{...e,messages:e.messages.map(e=>e.id===i.messageId?{...e,content:e.content+i.delta}:e)}:e)})):i.type===`error`?(u(i.message),Ne.current&&(Ne.current=!1,F(`重命名失败:${i.message}`,`error`))):i.type===`extension.ui`?st(i.conversationId,i.request):i.type===`extension.ui.closed`?ct(i.conversationId,i.requestId,i.reason):i.type===`model.catalog`?ie(i.catalog):i.type===`agent.catalog`?oe(i.catalog):i.type===`subagent.catalog`?ce(i.catalog):i.type===`subagent.event`?t(e=>({...e,subagentRuns:at(e.subagentRuns??[],i.run)})):i.type===`workflow.event`?t(e=>({...e,workflows:ot(e.workflows??[],i.workflow)})):i.type===`message.tools`?t(e=>({...e,conversations:e.conversations.map(e=>e.id===i.conversationId?{...e,messages:e.messages.map(e=>e.id===i.messageId?{...e,toolCalls:i.toolCalls}:e)}:e)})):i.type===`pi.queue`?ye(e=>{let t=new Map(e);return t.set(i.conversationId,{steering:i.steering,followUp:i.followUp}),t}):i.type===`conversation.fork.result`&&(Yn(e=>e===i.conversationId?void 0:e),F(i.ok?`已从「${i.title}」分叉出新会话,放在侧边栏最上面;没有切换过去。${i.messagesCopied?`复制了 ${i.messagesCopied} 条消息。`:`原会话还没有消息,只复制了会话本身。`}`:`分叉失败:${i.message}`,i.ok?`info`:`error`))}};return a(),()=>{e=!0,window.clearTimeout(i);for(let e of je.current)window.clearTimeout(e);_.current?.close()}},[]);let I=e=>_.current?.readyState===WebSocket.OPEN&&(_.current.send(JSON.stringify(e)),!0),dt=(e,t,n)=>I({type:`extension.ui.answer`,conversationId:e,requestId:t,...n}),ft=M?.model??E?.defaultModel,pt=M?.thinkingLevel??E?.defaultThinkingLevel,mt=E?.source===`pi`,ht=!!E?.models.find(e=>e.provider===ft?.provider&&e.modelId===ft?.modelId)?.imageInput,gt=(E?.models??[]).map(e=>({key:`${e.provider}/${e.modelId}`,label:e.label,detail:e.detail,badge:xn(e),selected:ft?.provider===e.provider&&ft.modelId===e.modelId})),_t=(E?.levels??[]).map(e=>({key:e,label:e,selected:e===pt})),vt=e=>{if(!M)return;let[t,n]=e.split(`/`);t&&n&&I({type:`conversation.model`,conversationId:M.id,provider:t,modelId:n})},yt=e=>{M&&I({type:`conversation.thinking`,conversationId:M.id,level:e})},bt=ae?.agents.find(e=>e.id===M?.agentId),xt=[{key:Rn,label:`跟随 Pi 默认`,detail:`不使用任何 agent 角色`,selected:!M?.agentId},...(ae?.agents??[]).map(e=>({key:e.id,label:e.name,detail:e.toolSummary,color:e.color,selected:M?.agentId===e.id}))],Ct=bt?.model,wt=!!(Ct&&M?.model&&M.model.provider===Ct.provider&&M.model.modelId===Ct.modelId);bt?.thinkingLevel&&(M?.thinkingLevel,bt.thinkingLevel);let Tt=e=>{M&&I({type:`conversation.agent`,conversationId:M.id,agentId:e===Rn?null:e})},Dt=b.filter(e=>e.conversationId===M?.id),Ot=(0,l.useMemo)(()=>(e.subagentRuns??[]).filter(e=>e.conversationId===M?.id),[e.subagentRuns,M?.id]),kt=(0,l.useMemo)(()=>(e.workflows??[]).filter(e=>e.conversationId===M?.id),[e.workflows,M?.id]),At=(0,l.useMemo)(()=>new Map(kt.map(e=>[e.id,e])),[kt]),jt=(0,l.useMemo)(()=>new Map((se?.agents??[]).map(e=>[e.id,e.name])),[se]),Mt=(0,l.useMemo)(()=>new Map((M?.messages??[]).map(e=>[e.id,e])),[M?.messages]),Nt=(0,l.useMemo)(()=>new Map(Ot.map(e=>[e.id,e])),[Ot]),Pt=(0,l.useMemo)(()=>{if(!M)return[];let e=M.messages.map((e,t)=>({at:Date.parse(e.createdAt)||0,seq:t,key:`m:${e.id}`}));return Ot.forEach((t,n)=>e.push({at:Date.parse(t.startedAt)||0,seq:e.length+n,key:`r:${t.id}`})),kt.forEach((t,n)=>e.push({at:Date.parse(t.startedAt)||0,seq:e.length+n,key:`w:${t.id}`})),e.sort((e,t)=>e.at-t.at||e.seq-t.seq).map(e=>e.key)},[M,Ot,kt]),Ft=e=>xe(t=>({...t,[e]:!t[e]})),It=(e,t)=>Ce(n=>({...n,[`${e}:${t}`]:!n[`${e}:${t}`]})),Lt=e=>{I({type:`subagent.stop`,runId:e})||F(`连接断开,无法停止子智能体,请重试`,`error`)},Rt=e=>{I({type:`workflow.stop`,workflowId:e})||F(`连接断开,无法停止编排,请重试`,`error`)},zt=e=>[...te].filter(([,t])=>t.placement===e).map(([e,t])=>{let n=t.lines;return(0,j.jsxs)(`div`,{className:`extui-widget`,"data-widget-key":e,"data-widget-lines":n.length,children:[n.slice(0,En).map((e,t)=>(0,j.jsx)(`div`,{children:e},`${t}:${e}`)),n.length>En&&(0,j.jsx)(`div`,{children:`… (widget truncated)`})]},e)}),Bt=(e,t)=>{I({type:`workspace.create`,name:e,path:t}),g(!1)},[Vt,Ht]=(0,l.useState)(),Ut=(e,t)=>Ht(n=>n?.kind===e&&n.id===t?n:{kind:e,id:t}),Wt=()=>Ht(void 0),Gt=(e,t)=>Vt?.kind===e&&Vt.id===t,Kt=(e,t,n)=>I(e===`workspace`?{type:`workspace.rename`,workspaceId:t,name:n}:{type:`conversation.rename`,conversationId:t,name:n})?(Ne.current=!0,Wt(),!0):(F(`连接断开,改名未保存,请重试`,`error`),!1),qt=t=>{let n=e.conversations.filter(e=>e.workspaceId===t.id).length;window.confirm(`删除工作区「${t.name}」?${n?`其中 ${n} 条会话将一并删除,`:``}此操作不可撤销。`)&&I({type:`workspace.delete`,workspaceId:t.id})},[L,Jt]=(0,l.useState)(),Yt=L?e.workspaces.find(e=>e.id===L):void 0,{theme:Xt,setTheme:Zt}=St(),[Qt,$t]=(0,l.useState)(!1),[en,rn]=(0,l.useState)(!1),an=(e,t,n,r)=>{I({type:`workspace.settings`,workspaceId:e,model:n?{provider:n.provider,modelId:n.modelId}:null,thinkingLevel:r??null,agentId:t??null})?Jt(void 0):F(`连接断开,设置未保存,请重试`,`error`)},on=e=>{m(e),I({type:`conversation.create`,workspaceId:e})},sn=e=>{r(t=>t===e?void 0:t),I({type:`conversation.archive`,conversationId:e})},cn=e=>I({type:`conversation.unarchive`,conversationId:e}),ln=async e=>{if(!M){F(`请先选择或创建会话`,`error`);return}if(!ht){F(`当前模型不支持图片输入`,`error`);return}let t=[`image/png`,`image/jpeg`,`image/gif`,`image/webp`],n=e.filter(e=>t.includes(e.type)?e.size>5242880?(F(`图片「${e.name}」超过 5MB 上限`,`error`),!1):!0:(F(`不支持的文件格式「${e.name}」,仅支持 PNG/JPEG/GIF/WebP`,`error`),!1));if(n.length===0)return;let r=M.id;we(e=>e+n.length);for(let e of n)try{let t=await new Promise((t,n)=>{let r=new FileReader;r.onload=()=>{let e=r.result,n=e.indexOf(`,`);t(n>=0?e.slice(n+1):e)},r.onerror=n,r.readAsDataURL(e)}),n=await fetch(`/api/upload`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({conversationId:r,name:e.name,mimeType:e.type,data:t})});if(!(n.headers.get(`content-type`)??``).includes(`application/json`)){F(`服务器未返回 JSON 响应,请刷新或重启服务`,`error`);continue}if(n.ok){let e=await n.json();O(t=>[...t,{id:e.id,name:e.name,mimeType:e.mimeType,bytes:e.bytes}])}else{let e=await n.json().catch(()=>({error:`上传失败`}));F(e.error||`上传失败: ${n.status}`,`error`)}}catch(e){F(`上传错误: ${e instanceof Error?e.message:`网络错误`}`,`error`)}finally{we(e=>Math.max(0,e-1))}},_n=e=>{let t=e.clipboardData?.items;if(!t)return;let n=[];for(let e=0;e<t.length;e++){let r=t[e];if(r.type.startsWith(`image/`)){let e=r.getAsFile();e&&n.push(e)}}if(n.length>0){if(!ht){F(`当前模型不支持图片输入`,`error`);return}e.preventDefault(),ln(n)}},vn=e=>{e.dataTransfer?.types?.includes(`Files`)&&(e.preventDefault(),A(!0))},yn=e=>{e.currentTarget.contains(e.relatedTarget)||A(!1)},bn=e=>{A(!1);let t=Array.from(e.dataTransfer?.files??[]).filter(e=>e.type.startsWith(`image/`));if(t.length>0){if(e.preventDefault(),!ht){F(`当前模型不支持图片输入`,`error`);return}ln(t)}},Sn=e=>{e.preventDefault(),M&&(i.trim()||D.length!==0)&&(D.length>0&&!ht?F(`当前模型不支持图片输入,请移除图片或切换至支持图文的模型`,`error`):k>0?F(`图片正在上传中,请稍候…`,`info`):(I({type:`message.send`,conversationId:M.id,content:i,...D.length>0?{images:D}:{}}),a(``),O([])))},Cn=(0,l.useMemo)(()=>(e.queuedMessages??[]).filter(e=>e.conversationId===M?.id),[e.queuedMessages,M?.id]),kn=e=>{I({type:`message.cancel`,conversationId:M?.id??``,queueId:e})||F(`连接断开,取消没有生效,请重试`,`error`)},An=e=>{I({type:`message.steer`,conversationId:M?.id??``,queueId:e})||F(`连接断开,插队没有生效,请重试`,`error`)},[jn,Vn]=(0,l.useState)(),Hn=e=>{M&&!jn&&(I({type:`message.revert`,conversationId:M.id,messageId:e})?Vn(e):F(`连接断开,回退未执行,请重试`,`error`))};(0,l.useEffect)(()=>{M?.status!==`running`&&Vn(void 0)},[M?.id,M?.status]);let[Un,Wn]=(0,l.useState)(),Gn=(0,l.useRef)(void 0),Kn=async(e,t)=>{Gn.current&&clearTimeout(Gn.current);let n=await gn(t);Wn({id:e,kind:n?`copied`:`error`}),n||F(`复制失败:浏览器拒绝了剪贴板写入,可以手动选中这条消息的文字复制`,`error`),Gn.current=setTimeout(()=>Wn(void 0),2e3)};(0,l.useEffect)(()=>()=>{Gn.current&&clearTimeout(Gn.current)},[]);let[Jn,Yn]=(0,l.useState)(),Xn=e=>{Jn||(I({type:`conversation.fork`,conversationId:e})?Yn(e):F(`连接断开,分叉没有执行,请重试`,`error`))};return(0,j.jsxs)(`main`,{className:`shell${le?` shell-rail-collapsed`:``}`,"data-rail-collapsed":le,style:{"--sidebar-width":`${he.sidebar}px`,"--rail-col":le?void 0:`${he.rail}px`},children:[(0,j.jsxs)(`aside`,{children:[(0,j.jsxs)(`div`,{className:`brand`,children:[(0,j.jsx)(`span`,{children:`π`}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`strong`,{children:`SUPER PI`}),(0,j.jsx)(`small`,{children:`agent workspace`})]})]}),(0,j.jsx)(`div`,{className:`sidebar-actions`,children:(0,j.jsx)(`button`,{className:`workspace-new`,onClick:()=>g(!0),children:`+ 工作区`})}),(0,j.jsx)(`div`,{className:`label`,children:`工作区`}),(0,j.jsx)(`nav`,{children:e.workspaces.map(t=>{let n=e.conversations.filter(e=>e.workspaceId===t.id),r=n.filter(e=>!e.archivedAt).sort(dn),i=n.filter(e=>e.archivedAt).sort(fn),a=d[t.id]??!1,o=v[t.id]??!0;return(0,j.jsxs)(`section`,{className:`workspace-group`,children:[(0,j.jsx)(`div`,{className:`workspace-header`,children:Gt(`workspace`,t.id)?(0,j.jsx)(In,{initial:t.name,label:`重命名工作区 ${t.name}`,onCommit:e=>Kt(`workspace`,t.id,e),onClose:Wt}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`button`,{className:`workspace-toggle`,title:t.path,onClick:()=>{m(t.id),f(e=>({...e,[t.id]:!a}))},children:[(0,j.jsx)(`span`,{className:`chevron`,children:a?`▸`:`▾`}),(0,j.jsxs)(`span`,{children:[(0,j.jsx)(`strong`,{onDoubleClick:()=>Ut(`workspace`,t.id),children:t.name}),(0,j.jsx)(`small`,{children:t.path})]})]}),(0,j.jsx)(`button`,{className:`workspace-add`,title:`在此工作区新建会话`,onClick:()=>on(t.id),children:`+`}),(0,j.jsx)(`button`,{className:`workspace-settings`,title:`工作区设置(默认智能体 / 模型 / 思考强度)`,"aria-label":`工作区设置 ${t.name}`,onClick:()=>Jt(t.id),children:`⚙`}),(0,j.jsx)(`button`,{className:`workspace-delete`,title:`删除工作区`,onClick:()=>qt(t),children:`×`})]})}),!a&&(r.length?r.map(e=>(0,j.jsx)(`div`,{className:`conversation-row`,children:Gt(`conversation`,e.id)?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(In,{initial:e.title,label:`重命名会话 ${e.title}`,onCommit:t=>Kt(`conversation`,e.id,t),onClose:Wt}),(0,j.jsx)(`small`,{className:`conversation-time`,children:un(e.updatedAt,Pe)})]}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`button`,{className:`conversation ${M?.id===e.id?`selected`:``}`,"data-conversation":e.id,title:e.title,"aria-label":`打开会话 ${e.title}`,onClick:()=>{Ve(e.id),m(t.id)},children:[(0,j.jsxs)(`span`,{onDoubleClick:()=>Ut(`conversation`,e.id),children:[`· `,e.title]}),(0,j.jsx)(`small`,{children:un(e.updatedAt,Pe)})]}),(0,j.jsx)(`button`,{type:`button`,className:`conversation-fork`,"data-fork-conversation":e.id,"data-fork-state":Jn===e.id?`pending`:`idle`,disabled:!!Jn,title:`从此会话分叉出一个新会话`,"aria-label":`从会话 ${e.title} 分叉出一个新会话`,onClick:()=>Xn(e.id),children:`⑂`}),(0,j.jsx)(`button`,{className:`conversation-archive`,title:`归档会话`,"aria-label":`归档会话 ${e.title}`,onClick:()=>sn(e.id),children:`×`})]})},e.id)):(0,j.jsx)(`div`,{className:`conversation-empty`,children:`暂无会话`})),!a&&i.length>0&&(0,j.jsxs)(`div`,{className:`archived-group`,"data-archived-count":i.length,children:[(0,j.jsxs)(`button`,{className:`archived-toggle`,title:o?`展开已归档会话`:`收起已归档会话`,"aria-expanded":!o,onClick:()=>y(e=>({...e,[t.id]:!o})),children:[(0,j.jsx)(`span`,{className:`chevron`,children:o?`▸`:`▾`}),(0,j.jsxs)(`span`,{className:`archived-label`,children:[`Archived (`,i.length,`)`]})]}),!o&&i.map(e=>(0,j.jsx)(`div`,{className:`conversation-archived`,"data-archived-at":e.archivedAt,children:Gt(`conversation`,e.id)?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(In,{initial:e.title,label:`重命名已归档会话 ${e.title}`,onCommit:t=>Kt(`conversation`,e.id,t),onClose:Wt}),(0,j.jsx)(`small`,{children:pn(e.archivedAt)})]}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`span`,{onDoubleClick:()=>Ut(`conversation`,e.id),children:[`· `,e.title]}),(0,j.jsx)(`small`,{children:pn(e.archivedAt)}),(0,j.jsx)(`button`,{type:`button`,className:`conversation-fork`,"data-fork-conversation":e.id,"data-fork-state":Jn===e.id?`pending`:`idle`,disabled:!!Jn,title:`从此会话分叉出一个新会话`,"aria-label":`从已归档会话 ${e.title} 分叉出一个新会话`,onClick:()=>Xn(e.id),children:`⑂`}),(0,j.jsx)(`button`,{className:`conversation-restore`,title:`恢复为正常会话`,"aria-label":`恢复会话 ${e.title}`,onClick:()=>cn(e.id),children:`↑`})]})},e.id))]})]},t.id)})}),(0,j.jsxs)(`footer`,{children:[(0,j.jsxs)(`div`,{className:`footer-status`,children:[(0,j.jsx)(`i`,{className:o?`online`:`offline`}),o?`已连接`:`正在连接`,(0,j.jsx)(`span`,{children:`本地持久化`})]}),(0,j.jsxs)(`button`,{type:`button`,className:`theme-settings-trigger`,"data-theme-open":`1`,"aria-haspopup":`dialog`,"aria-expanded":Qt,onClick:()=>$t(!0),children:[(0,j.jsx)(`span`,{"aria-hidden":`true`,children:`⚙`}),`设置`]}),(0,j.jsxs)(`button`,{type:`button`,className:`theme-settings-trigger`,"data-help-open":`1`,"aria-haspopup":`dialog`,"aria-expanded":en,onClick:()=>rn(!0),children:[(0,j.jsx)(`span`,{"aria-hidden":`true`,children:`📖`}),`使用指南`]})]})]}),(0,j.jsx)(lr,{side:`left`,width:he.sidebar,min:he.sidebarMin,max:he.sidebarMax,label:`调整左侧栏宽度`,onWidth:ge}),(0,j.jsxs)(`section`,{className:`chat`,"data-main-view":P,"data-main-view-kind":P,children:[Qe.length>0&&(0,j.jsx)(`div`,{className:`chat-tab-strip`,"data-chat-tab-strip":`1`,"data-session-count":Be.length,"data-file-count":N.open.length,children:(0,j.jsx)(nt,{tabs:Qe,prefix:`workspace-tab`,ariaLabel:`工作区标签页`,activeId:$e,onSelect:et,onClose:tt,minWidth:120,maxWidth:320})}),(0,j.jsxs)(`header`,{children:[(0,j.jsxs)(`div`,{className:`chat-head`,children:[(0,j.jsx)(`h1`,{children:M?.title??`准备开始`}),ee.size>0?[...ee].map(([e,t])=>(0,j.jsx)(`p`,{"data-role":`run-status`,"data-status-key":e,children:`扩展状态:${e?`${e} · `:``}${t}`},e)):(0,j.jsx)(`p`,{"data-role":`run-status`,children:M?.status===`running`?`Agent 正在工作`:`Pi runtime · Web 控制台`})]}),(0,j.jsxs)(`span`,{className:`chat-view chat-view-${P}`,"data-main-view-indicator":P,"data-main-view-kind":P,title:P===`file`?`中间主画面正在显示文件 ${N.active?.path??``}`:`中间主画面正在显示这个会话的消息流`,children:[(0,j.jsx)(`span`,{className:`chat-view-label`,children:`主区显示`}),(0,j.jsx)(`span`,{className:`chat-view-kind`,children:P===`file`?`文件`:`会话`}),P===`file`&&N.active&&(0,j.jsx)(`span`,{className:`chat-view-name`,"data-main-view-name":N.active.name,children:N.active.name})]}),(0,j.jsx)(`div`,{className:`badge`,children:M?.status??`idle`})]}),c&&(0,j.jsx)(`div`,{className:`error`,children:c}),M?.error&&(0,j.jsx)(`div`,{className:`error`,"data-role":`conversation-error`,children:M.error}),ne&&(0,j.jsxs)(`div`,{className:`extui-title-note`,children:[`扩展建议标题:`,ne]}),S.length>0&&(0,j.jsx)(`div`,{className:`toasts`,role:`status`,"aria-live":`polite`,"data-toast-count":S.length,children:S.map(e=>(0,j.jsx)(`div`,{className:`toast toast-${e.kind}`,"data-toast-kind":e.kind,children:e.text},e.key))}),P===`file`?(0,j.jsx)(`div`,{className:`chat-file-view`,"data-main-file-view":rt?.path,"data-file-view-kind":`editor`,children:rt?(0,j.jsx)(Ye,{file:rt,state:N.saves[rt.path]?.state??`idle`,message:N.saves[rt.path]?.message??``,external:N.external[rt.path]===!0,onChange:e=>N.updateBuffer(rt.path,e),onSave:()=>void N.save(rt.path,!1),onReload:()=>void N.reload(rt.path),onOverwrite:()=>void N.save(rt.path,!0)}):(0,j.jsx)(`p`,{className:`rail-empty`,"data-main-file-empty":`1`,children:`没有选中的文件。`})}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`messages`,children:[!M&&(0,j.jsxs)(`div`,{className:`empty`,children:[(0,j.jsx)(`div`,{className:`orb`,children:`π`}),(0,j.jsx)(`h2`,{children:`开始一个新会话`}),(0,j.jsx)(`p`,{children:e.workspaces.length?`选择一个工作区创建会话,即可从浏览器向 Super Pi 发送任务。`:`先创建一个工作区,再开始会话。`}),e.workspaces.map(e=>(0,j.jsxs)(`button`,{onClick:()=>on(e.id),children:[`在「`,e.name,`」中创建会话`]},e.id)),(0,j.jsx)(`button`,{onClick:()=>g(!0),children:`+ 新建工作区`})]}),Pt.map(e=>{if(e.startsWith(`m:`)){let t=Mt.get(e.slice(2));if(!t)return null;let n=t.role===`user`&&!!t.piEntryId&&e!==Pt.at(-1)&&M?.status!==`running`&&jn!==t.id,r=t.content?(0,j.jsx)(ke,{source:t.content}):(0,j.jsx)(`span`,{className:`typing`,children:`正在思考`}),i=t.toolCalls??[];if(t.role===`user`){let i=Un?.id===t.id?Un.kind:void 0,a=t.content||(t.images?.length?`[图片]`:``);return(0,j.jsxs)(`article`,{className:`message user`,children:[(0,j.jsxs)(`div`,{className:`message-body`,children:[(0,j.jsxs)(`div`,{className:`bubble`,children:[(0,j.jsxs)(`div`,{className:`meta`,children:[`你`,(0,j.jsx)(`time`,{children:nn(t.createdAt)})]}),t.images&&t.images.length>0&&(0,j.jsx)(`div`,{className:`message-images`,"data-message-images":`1`,children:t.images.map(e=>(0,j.jsx)(`button`,{type:`button`,className:`message-image-btn`,"data-message-image-id":e.id,onClick:()=>Ee({url:`/api/upload/${encodeURIComponent(M.id)}/${encodeURIComponent(e.id)}`,name:e.name,bytes:e.bytes}),title:e.name?`查看大图:${e.name}`:`查看大图`,children:(0,j.jsx)(`img`,{src:`/api/upload/${encodeURIComponent(M.id)}/${encodeURIComponent(e.id)}`,alt:e.name||`图片`,className:`message-image-thumb`,loading:`lazy`})},e.id))}),(0,j.jsx)(`div`,{className:`content`,children:r})]}),(0,j.jsxs)(`div`,{className:`message-actions`,children:[(0,j.jsx)(`button`,{type:`button`,className:`message-copy`,"data-copy-message":t.id,"data-copy-state":i,"aria-label":`复制这条消息:${a}`,onClick:()=>Kn(t.id,a),children:i===`copied`?`已复制`:i===`error`?`复制失败`:`复制`}),n&&(0,j.jsx)(`button`,{type:`button`,className:`message-revert`,"data-revert-message":t.id,title:`回退到这里:删除这条消息之后的全部内容(Pi 的记录和这里的历史一起清掉,不会新建会话,也不动任何代码文件)`,onClick:()=>Hn(t.id),children:`⟲ 回退`})]})]}),(0,j.jsx)(`div`,{className:`avatar`,children:`你`})]},e)}return(0,j.jsxs)(`article`,{className:`message assistant`,children:[(0,j.jsx)(`div`,{className:`avatar`,children:`π`}),(0,j.jsxs)(`div`,{className:`message-body`,children:[(0,j.jsxs)(`div`,{className:`meta`,children:[`Super Pi`,(0,j.jsx)(`time`,{children:nn(t.createdAt)})]}),(0,j.jsx)(`div`,{className:`content`,children:r}),i.length>0&&(0,j.jsx)(`div`,{className:`call-blocks`,"data-call-block-count":i.length,children:i.map((e,n)=>(0,j.jsx)(Mn,{call:e,index:n,expanded:!!Se[`${t.id}:${n}`],onToggle:()=>It(t.id,n)},`${t.id}:${n}:${e.label}`))})]})]},e)}if(e.startsWith(`w:`)){let t=At.get(e.slice(2));return t?(0,j.jsx)(lt,{workflow:t,names:jt,onStop:()=>Rt(t.id)},e):null}let t=Nt.get(e.slice(2));return t?(0,j.jsx)(Nn,{run:t,name:jt.get(t.agentId)??``,expanded:!!be[t.id],onToggle:()=>Ft(t.id),onStop:()=>Lt(t.id)},e):null})]}),(0,j.jsx)(Pn,{items:Cn,pi:ve.get(M?.id??``),running:M?.status===`running`,onCancel:kn,onSteer:An}),(Dt.length>0||[...te.values()].some(e=>e.placement===`aboveEditor`))&&(0,j.jsxs)(`div`,{className:`extui`,"data-extui-count":Dt.length,children:[Dt.map(e=>(0,j.jsx)(Fn,{request:e.request,onAnswer:t=>dt(e.conversationId,e.request.requestId,t)},e.request.requestId)),zt(`aboveEditor`)]}),(0,j.jsxs)(`form`,{onSubmit:Sn,onPaste:_n,onDragOver:vn,onDragLeave:yn,onDrop:bn,className:De?`composer-dropzone-active`:void 0,children:[(0,j.jsxs)(`div`,{className:`session-picker`,"data-session-picker":`1`,children:[(0,j.jsx)(Ln,{kind:`agent`,label:bt?.name??`跟随 Pi 默认`,value:M?.agentId??Rn,detail:bt?.description||void 0,options:xt,disabled:!ae||ae.source===`unavailable`,note:On(ae),onChoose:Tt}),(0,j.jsx)(Ln,{kind:`model`,label:ft?.label??(E?`Pi 默认`:`读取中…`),value:ft?`${ft.provider}/${ft.modelId}`:void 0,detail:wt?`来自 ${bt?.name}`:ft&&E?.source===`pi`&&!M?.model?`Pi 默认模型`:ft?`${ft.provider}/${ft.modelId}`:void 0,options:gt,disabled:!mt,note:Dn(`模型`,E),onChoose:vt}),(0,j.jsx)(Ln,{kind:`thinking`,label:pt??(E?`Pi 默认`:`读取中…`),value:pt,options:_t,disabled:!mt,note:Dn(`思考等级`,E),onChoose:yt})]}),(0,j.jsx)(`textarea`,{value:i,onChange:e=>a(e.target.value),placeholder:M?ht?`描述你要完成的任务(支持粘贴/拖放图片)…`:`描述你要完成的任务…`:`先创建会话`,disabled:!M,onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),e.currentTarget.form?.requestSubmit())}}),(D.length>0||k>0)&&(0,j.jsxs)(`div`,{className:`composer-attachments`,"data-composer-attachments":`1`,children:[D.map((e,t)=>(0,j.jsxs)(`div`,{className:`composer-attachment-item`,"data-composer-attachment-id":e.id,children:[(0,j.jsx)(`img`,{src:`/api/upload/${encodeURIComponent(M.id)}/${encodeURIComponent(e.id)}`,alt:e.name||`已附图片`,className:`composer-attachment-thumb`,onClick:()=>Ee({url:`/api/upload/${encodeURIComponent(M.id)}/${encodeURIComponent(e.id)}`,name:e.name,bytes:e.bytes}),title:`点击查看大图`}),(0,j.jsx)(`span`,{className:`composer-attachment-name`,title:e.name,children:e.name||`图片`}),(0,j.jsx)(`button`,{type:`button`,className:`composer-attachment-remove`,"data-composer-attachment-remove":e.id,onClick:()=>O(e=>e.filter((e,n)=>n!==t)),"aria-label":`移除 ${e.name||`图片`}`,title:`移除图片`,children:`✕`})]},e.id)),k>0&&(0,j.jsx)(`div`,{className:`composer-attachment-item composer-attachment-uploading`,children:(0,j.jsxs)(`span`,{children:[`图片上传中 (`,k,`)…`]})})]}),(0,j.jsxs)(`div`,{className:`composer`,children:[(0,j.jsxs)(`div`,{className:`composer-hints`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`composer-attach-btn`,"data-composer-attach":`1`,onClick:()=>Oe.current?.click(),disabled:!M||!ht||k>0,title:M?ht?`添加图片(支持剪贴板粘贴与拖拽)`:`当前模型不支持图片输入`:`请先创建或选择会话`,"aria-label":`添加图片`,children:[(0,j.jsx)(`span`,{"aria-hidden":`true`,children:`+`}),` 图片`]}),(0,j.jsx)(`input`,{ref:Oe,type:`file`,accept:`image/png,image/jpeg,image/gif,image/webp`,multiple:!0,style:{display:`none`},onChange:e=>{e.target.files?.length&&(ln(Array.from(e.target.files)),e.target.value=``)}}),(0,j.jsx)(`span`,{children:`Enter 发送 · Shift + Enter 换行`})]}),(0,j.jsxs)(`div`,{className:`composer-actions`,children:[M?.status===`running`&&(0,j.jsx)(`button`,{type:`button`,className:`stop`,"data-stop-run":M.id,onClick:()=>I({type:`run.stop`,conversationId:M.id}),children:`停止`}),(0,j.jsx)(`button`,{className:`send ${M?.status===`running`?`send-queued`:``}`,"data-send-mode":M?.status===`running`?`queued`:`direct`,disabled:!i.trim()&&D.length===0||!M||k>0,title:M?!i.trim()&&D.length===0?`请输入消息或添加图片后发送`:k>0?`图片上传中…`:M.status===`running`?`这一轮结束后发送(发送后可在上面的排队区取消或插队)`:void 0:`请先创建或选择会话`,children:M?.status===`running`?`排队发送 ↑`:`发送 ↑`})]})]})]}),zt(`belowEditor`)]})]}),(0,j.jsx)(lr,{side:`right`,width:le?30:he.rail,min:he.railMin,max:he.railMax,label:`调整右侧栏宽度`,onWidth:_e}),h&&(0,j.jsx)(wn,{onClose:()=>g(!1),onCreate:Bt}),Qt&&(0,j.jsx)(Et,{theme:Xt,onChooseTheme:e=>Zt(e),onClose:()=>$t(!1)}),en&&(0,j.jsx)(ut,{onClose:()=>rn(!1)}),Yt&&(0,j.jsx)(zn,{workspace:Yt,catalog:E,agents:ae,onClose:()=>Jt(void 0),onRename:()=>{let e=Yt.id;Jt(void 0),Ut(`workspace`,e)},onSave:(e,t,n)=>an(Yt.id,e,t,n)}),Te&&(0,j.jsx)($n,{image:Te,onClose:()=>Ee(void 0)}),(0,j.jsx)(qn,{todos:e.todos??[],tasks:e.backgroundTasks??[],collapsed:le,onToggle:()=>ue(e=>!e),workspaceId:p,files:N,onOpenFile:e=>void qe(e),activeTab:Ue,onSelectTab:We})]})}xt(bt()),(0,d.createRoot)(document.getElementById(`root`)).render((0,j.jsx)(l.StrictMode,{children:(0,j.jsx)(ur,{})}));
43
+ npx @evandu/super-pi`})})]}),(0,j.jsxs)(`div`,{className:`help-card`,children:[(0,j.jsx)(`h4`,{children:`🎯 键盘快捷键`}),(0,j.jsxs)(`div`,{className:`help-command-table`,children:[(0,j.jsxs)(`div`,{className:`cmd-row`,children:[(0,j.jsx)(`code`,{children:`Enter`}),(0,j.jsx)(`span`,{children:`发送对话消息`})]}),(0,j.jsxs)(`div`,{className:`cmd-row`,children:[(0,j.jsx)(`code`,{children:`Shift + Enter`}),(0,j.jsx)(`span`,{children:`输入框内换行`})]}),(0,j.jsxs)(`div`,{className:`cmd-row`,children:[(0,j.jsx)(`code`,{children:`Esc`}),(0,j.jsx)(`span`,{children:`快速关闭当前顶层弹窗(使用指南、设置、工作区选择器等)`})]})]})]})]})}function ht(){return(0,j.jsx)(`div`,{className:`help-section-group`,children:(0,j.jsxs)(`div`,{className:`help-card`,children:[(0,j.jsx)(`h4`,{children:`🎨 4 款内置专业高对比度主题`}),(0,j.jsxs)(`div`,{className:`help-theme-list`,children:[(0,j.jsxs)(`div`,{className:`help-theme-item`,children:[(0,j.jsx)(`strong`,{children:`🌙 Midnight(午夜冷蓝)`}),(0,j.jsx)(`p`,{children:`深邃冷调分层界面,对比度鲜明,非常适合长时间夜间专注编程。`})]}),(0,j.jsxs)(`div`,{className:`help-theme-item`,children:[(0,j.jsx)(`strong`,{children:`⬛ Slate(中性石墨)`}),(0,j.jsx)(`p`,{children:`经典低饱和中性灰度质感,克制沉稳,专业工程界面的默认首选。`})]}),(0,j.jsxs)(`div`,{className:`help-theme-item`,children:[(0,j.jsx)(`strong`,{children:`🌊 Ocean(深海冷灰)`}),(0,j.jsx)(`p`,{children:`冷调浅蓝灰阶设计,边界轮廓清晰分明,视觉感受轻盈柔和。`})]}),(0,j.jsxs)(`div`,{className:`help-theme-item`,children:[(0,j.jsx)(`strong`,{children:`☀️ Dawn(破晓暖色)`}),(0,j.jsx)(`p`,{children:`清爽明亮浅色主题,适合白天自然光线充足环境下的阅读与工作。`})]})]}),(0,j.jsxs)(`p`,{className:`help-hint`,children:[`可在左侧栏底部的 `,(0,j.jsx)(`strong`,{children:`⚙ 设置`}),` 中一键切换主题,设置会自动持久化保存在本地。`]})]})})}var gt=`super-pi.theme`,_t=[{id:`midnight`,name:`午夜`,blurb:`冷暗调鸭的分层画面,适合长时间。`},{id:`slate`,name:`石板`,blurb:`低饱和的冷调,对视觉负荷最少。`},{id:`ocean`,name:`晴空`,blurb:`浅色的界面清澈,适合天天明亮的环境。`},{id:`dawn`,name:`黎明`,blurb:`温暖低调的纸感柔和,适合大量阅读文档。`}],vt=`midnight`,yt=e=>typeof e==`string`&&_t.some(t=>t.id===e);function bt(){try{let e=window.localStorage.getItem(gt);if(!e)return vt;let t=JSON.parse(e),n=typeof t==`string`?t:t?.id;return yt(n)?n:vt}catch{return vt}}function xt(e){document.documentElement.setAttribute(`data-theme`,e);try{window.localStorage.setItem(gt,JSON.stringify({id:e,version:1}))}catch{}}function St(){let[e,t]=(0,l.useState)(vt);return(0,l.useEffect)(()=>{t(bt());let e=e=>{if(e.key===`super-pi.theme`&&e.newValue)try{let n=JSON.parse(e.newValue),r=typeof n==`string`?n:n?.id;yt(r)&&(document.documentElement.setAttribute(`data-theme`,r),t(r))}catch{}};return window.addEventListener(`storage`,e),()=>window.removeEventListener(`storage`,e)},[]),{theme:e,setTheme:(0,l.useCallback)(e=>{xt(e),t(e)},[])}}function Ct({theme:e,onChooseTheme:t,onClose:n}){let r=_t.find(t=>t.id===e);return(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`div`,{className:`settings-scope`,children:`主题只影响这台设备的显示,不改变任何内容;切换立即生效。`}),_t.length===0?(0,j.jsx)(`div`,{className:`theme-empty`,"data-theme-empty":`1`,children:`没有可用的主题。界面将继续使用默认配色,你可以在主题文件恢复后重试。`}):(0,j.jsx)(`div`,{className:`theme-options`,role:`radiogroup`,"aria-label":`主题`,children:_t.map(n=>{let r=n.id===e;return(0,j.jsxs)(`button`,{type:`button`,className:`theme-option`,role:`radio`,"aria-checked":r,"aria-pressed":r,"data-theme-option":n.id,"data-theme-current":r?`1`:`0`,onClick:()=>t(n.id),children:[(0,j.jsxs)(`span`,{className:`theme-preview`,"data-preview":n.id,"aria-hidden":`true`,children:[(0,j.jsx)(`span`,{className:`theme-preview-rail`}),(0,j.jsxs)(`span`,{className:`theme-preview-body`,children:[(0,j.jsx)(`span`,{className:`theme-preview-line`}),(0,j.jsx)(`span`,{className:`theme-preview-line dim`}),(0,j.jsx)(`span`,{className:`theme-preview-line accent`}),(0,j.jsx)(`span`,{className:`theme-preview-panel`})]})]}),(0,j.jsxs)(`span`,{className:`theme-option-name`,children:[n.name,(0,j.jsx)(`small`,{children:n.id}),r&&(0,j.jsx)(`span`,{className:`theme-option-current`,children:`当前 ✓`})]}),(0,j.jsx)(`span`,{className:`theme-option-blurb`,children:n.blurb})]},n.id)})}),(0,j.jsx)(`div`,{className:`picker-actions`,children:(0,j.jsx)(`button`,{type:`button`,className:`picker-cancel`,"data-theme-close":`1`,onClick:n,children:`完成`})}),(0,j.jsxs)(`div`,{className:`settings-scope theme-current-line`,children:[`当前:`,r?`${r.name}(${r.id})`:`默认`]})]})}function wt({context:e}){let[t,n]=(0,l.useState)(``),[r,i]=(0,l.useState)(``),[a,o]=(0,l.useState)(!1),s=e.agentCatalog,c=e.subagentCatalog,u=s?.agents??[],d=c?.agents??[],f=[...u,...d],p=[...s?.problems??[],...c?.problems??[]],m=s?.directories??(s?.directory?[s.directory]:[]),h=e.customAgentDirs??[],g=r=>{r.preventDefault();let a=t.trim();a&&(h.includes(a)?i(`该路径已存在于自定义目录列表中`):(e.onSetCustomAgentDirs?.([...h,a]),n(``),i(``)))},_=t=>{let n=h.filter(e=>e!==t);e.onSetCustomAgentDirs?.(n)};return(0,j.jsxs)(`div`,{className:`settings-agents-container`,children:[(0,j.jsxs)(`div`,{className:`settings-agents-header`,children:[(0,j.jsx)(`p`,{className:`settings-agents-desc`,children:`Super Pi 支持多目录发现智能体。系统会按优先级自上而下合并扫描目录;若存在同名配置,高优先级目录的文件将覆盖低优先级目录。`}),(0,j.jsx)(`button`,{type:`button`,className:`settings-agent-rescan-btn`,onClick:()=>{o(!0),e.onRescanAgents?.(),setTimeout(()=>o(!1),600)},disabled:a,title:`重新扫描所有目录中的智能体定义文件`,children:a?`正在扫描…`:`🔄 立即重新扫描`})]}),(0,j.jsxs)(`section`,{className:`settings-section`,children:[(0,j.jsx)(`h4`,{className:`settings-section-title`,children:`发现路径清单(按优先级自高到低)`}),(0,j.jsx)(`div`,{className:`settings-dirs-list`,children:m.length===0?(0,j.jsx)(`div`,{className:`settings-empty-hint`,children:`暂无活跃的发现路径`}):m.map((e,t)=>{let n=h.includes(e),r=e.includes(`.super_pi`)||e.includes(`.super-pi`)||e.includes(`.pi`),i=!n&&!r,a=f.filter(t=>t.sourceDir===e).length;return(0,j.jsxs)(`div`,{className:`settings-dir-row`,children:[(0,j.jsxs)(`div`,{className:`settings-dir-info`,children:[(0,j.jsxs)(`span`,{className:`settings-dir-priority`,children:[`#`,t+1]}),(0,j.jsx)(`span`,{className:`settings-dir-path`,title:e,children:e}),(0,j.jsx)(`span`,{className:`settings-dir-tag`,children:n?`自定义`:r?`用户全局`:i?`内置`:`环境`}),(0,j.jsxs)(`span`,{className:`settings-dir-count`,children:[`(发现 `,a,` 个智能体)`]})]}),n&&(0,j.jsx)(`button`,{type:`button`,className:`settings-dir-remove-btn`,onClick:()=>_(e),title:`移除此自定义扫描路径`,children:`移除`})]},e)})})]}),(0,j.jsxs)(`section`,{className:`settings-section`,children:[(0,j.jsx)(`h4`,{className:`settings-section-title`,children:`添加自定义路径`}),(0,j.jsxs)(`form`,{onSubmit:g,className:`settings-add-dir-form`,children:[(0,j.jsx)(`input`,{type:`text`,className:`settings-dir-input`,value:t,onChange:e=>{n(e.target.value),r&&i(``)},placeholder:`输入本地目录绝对路径或 ~/ 开头路径,如 D:\\agents 或 ~/.super_pi/agents`}),(0,j.jsx)(`button`,{type:`submit`,className:`settings-dir-add-btn`,disabled:!t.trim(),children:`添加目录`})]}),r&&(0,j.jsx)(`div`,{className:`settings-dir-error`,children:r})]}),p.length>0&&(0,j.jsxs)(`section`,{className:`settings-section settings-problems-section`,children:[(0,j.jsxs)(`h4`,{className:`settings-problems-title`,children:[`⚠️ 发现 `,p.length,` 个文件解析问题`]}),(0,j.jsx)(`div`,{className:`settings-problems-list`,children:p.map((e,t)=>(0,j.jsxs)(`div`,{className:`settings-problem-row`,children:[(0,j.jsx)(`span`,{className:`settings-problem-file`,children:e.file}),`: `,e.message]},t))})]}),(0,j.jsxs)(`section`,{className:`settings-section`,children:[(0,j.jsxs)(`h4`,{className:`settings-section-title`,children:[`已发现的智能体(共 `,f.length,` 个)`]}),f.length===0?(0,j.jsxs)(`div`,{className:`settings-empty-hint`,children:[`当前未发现任何智能体。请在上述目录中添加 `,(0,j.jsx)(`code`,{children:`.md`}),` 文件(需包含 YAML frontmatter)。`]}):(0,j.jsx)(`div`,{className:`settings-agent-grid`,children:f.map(e=>(0,j.jsxs)(`div`,{className:`settings-agent-card`,children:[(0,j.jsxs)(`div`,{className:`settings-agent-card-header`,children:[(0,j.jsx)(`span`,{className:`settings-agent-name`,children:e.name}),(0,j.jsxs)(`span`,{className:`settings-agent-id`,children:[`(`,e.id,`)`]}),(0,j.jsx)(`span`,{className:`settings-agent-mode-badge ${e.mode}`,children:e.mode===`primary`?`主智能体`:`子智能体`})]}),e.sourceDir&&(0,j.jsxs)(`div`,{className:`settings-agent-source`,title:e.sourceDir,children:[`来源:`,e.sourceDir]}),e.description&&(0,j.jsx)(`div`,{className:`settings-agent-desc`,children:e.description}),(0,j.jsxs)(`div`,{className:`settings-agent-footer`,children:[(0,j.jsx)(`span`,{className:`settings-agent-tools`,children:e.toolSummary}),e.model&&(0,j.jsxs)(`span`,{className:`settings-agent-model`,children:[e.model.provider,`/`,e.model.modelId]})]})]},`${e.sourceDir}-${e.id}`))})]}),(0,j.jsx)(`div`,{className:`picker-actions`,children:(0,j.jsx)(`button`,{type:`button`,className:`picker-cancel`,onClick:e.onClose,children:`完成`})})]})}function Tt(e){return(0,j.jsx)(wt,{context:e})}var Et=[{id:`appearance`,label:`外观`,render:Ct},{id:`agents`,label:`智能体`,render:Tt}],Dt=Et[0]?.id;function Ot({theme:e,onChooseTheme:t,onClose:n,agentCatalog:r,subagentCatalog:i,customAgentDirs:a,onSetCustomAgentDirs:o,onRescanAgents:s}){let[c,u]=(0,l.useState)(Dt);(0,l.useEffect)(()=>{let e=e=>{e.key===`Escape`&&!e.defaultPrevented&&n()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[n]);let d=Et.find(e=>e.id===c)??Et[0];return(0,j.jsx)(`div`,{className:`overlay`,onClick:n,children:(0,j.jsxs)(`div`,{className:`picker settings-window`,"data-theme-dialog":`1`,"data-settings-window":`1`,onClick:e=>e.stopPropagation(),children:[(0,j.jsx)(`div`,{className:`settings-window-head`,children:(0,j.jsx)(`h2`,{children:`设置`})}),(0,j.jsxs)(`div`,{className:`settings-window-body`,children:[(0,j.jsxs)(`nav`,{className:`settings-nav`,role:`tablist`,"aria-orientation":`vertical`,"aria-label":`设置分类`,"data-settings-nav":`1`,children:[(0,j.jsx)(`div`,{className:`settings-nav-label`,children:`分类`}),Et.map(e=>(0,j.jsx)(`button`,{type:`button`,id:`settings-tab-${e.id}`,className:`settings-category`,role:`tab`,"aria-selected":e.id===d?.id,"aria-controls":`settings-panel`,tabIndex:e.id===d?.id?0:-1,"data-settings-category":e.id,onClick:()=>u(e.id),children:e.label},e.id))]}),d&&(0,j.jsxs)(`div`,{className:`settings-panel`,id:`settings-panel`,role:`tabpanel`,"aria-labelledby":`settings-tab-${d.id}`,"data-settings-panel":d.id,children:[(0,j.jsx)(`h3`,{className:`settings-panel-title`,"data-settings-panel-title":d.id,children:d.label}),d.render({theme:e,onChooseTheme:t,onClose:n,agentCatalog:r,subagentCatalog:i,customAgentDirs:a,onSetCustomAgentDirs:o,onRescanAgents:s})]})]})]})})}var kt=[{kind:`calculator`,name:`计算器`,glyph:`∑`,blurb:`算术表达式,四则运算与乘方。除零会明确报错。`},{kind:`timestamp`,name:`时间戳`,glyph:`◷`,blurb:`Unix 时间戳与日期互转,本地计算,不联网。`}],At=[{id:`preset_calculator`,kind:`calculator`,name:`计算器`,glyph:`∑`}],jt=40,Mt=2048,Nt=`super-pi:tools:v1`;function Pt(e){return typeof e==`string`?e.replace(/\s+/g,` `).trim().slice(0,jt):``}function Ft(e){let t=e.trim();if(!t)return{ok:!1,reason:`请填写网址。`};if(t.length>Mt)return{ok:!1,reason:`网址太长了,请控制在 ${Mt} 个字符以内。`};let n=h(t);return n?{ok:!0,url:n}:{ok:!1,reason:`这个网址不是允许的协议。只支持 http / https / mailto 开头的网址。`}}function It(e){if(!e)return[];let t;try{t=JSON.parse(e)}catch{return[]}if(!Array.isArray(t))return[];let n=[],r=new Set;for(let e of t){if(typeof e!=`object`||!e)continue;let t=e,i=t.kind;if(typeof i!=`string`||i!==`calculator`&&i!==`timestamp`&&i!==`link`)continue;let a=Pt(t.name);if(!a)continue;let o=typeof t.glyph==`string`&&t.glyph.trim()?t.glyph.trim().slice(0,4):``;if(!o)continue;let s=typeof t.id==`string`&&t.id.trim()?t.id.trim().slice(0,64):``;if(s&&!r.has(s)){if(i===`link`){let e=h(typeof t.url==`string`?t.url:``);if(!e)continue;r.add(s),n.push({id:s,kind:`link`,name:a,glyph:o,url:e})}else if(r.add(s),n.push({id:s,kind:i,name:a,glyph:o}),n.length>=32)break}}return n}function Lt(e){return JSON.stringify(e.map(e=>e.kind===`link`?{...e}:{id:e.id,kind:e.kind,name:e.name,glyph:e.glyph}))}function Rt(e,t){let n=e===`link`?`link`:`preset_${e}`,r=typeof globalThis<`u`?globalThis.crypto:void 0,i=typeof r?.randomUUID==`function`?r.randomUUID().slice(0,8):``;i||=Math.random().toString(36).slice(2,10);let a=`${n}_${i}`,o=1;for(;t.includes(a);)a=`${n}_${i}_${o}`,o+=1;return a}function zt(e,t){if(e.some(e=>e.kind===t))return e.slice();let n=kt.find(e=>e.kind===t);return n?[...e,{id:Rt(t,e.map(e=>e.id)),kind:t,name:n.name,glyph:n.glyph}]:e.slice()}function Bt(e,t){return e.filter(e=>e.id!==t)}var Vt=e=>({ok:!1,reason:e}),Ht=`除数不能为 0:除以零没有结果,请换一个非零的除数。`,Ut=new Set([`/`,`%`]),Wt=e=>e!==void 0&&e>=`0`&&e<=`9`,Gt=e=>e!==void 0&&/\s/.test(e);function Kt(e){for(;Gt(e.source[e.at]);)e.at+=1}function qt(e){let t=e.at,n=0;for(;Wt(e.source[e.at]);)e.at+=1,n+=1;if(e.source[e.at]===`.`)for(e.at+=1;Wt(e.source[e.at]);)e.at+=1,n+=1;if(!n)return e.at=t,Vt(`「${e.source[t]}」不是有效的数字。`);let r=Number(e.source.slice(t,e.at));return Number.isFinite(r)?{ok:!0,value:r}:Vt(`数字太长了,无法表示。`)}function L(e){Kt(e);let t=e.source[e.at];if(t===void 0)return Vt(`算式不完整:末尾还缺一个数字或右括号。`);if(t===`(`){e.at+=1;let t=Zt(e);return t.ok?(Kt(e),e.source[e.at]===`)`?(e.at+=1,t):Vt(`括号不匹配:少了一个右括号「)」。`)):t}return Wt(t)||t===`.`?qt(e):Vt(`无法识别的字符「${t}」。`)}function Jt(e){let t=L(e);if(!t.ok||(Kt(e),e.source[e.at]!==`^`))return t;e.at+=1;let n=Yt(e);if(!n.ok)return n;let r=t.value**n.value;return Number.isFinite(r)?{ok:!0,value:r}:Vt(`结果超出了可计算的数值范围。`)}function Yt(e){Kt(e);let t=e.source[e.at];if(t!==`+`&&t!==`-`)return Jt(e);e.at+=1;let n=Yt(e);if(!n.ok)return n;let r=t===`-`?-n.value:n.value;return Number.isFinite(r)?{ok:!0,value:r}:Vt(`结果超出了可计算的数值范围。`)}function Xt(e){let t=Yt(e);if(!t.ok)return t;for(;;){Kt(e);let n=e.source[e.at];if(n!==`*`&&!Ut.has(n))return t;e.at+=1;let r=Yt(e);if(!r.ok)return r;if(Ut.has(n)&&r.value===0)return Vt(Ht);let i=n===`*`?t.value*r.value:n===`%`?t.value%r.value:t.value/r.value;if(!Number.isFinite(i))return Vt(`结果超出了可计算的数值范围。`);t={ok:!0,value:i}}}function Zt(e){let t=Xt(e);if(!t.ok)return t;for(;;){Kt(e);let n=e.source[e.at];if(n!==`+`&&n!==`-`)return t;e.at+=1;let r=Xt(e);if(!r.ok)return r;let i=n===`+`?t.value+r.value:t.value-r.value;if(!Number.isFinite(i))return Vt(`结果超出了可计算的数值范围。`);t={ok:!0,value:i}}}function Qt(e){let t=e.trim();if(!t)return Vt(`请输入算式。`);if(t.length>200)return Vt(`算式太长了,请控制在 200 个字符以内。`);let n={source:t,at:0},r=Zt(n);return r.ok?(Kt(n),n.at===t.length?Number.isFinite(r.value)?r:Vt(`结果不是有限数字。`):Vt(`「${t[n.at]}」后面的内容无法识别,请检查是否漏了运算符。`)):r}function $t(e){return String(!Number.isFinite(e)||Number.isInteger(e)&&Math.abs(e)<1e21?e:Number(e.toPrecision(12)))}function en(e){let t=e.trim();if(!t)return{ok:!1,reason:`请输入时间戳或日期。`};if(/^\d+$/.test(t)){let e=Number(t);if(!Number.isFinite(e))return{ok:!1,reason:`这个数字太大,无法表示。`};let n=t.length<=11?e*1e3:e;return!Number.isFinite(n)||Math.abs(n)>864e13?{ok:!1,reason:`这个时间戳超出了日期能表示的范围。`}:{ok:!0,ms:n}}let n=Date.parse(t);return Number.isNaN(n)?{ok:!1,reason:`看不懂这个日期。试试 1757000000、2026-10-08 或 2026-10-08T09:00:00。`}:{ok:!0,ms:n}}var tn=e=>String(Math.abs(e)).padStart(2,`0`);function nn(e){let t=new Date(e);return Number.isNaN(t.getTime())?null:{local:`${t.getFullYear()}-${tn(t.getMonth()+1)}-${tn(t.getDate())} ${tn(t.getHours())}:${tn(t.getMinutes())}:${tn(t.getSeconds())}`,iso:t.toISOString(),seconds:String(Math.floor(e/1e3)),milliseconds:String(e)}}var rn={workspaces:[],conversations:[],subagentRuns:[],queuedMessages:[]},an=e=>{if(typeof e!=`string`||e.length===0)return``;let t=new Date(e);return Number.isNaN(t.getTime())?``:new Intl.DateTimeFormat(`zh-CN`,{hour:`2-digit`,minute:`2-digit`}).format(t)},on=6e4,sn=60*on,cn=24*sn,ln=7*cn,un=30*cn,dn=365*cn,fn=(e,t)=>{let n=new Date(e);if(Number.isNaN(n.getTime()))return``;let r=t-n.getTime();return r<3e4?`now`:r<sn?`${Math.max(1,Math.floor(r/on))}m ago`:r<cn?`${Math.floor(r/sn)}h ago`:r<ln?`${Math.floor(r/cn)}d ago`:r<un?`${Math.floor(r/ln)}w ago`:r<dn?`${Math.floor(r/un)}mo ago`:`${Math.floor(r/dn)}y ago`},pn=(e,t)=>e.updatedAt<t.updatedAt?1:e.updatedAt>t.updatedAt?-1:0,mn=(e,t)=>{let n=e.archivedAt??``,r=t.archivedAt??``;return n<r?1:n>r?-1:0},hn=e=>{if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?``:`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`},gn=1e3,_n=3e4,vn=async e=>{try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}let t=document.createElement(`textarea`);t.value=e,t.setAttribute(`readonly`,``),t.style.cssText=`position:fixed;top:0;left:0;width:1px;height:1px;padding:0;border:0;opacity:0;pointer-events:none`,document.body.appendChild(t);try{return t.select(),t.setSelectionRange(0,t.value.length),document.execCommand(`copy`)}catch{return!1}finally{t.remove()}},yn={model:`模型`,thinking:`思考`,agent:`智能体`,subagent:`子智能体`},bn={model:`模型`,thinking:`思考等级`,agent:`智能体`,subagent:`子智能体`},xn={model:`选择模型`,thinking:`选择思考等级`,agent:`选择智能体`,subagent:`选择子智能体`},Sn=`图文`,Cn=e=>e.imageInput?Sn:void 0,wn=e=>e.normalize(`NFKD`).replace(/\p{M}/gu,``).toLowerCase(),Tn=(e,t)=>{let n=wn(t.trim());return n?e.filter(e=>wn(`${e.label} ${e.detail??``} ${e.badge??``}`).includes(n)):e};function En({onClose:e,onCreate:t}){let[n,r]=(0,l.useState)(),[i,a]=(0,l.useState)(!0),[o,s]=(0,l.useState)(),[c,u]=(0,l.useState)(``),d=async e=>{a(!0),s(void 0);try{let t=await fetch(`/api/fs/dirs${e?`?path=${encodeURIComponent(e)}`:``}`),n=await t.json();if(!t.ok)throw Error(n.error??`HTTP ${t.status}`);r(n),u(n.suggestedName)}catch(e){s(e instanceof Error?e.message:`目录加载失败`)}finally{a(!1)}};return(0,l.useEffect)(()=>{d()},[]),(0,l.useEffect)(()=>{let t=t=>{t.key===`Escape`&&e()};return window.addEventListener(`keydown`,t),()=>window.removeEventListener(`keydown`,t)},[e]),(0,j.jsx)(`div`,{className:`overlay`,onClick:e,children:(0,j.jsxs)(`div`,{className:`picker`,onClick:e=>e.stopPropagation(),children:[(0,j.jsx)(`h2`,{children:`选择工作区目录`}),(0,j.jsx)(`div`,{className:`picker-path`,children:n?.path??(i?`加载中…`:`—`)}),(0,j.jsxs)(`div`,{className:`picker-list`,children:[i&&(0,j.jsx)(`div`,{className:`picker-status`,children:`加载中…`}),!i&&o&&(0,j.jsxs)(`div`,{className:`picker-error`,children:[o,(0,j.jsx)(`button`,{onClick:()=>void d(n?.path),children:`重试`})]}),!i&&!o&&n?.parent&&(0,j.jsx)(`button`,{className:`picker-dir`,onClick:()=>void d(n.parent??void 0),children:`📁 ..`}),!i&&!o&&n?.entries.map(e=>(0,j.jsxs)(`button`,{className:`picker-dir`,onClick:()=>void d(e.path),children:[`📁 `,e.name]},e.path)),!i&&!o&&n&&n.entries.length===0&&(0,j.jsx)(`div`,{className:`picker-status`,children:`此目录下没有子目录`}),!i&&!o&&n?.truncated&&(0,j.jsx)(`div`,{className:`picker-status`,children:`目录过多,仅显示前 2000 项`})]}),(0,j.jsxs)(`label`,{className:`picker-name`,children:[`名称`,(0,j.jsx)(`input`,{value:c,onChange:e=>u(e.target.value),placeholder:`工作区名称`})]}),(0,j.jsxs)(`div`,{className:`picker-actions`,children:[(0,j.jsx)(`button`,{className:`picker-cancel`,onClick:e,children:`取消`}),(0,j.jsx)(`button`,{className:`picker-ok`,disabled:!c.trim()||i||!!o||!n,onClick:()=>n&&t(c.trim(),n.path),children:`使用这个目录`})]})]})})}var Dn={timeout:`扩展提问超时,已取消`,aborted:`运行已停止,扩展提问已取消`,expired:`运行已结束,扩展提问已取消`},On=10;function kn(e,t){if(!t)return`正在从 Pi 读取${e}列表…`;if(t.source!==`pi`)return`读取 Pi ${e}列表失败:${t.error??`未知原因`}`}function An(e){if(!e)return`正在读取 agent 列表…`;if(e.source!==`directory`)return`读取 agent 列表失败:${e.error??`未知原因`}`;if(e.problems.length)return`${e.problems.length} 个 agent 文件无法使用:${e.problems.map(e=>e.file).join(`、`)}`;if(!e.agents.length)return`${e.directory} 下没有 primary agent`}var jn=e=>Math.abs(e)<1e3?String(e):`${(e/1e3).toFixed(1).replace(/\.0$/,``)}k`;function Mn(e){if(e===void 0||!Number.isFinite(e))return``;let t=Math.max(0,e);return t<1e3?`${Math.round(t)}ms`:t<6e4?`${(t/1e3).toFixed(1)}s`:`${Math.floor(t/6e4)}分${Math.round(t%6e4/1e3)}秒`}var Nn={dispatch:`派发时(子进程还没起来)`,prompt:`派活时(Pi 拒收了任务)`,turn:`生成回答时`,tool:`调用工具时`,settle:`收尾时`};function Pn({call:e,index:t,expanded:n,onToggle:r}){let i=e.args??[];return(0,j.jsxs)(`div`,{className:`call-block call-block-${e.status??`running`}`,"data-call-block":t,"data-call-tool":e.label,"data-call-detail":e.detail??void 0,"data-call-status":e.status??`running`,"data-call-expanded":n?`true`:`false`,"data-call-arg-count":i.length,children:[(0,j.jsx)(`button`,{type:`button`,className:`call-fold-edge`,"data-call-fold-edge":t,"aria-expanded":n,"aria-label":`${n?`折叠`:`展开`} ${e.label} 调用`,title:n?`折叠这次调用`:`展开这次调用`,onClick:r}),(0,j.jsxs)(`div`,{className:`call-head-row`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`call-head`,"data-call-head":t,"aria-expanded":n,onClick:r,children:[(0,j.jsx)(`span`,{className:`call-chevron`,"aria-hidden":`true`,children:n?`▾`:`▸`}),(0,j.jsx)(`span`,{className:`call-glyph`,"aria-hidden":`true`,children:e.status===`error`?`✕`:e.status===`ok`?`✓`:`·`}),(0,j.jsx)(`span`,{className:`call-label`,children:e.label}),e.detail&&(0,j.jsx)(`span`,{className:`call-detail`,title:e.detail,children:e.detail}),e.durationMs!==void 0&&(0,j.jsx)(`span`,{className:`call-duration`,children:Mn(e.durationMs)})]}),n&&(0,j.jsx)(`button`,{type:`button`,className:`call-fold-top`,"data-call-fold-top":t,onClick:r,children:`收起`})]}),n&&(0,j.jsx)(`div`,{className:`call-args`,"data-call-args":i.length,children:i.length===0?(0,j.jsx)(`div`,{className:`call-arg call-arg-empty`,"data-call-arg-empty":t,children:`(这次调用没有可显示的参数)`}):i.map(e=>(0,j.jsxs)(`div`,{className:`call-arg`,"data-call-arg":e.key,"data-call-arg-value":e.value,children:[(0,j.jsx)(`span`,{className:`call-arg-key`,children:e.key}),(0,j.jsx)(`span`,{className:`call-arg-value`,title:e.value,children:e.value})]},e.key))})]})}function Fn({run:e,name:t,expanded:n,onToggle:r,onStop:i}){let a=e.toolCalls??[],o=n?a:a.slice(-10),s=a.length-o.length,c=e.status===`running`,u=e.output??``,d=e.dispatchedBy===`model`,[f,p]=(0,l.useState)(0);(0,l.useEffect)(()=>{if(!c)return;p(Date.now());let e=window.setInterval(()=>p(Date.now()),200);return()=>window.clearInterval(e)},[c,e.startedAt]);let m=Date.parse(e.startedAt),h=c&&f>0&&Number.isFinite(m)?f-m:void 0,g=[...a].reverse().find(e=>e.status===void 0)?.label;return(0,j.jsxs)(`article`,{className:`subagent-card subagent-${e.status}${d?` subagent-by-model`:``}`,"data-subagent-card":e.id,"data-subagent-status":e.status,"data-subagent-agent":e.agentId,"data-subagent-tools":a.length,"data-subagent-dispatched-by":d?`model`:`human`,children:[(0,j.jsxs)(`div`,{className:`subagent-head`,children:[(0,j.jsx)(`span`,{className:`subagent-badge`,children:`子智能体`}),d&&(0,j.jsxs)(`span`,{className:`subagent-source`,"data-subagent-source":`model`,title:`primary 模型自己决定派这个子智能体去干活`,children:[(0,j.jsx)(`span`,{className:`subagent-source-glyph`,"aria-hidden":`true`,children:`⚡`}),`模型自主派发`]}),(0,j.jsx)(`strong`,{className:`subagent-name`,"data-subagent-name":`1`,children:t||e.agentId}),(0,j.jsx)(`span`,{className:`subagent-status`,"data-subagent-status-text":`1`,children:c?`运行中`:e.status===`completed`?`已完成`:e.status===`stopped`?`已停止`:`失败`}),c?h!==void 0&&(0,j.jsxs)(`span`,{className:`subagent-clock`,"data-subagent-elapsed":`1`,"data-subagent-elapsed-ms":h,children:[`已运行 `,Mn(h)]}):e.durationMs!==void 0&&(0,j.jsxs)(`span`,{className:`subagent-duration`,"data-subagent-duration":`1`,"data-subagent-duration-ms":e.durationMs,children:[`用时 `,Mn(e.durationMs)]}),c&&(0,j.jsx)(`button`,{type:`button`,className:`subagent-stop`,"data-subagent-stop":e.id,onClick:i,children:`停止`})]}),c&&e.activity&&(0,j.jsxs)(`div`,{className:`subagent-activity`,"data-subagent-activity":e.activity.kind,"data-subagent-activity-at":e.activity.at,children:[(0,j.jsx)(`span`,{className:`subagent-activity-dot`,"aria-hidden":`true`}),e.activity.kind===`tool`?`正在调用 ${e.activity.label??`工具`}`:`正在思考…`]}),(0,j.jsxs)(`div`,{className:`subagent-task`,"data-subagent-task":`1`,children:[d&&(0,j.jsx)(`span`,{className:`subagent-task-source`,"data-subagent-model-task":`1`,children:`模型给的任务`}),e.task]}),(0,j.jsx)(`div`,{className:`subagent-output`,"data-subagent-output":`1`,"data-live-length":u.length,children:u||(c?`…`:e.outputTruncated?`(已按 50 KB 上限截断,浏览器仍收到完整内容)`:`(没有输出)`)}),e.failure&&(0,j.jsxs)(`div`,{className:`subagent-failure`,"data-subagent-failure":`1`,"data-subagent-failure-stage":e.failure.stage,children:[(0,j.jsx)(`span`,{className:`subagent-failure-label`,children:`卡在`}),(0,j.jsx)(`span`,{className:`subagent-failure-stage`,"data-subagent-failure-text":`1`,children:Nn[e.failure.stage]}),e.failure.stage===`tool`&&g&&(0,j.jsxs)(`span`,{className:`subagent-failure-tool`,"data-subagent-failure-tool":`1`,children:[`· 正在跑 `,g]}),a.length>0&&(0,j.jsxs)(`span`,{className:`subagent-failure-progress`,children:[`· 死前已尝试 `,a.length,` 次工具调用`]})]}),e.error&&(0,j.jsx)(`div`,{className:`subagent-error`,"data-subagent-error":`1`,children:e.error}),a.length>0&&(0,j.jsxs)(`div`,{className:`subagent-tools`,"data-subagent-tool-count":a.length,children:[s>0&&!n&&(0,j.jsxs)(`button`,{type:`button`,className:`subagent-more`,"data-subagent-hidden":s,onClick:r,children:[`… 另有 `,s,` 条工具调用`]}),o.map((e,t)=>(0,j.jsxs)(`div`,{className:`subagent-tool${e.status?` subagent-tool-${e.status}`:``}`,"data-subagent-tool":e.label,"data-subagent-tool-detail":e.detail??void 0,"data-subagent-tool-status":e.status??`running`,children:[(0,j.jsx)(`span`,{className:`subagent-tool-glyph`,"aria-hidden":`true`,children:e.status===`error`?`✕`:e.status===`ok`?`✓`:`·`}),(0,j.jsx)(`span`,{className:`subagent-tool-label`,children:e.label}),e.detail&&(0,j.jsx)(`span`,{className:`subagent-tool-detail`,title:e.detail,children:e.detail}),e.durationMs!==void 0&&(0,j.jsx)(`span`,{className:`subagent-tool-duration`,children:Mn(e.durationMs)})]},`${t}:${e.label}`))]}),e.usage&&(0,j.jsxs)(`div`,{className:`subagent-usage`,"data-subagent-usage":`1`,"data-subagent-turns":e.usage.turns,children:[(0,j.jsxs)(`span`,{children:[e.usage.turns,` turns`]}),(0,j.jsxs)(`span`,{children:[`↑`,jn(e.usage.input)]}),(0,j.jsxs)(`span`,{children:[`↓`,jn(e.usage.output)]}),e.usage.cacheRead>0&&(0,j.jsxs)(`span`,{children:[`cache↓`,jn(e.usage.cacheRead)]}),e.usage.cacheWrite>0&&(0,j.jsxs)(`span`,{children:[`cache↑`,jn(e.usage.cacheWrite)]}),e.usage.cost>0&&(0,j.jsxs)(`span`,{children:[`$`,e.usage.cost.toFixed(4)]})]}),a.length>10&&(0,j.jsx)(`button`,{type:`button`,className:`subagent-collapse`,"data-subagent-collapse":e.id,"aria-expanded":n,onClick:r,children:n?`收起`:`展开全部 ${a.length} 条`})]})}function In({items:e,pi:t,running:n,onCancel:r,onSteer:i}){let[a,o]=(0,l.useState)(!1);if(!e.length)return null;let s=e.filter(e=>e.state===`sending`);return(0,j.jsxs)(`section`,{className:`queue-dock`,"data-queue-dock":`1`,"data-queue-count":e.length,"data-queue-sending":s.length,"aria-label":`排队等待发送的消息`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`queue-dock-head`,"data-queue-collapse":`1`,"aria-expanded":!a,onClick:()=>o(e=>!e),children:[(0,j.jsx)(`span`,{className:`chevron`,children:a?`▸`:`▾`}),(0,j.jsxs)(`strong`,{children:[e.length,` 条待发送`]}),s.length>0&&(0,j.jsxs)(`span`,{className:`queue-dock-badge`,"data-queue-badge":`sending`,children:[s.length,` 条已交给 Agent`]}),a&&(0,j.jsx)(`span`,{className:`queue-dock-preview`,children:e[0].content})]}),!a&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`p`,{className:`queue-dock-note`,"data-queue-note":`steer`,children:[n?`「插队」= 当前这一批工具调用跑完就插进来,不用等整个任务结束;正在跑单个长工具时无法打断。`:`当前没有正在运行的这一轮,「插队」会等下一轮开始时发出。`,t&&t.steering.length>0&&` Pi 手上还有 ${t.steering.length} 条插队消息在等下一个工具调用边界。`]}),(0,j.jsx)(`ul`,{className:`queue-dock-list`,children:e.map((e,t)=>{let a=e.state===`sending`,o=e.content||(e.images?.length?`【图片】(${e.images.length})`:``);return(0,j.jsxs)(`li`,{className:`queue-row ${a?`queue-row-sending`:`queue-row-queued`}`,"data-queue-id":e.id,"data-queue-state":e.state,children:[(0,j.jsx)(`span`,{className:`queue-index`,"aria-hidden":`true`,children:t+1}),(0,j.jsx)(`span`,{className:`queue-text`,title:o,children:o}),(0,j.jsx)(`span`,{className:`queue-state`,"data-queue-state-label":a?`sending`:`queued`,children:a?`投递中…`:`待发送`}),a?(0,j.jsx)(`span`,{className:`queue-locked`,"data-queue-locked":e.id,children:`已交给 Agent,取消不掉`}):(0,j.jsxs)(j.Fragment,{children:[n?(0,j.jsx)(`button`,{type:`button`,className:`queue-steer`,"data-queue-steer":e.id,title:`插队:当前这一批工具调用跑完后插入,不用等整个任务结束`,"aria-label":`把「${o}」插队发送:当前这一批工具调用跑完后插入`,onClick:()=>i(e.id),children:`插队`}):(0,j.jsx)(`span`,{className:`queue-steer-idle`,"data-queue-steer-idle":e.id,title:`没有正在运行的这一轮,现在无法插队`,children:`未运行,暂不能插队`}),(0,j.jsx)(`button`,{type:`button`,className:`queue-cancel`,"data-queue-cancel":e.id,title:`取消这条排队消息,它不会被发出`,"aria-label":`取消排队消息「${o}」`,onClick:()=>r(e.id),children:`取消`})]})]},e.id)})})]})]})}function Ln({request:e,onAnswer:t}){let[n,r]=(0,l.useState)(e.prefill??``),i=e.method===`input`||e.method===`editor`,a=(0,j.jsx)(`button`,{type:`button`,className:`extui-cancel`,onClick:()=>t({cancelled:!0}),children:`取消提问`});return(0,j.jsxs)(`article`,{className:`extui-card extui-${e.method}`,"data-request-id":e.requestId,"data-method":e.method,children:[(0,j.jsxs)(`div`,{className:`extui-head`,children:[(0,j.jsx)(`span`,{className:`extui-badge`,children:`扩展提问`}),e.timeoutMs!==void 0&&(0,j.jsxs)(`span`,{className:`extui-deadline`,children:[Math.round(e.timeoutMs/1e3),`s 超时`]})]}),(0,j.jsx)(`h3`,{className:`extui-title`,children:e.title||e.method}),e.method===`confirm`&&(0,j.jsx)(`p`,{className:`extui-body`,children:e.message}),e.method===`select`&&(0,j.jsxs)(`div`,{className:`extui-options`,children:[(e.options??[]).map(e=>(0,j.jsx)(`button`,{type:`button`,className:`extui-option`,onClick:()=>t({value:e}),children:e},e)),(e.options??[]).length===0&&(0,j.jsx)(`p`,{className:`extui-body`,children:`扩展没有提供任何选项`})]}),i&&(0,j.jsxs)(`form`,{className:`extui-form`,onSubmit:e=>{e.preventDefault(),n.trim()&&t({value:n})},children:[e.method===`input`?(0,j.jsx)(`input`,{className:`extui-field`,value:n,onChange:e=>r(e.target.value),placeholder:e.placeholder??``}):(0,j.jsx)(`textarea`,{className:`extui-field`,value:n,onChange:e=>r(e.target.value)}),(0,j.jsxs)(`div`,{className:`extui-actions`,children:[(0,j.jsx)(`button`,{type:`submit`,className:`extui-primary`,disabled:!n.trim(),children:`提交`}),a]})]}),!i&&(0,j.jsxs)(`div`,{className:`extui-actions`,children:[e.method===`confirm`&&(0,j.jsx)(`button`,{type:`button`,className:`extui-primary`,onClick:()=>t({confirmed:!0}),children:`确认`}),e.method===`confirm`&&(0,j.jsx)(`button`,{type:`button`,className:`extui-no`,onClick:()=>t({confirmed:!1}),children:`拒绝`}),a]})]})}function Rn({initial:e,label:t,onCommit:n,onClose:r}){let[i,a]=(0,l.useState)(e),o=(0,l.useRef)(null),s=(0,l.useRef)(!1);(0,l.useEffect)(()=>{o.current?.focus(),o.current?.select()},[]);let c=!i.trim(),u=()=>{s.current=!0,r()},d=()=>{if(c)return;let t=i.trim();(t===e||n(t))&&u()};return(0,j.jsxs)(`div`,{className:`inline-edit`,"data-editing":`1`,children:[(0,j.jsx)(`input`,{ref:o,className:`inline-edit-input`,value:i,"aria-label":t,onChange:e=>a(e.target.value),onKeyDown:e=>{e.key===`Enter`?(e.preventDefault(),d()):e.key===`Escape`&&(e.preventDefault(),u())},onBlur:()=>{s.current||r()}}),(0,j.jsx)(`button`,{type:`button`,className:`inline-edit-ok`,title:`确认重命名`,"aria-label":`确认重命名`,disabled:c,onMouseDown:e=>e.preventDefault(),onClick:d,children:`✓`}),(0,j.jsx)(`button`,{type:`button`,className:`inline-edit-cancel`,title:`取消重命名`,"aria-label":`取消重命名`,onMouseDown:e=>e.preventDefault(),onClick:u,children:`✗`})]})}function zn({kind:e,label:t,value:n,detail:r,options:i,disabled:a,note:o,onChoose:s,scope:c}){let[u,d]=(0,l.useState)(!1),[f,p]=(0,l.useState)(``),[m,h]=(0,l.useState)(0),g=(0,l.useRef)(null),_=(0,l.useRef)(null),v=(0,l.useRef)(null),y=(0,l.useRef)(null),b=(0,l.useRef)([]),x=i.find(e=>e.selected),S=Tn(i,f),C=S.length===0?-1:Math.min(Math.max(m,0),S.length-1),ee=C<0?void 0:S[C],w=(e=!1)=>{d(!1),e&&_.current?.focus()},te=()=>{p(``),h(Math.max(i.findIndex(e=>e.selected),0)),d(!0)},T=e=>h(t=>S.length?Math.min(Math.max(t+e,0),S.length-1):0);(0,l.useEffect)(()=>{if(!u)return;let e=e=>{g.current?.contains(e.target)||w()};return window.addEventListener(`mousedown`,e),()=>window.removeEventListener(`mousedown`,e)},[u]),(0,l.useEffect)(()=>{if(!u)return;let e=g.current,t=t=>{e?.contains(t.relatedTarget)||w()};return e?.addEventListener(`focusout`,t),()=>e?.removeEventListener(`focusout`,t)},[u]),(0,l.useEffect)(()=>{u&&y.current?.focus()},[u]),(0,l.useEffect)(()=>{u&&C>=0&&b.current[C]?.scrollIntoView({block:`nearest`})},[u,C]),(0,l.useLayoutEffect)(()=>{if(!u)return;let e=v.current;if(!e)return;e.style.setProperty(`--picker-nudge`,`0px`),e.style.setProperty(`--picker-drop`,`0px`);let t=e.getBoundingClientRect(),n=Math.min(window.innerWidth-8-t.right,Math.max(8-t.left,0)),r=Math.min(window.innerHeight-8-t.bottom,Math.max(8-t.top,0));e.style.setProperty(`--picker-nudge`,`${n}px`),e.style.setProperty(`--picker-drop`,`${r}px`)},[u,S.length,i.length]);let ne=e=>{u&&(e.key===`Escape`?(e.preventDefault(),w(!0)):e.key===`ArrowDown`?(e.preventDefault(),T(1)):e.key===`ArrowUp`?(e.preventDefault(),T(-1)):e.key===`Home`?(e.preventDefault(),h(0)):e.key===`End`?(e.preventDefault(),h(Math.max(S.length-1,0))):e.key===`Enter`&&(e.preventDefault(),ee&&(s(ee.key),w(!0))))},re=`picker-list-${c??e}`,E=t=>`picker-option-${c??e}-${t}`;return(0,j.jsxs)(`div`,{className:`session-picker-item session-picker-${e}`,ref:g,onKeyDown:u?ne:void 0,children:[(0,j.jsxs)(`button`,{ref:_,type:`button`,className:`session-picker-trigger`,disabled:a,"aria-haspopup":`listbox`,"aria-expanded":u,title:o??`${yn[e]}:${r?`${t} · ${r}`:t}`,"data-picker-trigger":e,"data-picker-value":n??t,"data-picker-selected":i.some(e=>e.selected),onClick:()=>u?w():te(),children:[(0,j.jsx)(`span`,{className:`session-picker-kind`,children:yn[e]}),(0,j.jsx)(`span`,{className:`session-picker-name`,children:t}),r&&(0,j.jsx)(`span`,{className:`session-picker-detail`,children:r}),(0,j.jsx)(`span`,{className:`session-picker-caret`,"aria-hidden":`true`,children:`▾`})]}),u&&(0,j.jsxs)(`div`,{className:`picker-menu`,ref:v,"data-picker-menu":e,"data-picker-highlight":C,children:[(0,j.jsxs)(`div`,{className:`picker-filter`,children:[(0,j.jsx)(`span`,{className:`picker-filter-icon`,"aria-hidden":`true`,children:`🔍`}),(0,j.jsx)(`input`,{ref:y,className:`picker-filter-input`,"data-picker-filter":e,role:`combobox`,"aria-label":`筛选${bn[e]}选项`,"aria-expanded":`true`,"aria-controls":re,"aria-autocomplete":`list`,"aria-activedescendant":ee?E(C):void 0,value:f,placeholder:`输入以筛选…`,autoComplete:`off`,spellCheck:!1,onChange:e=>{p(e.target.value),h(0)}}),f&&(0,j.jsx)(`button`,{type:`button`,className:`picker-filter-clear`,"data-picker-filter-clear":e,title:`清空筛选`,"aria-label":`清空筛选`,onMouseDown:e=>e.preventDefault(),onClick:()=>{p(``),h(0),y.current?.focus()},children:`✕`})]}),x&&!S.some(e=>e.key===x.key)&&(0,j.jsxs)(`div`,{className:`picker-current`,"data-picker-current":e,"data-picker-current-value":x.key,children:[(0,j.jsx)(`span`,{className:`picker-current-label`,children:`当前`}),(0,j.jsx)(`span`,{className:`picker-current-value`,children:x.label})]}),(0,j.jsxs)(`div`,{className:`picker-list`,role:`listbox`,id:re,"aria-label":xn[e],children:[S.map((e,t)=>(0,j.jsxs)(`button`,{id:E(t),type:`button`,role:`option`,"aria-selected":e.selected,ref:e=>{b.current[t]=e},className:`picker-option${e.selected?` selected`:``}${t===C&&!e.selected?` preview`:``}`,"data-picker-option":e.key,"data-picker-option-selected":e.selected,"data-picker-highlight":t===C,onClick:()=>{s(e.key),w(!0)},children:[e.color&&(0,j.jsx)(`span`,{className:`picker-option-swatch`,style:{background:e.color},"aria-hidden":`true`}),(0,j.jsx)(`span`,{className:`picker-option-name`,children:e.label}),e.badge&&(0,j.jsx)(`span`,{className:`picker-option-badge`,"data-picker-option-badge":e.badge,children:e.badge}),e.detail&&(0,j.jsx)(`span`,{className:`picker-option-detail`,children:e.detail}),e.selected&&(0,j.jsx)(`span`,{className:`picker-option-mark`,"aria-hidden":`true`,children:`✓`})]},e.key)),S.length===0&&(0,j.jsx)(`div`,{className:`picker-empty`,"data-picker-empty":e,children:`没有匹配「${f.trim()}」的${bn[e]}`})]})]})]})}var Bn=`__pi_default__`;function Vn({workspace:e,catalog:t,agents:n,onSave:r,onRename:i,onClose:a}){let[o,s]=(0,l.useState)(e.defaultAgentId),[c,u]=(0,l.useState)(e.defaultModel),[d,f]=(0,l.useState)(e.defaultThinkingLevel);(0,l.useEffect)(()=>{let e=e=>{e.key===`Escape`&&!e.defaultPrevented&&a()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[a]);let p=t?.source===`pi`,m=[{key:Bn,label:`跟随 Pi 默认`,detail:`不为新会话指定模型`,selected:c===void 0},...(t?.models??[]).map(e=>({key:`${e.provider}/${e.modelId}`,label:e.label,detail:e.detail,badge:Cn(e),selected:c?.provider===e.provider&&c.modelId===e.modelId}))],h=[{key:Bn,label:`跟随 Pi 默认`,detail:`不为新会话指定思考等级`,selected:d===void 0},...(t?.levels??[]).map(e=>({key:e,label:e,selected:e===d}))],g=e=>{if(e===Bn){u(void 0);return}let n=(t?.models??[]).find(t=>t.provider===e.split(`/`)[0]&&t.modelId===e.split(`/`)[1]);n&&u({provider:n.provider,modelId:n.modelId,label:n.label})},_=e=>f(e===Bn?void 0:e),v=[{key:Bn,label:`跟随 Pi 默认`,detail:`新会话不使用任何 agent 角色`,selected:o===void 0},...(n?.agents??[]).map(e=>({key:e.id,label:e.name,detail:e.toolSummary,color:e.color,selected:o===e.id}))];return(0,j.jsx)(`div`,{className:`overlay`,onClick:a,children:(0,j.jsxs)(`div`,{className:`picker settings-dialog`,"data-settings-dialog":`1`,onClick:e=>e.stopPropagation(),children:[(0,j.jsx)(`h2`,{children:`工作区设置`}),(0,j.jsxs)(`div`,{className:`settings-scope`,children:[e.name,` · 默认值只影响之后新建的会话,已有会话不变`]}),(0,j.jsxs)(`div`,{className:`settings-row`,children:[(0,j.jsx)(`span`,{className:`settings-label`,children:`默认智能体`}),(0,j.jsx)(zn,{kind:`agent`,scope:`settings-agent`,label:n?.agents.find(e=>e.id===o)?.name??`跟随 Pi 默认`,value:o??Bn,detail:o?`${n?.agents.find(e=>e.id===o)?.toolSummary??``}`:void 0,options:v,disabled:!n||n.source===`unavailable`,note:An(n),onChoose:e=>s(e===Bn?void 0:e)})]}),(0,j.jsxs)(`div`,{className:`settings-row`,children:[(0,j.jsx)(`span`,{className:`settings-label`,children:`默认模型`}),(0,j.jsx)(zn,{kind:`model`,scope:`settings-model`,label:c?.label??`跟随 Pi 默认`,value:c?`${c.provider}/${c.modelId}`:Bn,detail:c?`${c.provider}/${c.modelId}`:void 0,options:m,disabled:!p,note:kn(`模型`,t),onChoose:g})]}),(0,j.jsxs)(`div`,{className:`settings-row`,children:[(0,j.jsx)(`span`,{className:`settings-label`,children:`思考强度`}),(0,j.jsx)(zn,{kind:`thinking`,scope:`settings-thinking`,label:d??`跟随 Pi 默认`,value:d??Bn,options:h,disabled:!p,note:kn(`思考等级`,t),onChoose:_})]}),(0,j.jsxs)(`div`,{className:`picker-actions`,children:[(0,j.jsx)(`button`,{type:`button`,className:`settings-rename`,"data-settings-rename":`1`,onClick:i,children:`重命名工作区`}),(0,j.jsx)(`button`,{type:`button`,className:`picker-cancel`,"data-settings-cancel":`1`,onClick:a,children:`取消`}),(0,j.jsx)(`button`,{type:`button`,className:`picker-ok`,"data-settings-save":`1`,onClick:()=>r(o,c,d),children:`保存`})]})]})})}var Hn=[{id:`main`,label:`主`,name:`主 tab`},{id:`tools`,label:`工具`,name:`工具 tab`},{id:`files`,label:`文件`,name:`文件 tab`}],Un={pending:`未开始`,in_progress:`进行中`,completed:`已完成`},Wn={pending:`○`,in_progress:`◐`,completed:`✓`},Gn={high:`高`,medium:`中`,low:`低`};function Kn(e){let t=e.filter(e=>e.status!==`completed`).length;return e.length?t?`${t} 个未完成 / 共 ${e.length} 个`:`全部完成:${e.length} 个`:`0 个待办任务`}function qn({todo:e,index:t}){let n=e.id??`todo_${t}`;return(0,j.jsxs)(`li`,{className:`todo-item todo-${e.status}`,"data-todo-item":n,"data-todo-status":e.status,children:[(0,j.jsx)(`span`,{className:`todo-mark`,"aria-hidden":`true`,children:Wn[e.status]}),(0,j.jsx)(`span`,{className:`todo-text`,children:e.content}),(0,j.jsx)(`span`,{className:`todo-status`,"data-todo-status-text":`1`,children:Un[e.status]}),e.priority&&(0,j.jsx)(`span`,{className:`todo-priority`,"data-todo-priority":e.priority,children:Gn[e.priority]})]})}function Jn({tasks:e}){return(0,j.jsx)(`ul`,{className:`bg-list`,"data-bg-task-count":e.length,children:e.map((e,t)=>{let n=e.id||`bg_${t}`,r=e.status?.trim()||`未知状态`;return(0,j.jsxs)(`li`,{className:`bg-item`,"data-bg-task":n,"data-bg-task-status":e.status??`unknown`,children:[(0,j.jsx)(`span`,{className:`bg-title`,children:e.title?.trim()||e.id||`未命名任务 ${t+1}`}),(0,j.jsxs)(`span`,{className:`bg-meta`,children:[e.agentId?.trim()&&(0,j.jsx)(`span`,{className:`bg-agent`,"data-bg-agent":e.agentId,children:e.agentId}),(0,j.jsx)(`span`,{className:`bg-status`,children:r})]})]},n)})})}function Yn({todos:e,tasks:t,collapsed:n,onToggle:r,workspaceId:i,files:a,onOpenFile:o,activeTab:s,onSelectTab:c}){return(0,j.jsx)(`div`,{className:`right-rail${n?` right-rail-collapsed`:``}`,role:`complementary`,"aria-label":`右侧栏`,"data-right-rail":`1`,"data-right-rail-collapsed":n,children:n?(0,j.jsx)(`button`,{type:`button`,className:`right-rail-open`,"data-right-rail-open":`1`,title:`展开右侧栏`,"aria-label":`展开右侧栏`,onClick:r,children:`‹`}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`right-rail-head`,children:[(0,j.jsx)(`div`,{className:`right-tabs`,role:`tablist`,"aria-label":`右侧栏 tab`,"data-right-tab-count":Hn.length,children:Hn.map(e=>(0,j.jsx)(`button`,{type:`button`,role:`tab`,id:`right-tab-${e.id}`,className:`right-tab${e.id===s?` right-tab-active`:``}`,"data-right-tab":e.id,"aria-selected":e.id===s,"aria-controls":`right-panel-${e.id}`,title:e.name,"aria-label":e.name,onClick:()=>c(e.id),children:e.label},e.id))}),(0,j.jsx)(`button`,{type:`button`,className:`right-rail-collapse`,"data-right-rail-collapse":`1`,title:`收起右侧栏(聊天区会变宽)`,"aria-label":`收起右侧栏`,onClick:r,children:`›`})]}),Hn.filter(e=>e.id===s).map(n=>(0,j.jsxs)(`div`,{className:`right-rail-body`,role:`tabpanel`,id:`right-panel-${n.id}`,"aria-labelledby":`right-tab-${n.id}`,"data-right-panel":n.id,children:[n.id===`main`&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`rail-section-head`,children:[(0,j.jsx)(`h2`,{className:`rail-section-title`,children:`待办任务`}),(0,j.jsx)(`span`,{className:`rail-section-count`,"data-todo-summary":`1`,children:Kn(e)})]}),e.length>0?(0,j.jsx)(`ol`,{className:`todo-list`,"data-todo-count":e.length,children:e.map((e,t)=>(0,j.jsx)(qn,{todo:e,index:t},e.id??`todo_${t}`))}):(0,j.jsx)(`p`,{className:`rail-empty`,"data-todo-empty":`1`,children:`暂无待办任务。Agent 开始处理多步骤任务时,会自己把待办写到这里。`}),(0,j.jsxs)(`div`,{className:`rail-section-head`,children:[(0,j.jsx)(`h2`,{className:`rail-section-title`,children:`后台任务`}),(0,j.jsx)(`span`,{className:`rail-section-count`,"data-bg-summary":`1`,children:t.length?`${t.length} 个运行中`:`0 个`})]}),t.length>0?(0,j.jsx)(Jn,{tasks:t}):(0,j.jsx)(`p`,{className:`rail-empty`,"data-bg-empty":`1`,children:`当前没有正在运行的后台任务。`})]}),n.id===`tools`&&(0,j.jsx)(Qn,{}),n.id===`files`&&(0,j.jsx)(Qe,{workspaceId:i,files:a,onOpenFile:o})]},n.id))]})})}function Xn(){try{if(typeof window>`u`)return At.slice();let e=It(window.localStorage.getItem(Nt));return window.localStorage.getItem(`super-pi:tools:v1`)===null?At.slice():e}catch{return At.slice()}}function Zn(e){try{if(typeof window>`u`)return;window.localStorage.setItem(Nt,Lt(e))}catch{}}function Qn(){let[e,t]=(0,l.useState)(Xn),[n,r]=(0,l.useState)(),[i,a]=(0,l.useState)(``),[o,s]=(0,l.useState)(``),[c,u]=(0,l.useState)(),d=e.find(e=>e.id===n);return(0,l.useEffect)(()=>{Zn(e)},[e]),(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`rail-section-head`,children:[(0,j.jsx)(`h2`,{className:`rail-section-title`,children:`工具`}),(0,j.jsxs)(`span`,{className:`rail-section-count`,"data-tool-summary":`1`,children:[e.length,` 个`]})]}),e.length>0?(0,j.jsx)(`ul`,{className:`tool-grid`,"data-tool-count":e.length,children:e.map(e=>(0,j.jsxs)(`li`,{className:`tool-slot`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`tool-icon`,"data-tool-icon":e.id,"data-tool-kind":e.kind,"data-tool-state":e.id===n?`open`:`idle`,title:`打开${e.name}`,"aria-label":`打开${e.name}`,"aria-current":e.id===n?`true`:void 0,onClick:()=>r(t=>t===e.id?void 0:e.id),children:[(0,j.jsx)(`span`,{className:`tool-icon-glyph`,"aria-hidden":`true`,children:e.glyph}),(0,j.jsx)(`span`,{className:`tool-icon-name`,children:e.name})]}),e.kind===`link`&&(0,j.jsx)(`button`,{type:`button`,className:`tool-remove`,"data-tool-remove":e.id,title:`移除${e.name}`,"aria-label":`移除${e.name}`,onClick:()=>{t(t=>Bt(t,e.id)),n===e.id&&r(void 0)},children:`✕`})]},e.id))}):(0,j.jsx)(`p`,{className:`rail-empty`,"data-tool-empty":`1`,children:`还没有工具。从下面的预置列表挑一个,或者填一个自己的网址。`}),(0,j.jsx)(`div`,{className:`rail-section-head`,children:(0,j.jsx)(`h2`,{className:`rail-section-title`,children:`从预置列表添加`})}),(0,j.jsx)(`div`,{className:`tool-presets`,"data-tool-presets":kt.length,children:kt.map(n=>{let r=e.some(e=>e.kind===n.kind);return(0,j.jsxs)(`div`,{className:`tool-preset`,"data-tool-preset":n.kind,children:[(0,j.jsx)(`span`,{className:`tool-preset-glyph`,"aria-hidden":`true`,children:n.glyph}),(0,j.jsxs)(`span`,{className:`tool-preset-text`,children:[(0,j.jsx)(`strong`,{children:n.name}),(0,j.jsx)(`small`,{children:n.blurb})]}),(0,j.jsx)(`button`,{type:`button`,className:`tool-preset-add`,"data-tool-add-preset":n.kind,disabled:r,title:r?`${n.name}已经在工具栏里了`:`添加${n.name}`,"aria-label":r?`${n.name}已添加`:`添加${n.name}`,onClick:()=>t(e=>zt(e,n.kind)),children:r?`已添加`:`添加`})]},n.kind)})}),(0,j.jsx)(`div`,{className:`rail-section-head`,children:(0,j.jsx)(`h2`,{className:`rail-section-title`,children:`添加网址工具`})}),(0,j.jsx)(`p`,{className:`tool-hint`,children:`填一个网址,它会变成一个图标;点开后在弹窗里用按钮在新标签页打开。网址只接受 http / https / mailto。`}),(0,j.jsx)(`input`,{className:`tool-input`,"data-tool-url-input":`1`,value:i,maxLength:2048,placeholder:`https://example.com/工具`,"aria-label":`工具网址`,onChange:e=>{a(e.target.value),u(void 0)}}),(0,j.jsx)(`input`,{className:`tool-input`,"data-tool-url-name":`1`,value:o,maxLength:40,placeholder:`名称(可留空,默认用域名)`,"aria-label":`工具名称(可选)`,onChange:e=>s(e.target.value)}),(0,j.jsx)(`button`,{type:`button`,className:`tool-url-add`,"data-tool-url-add":`1`,disabled:!i.trim(),onClick:()=>{let n=Ft(i);if(!n.ok){u(n.reason);return}if(e.length>=32){u(`工具最多 32 个,先删掉一个再加。`);return}let r=e.map(e=>e.id);t(e=>[...e,{id:Rt(`link`,r),kind:`link`,name:o.trim()||$n(n.url),glyph:`↗`,url:n.url}]),a(``),s(``),u(void 0)},children:`添加网址工具`}),c&&(0,j.jsx)(`p`,{className:`tool-error`,"data-tool-error":`1`,role:`alert`,children:c}),(0,j.jsxs)(`p`,{className:`tool-hint`,"data-tool-scope-note":`1`,children:[`能自定义到哪:从上面挑预置工具,或自己填一个网址。`,(0,j.jsx)(`b`,{children:`没有开放「写一段脚本来执行」这一档`}),`——它在浏览器里等同于任意代码执行,会拿着本应用的权限跑。计算器是手写的算术解析器,不含 eval,也认不出变量名。`]}),d&&(0,j.jsx)(er,{tool:d,onClose:()=>r(void 0)})]})}function $n(e){try{return new URL(e,typeof window>`u`?`http://localhost`:window.location.href).hostname||e.slice(0,30)}catch{return e.slice(0,30)}}function er({tool:e,onClose:t}){return(0,l.useEffect)(()=>{let e=e=>{e.key===`Escape`&&t()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]),(0,u.createPortal)((0,j.jsx)(`div`,{className:`tool-overlay`,"data-tool-overlay":e.id,onClick:e=>{e.target===e.currentTarget&&t()},children:(0,j.jsxs)(`div`,{className:`tool-dialog`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`tool-dialog-title`,"data-tool-dialog":e.id,children:[(0,j.jsxs)(`div`,{className:`tool-dialog-head`,children:[(0,j.jsxs)(`h2`,{className:`tool-dialog-title`,id:`tool-dialog-title`,children:[(0,j.jsx)(`span`,{className:`tool-dialog-glyph`,"aria-hidden":`true`,children:e.glyph}),e.name]}),(0,j.jsx)(`button`,{type:`button`,className:`tool-dialog-close`,"data-tool-close":`1`,title:`关闭(Esc)`,"aria-label":`关闭${e.name}`,onClick:t,children:`✕`})]}),(0,j.jsxs)(`div`,{className:`tool-dialog-body`,children:[e.kind===`calculator`&&(0,j.jsx)(nr,{}),e.kind===`timestamp`&&(0,j.jsx)(rr,{}),e.kind===`link`&&(0,j.jsx)(ir,{tool:e})]})]})}),document.body)}function tr({image:e,onClose:t}){return(0,l.useEffect)(()=>{let e=e=>{e.key===`Escape`&&t()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]),(0,u.createPortal)((0,j.jsx)(`div`,{className:`lightbox-overlay`,"data-lightbox-overlay":`1`,onClick:e=>{e.target===e.currentTarget&&t()},children:(0,j.jsxs)(`div`,{className:`lightbox-dialog`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`lightbox-title`,"data-lightbox-dialog":`1`,children:[(0,j.jsxs)(`div`,{className:`lightbox-head`,children:[(0,j.jsx)(`h2`,{className:`lightbox-title`,id:`lightbox-title`,children:e.name||`图片大图`}),(0,j.jsx)(`button`,{type:`button`,className:`lightbox-close`,"data-lightbox-close":`1`,title:`关闭(Esc)`,"aria-label":`关闭大图`,onClick:t,children:`✕`})]}),(0,j.jsx)(`div`,{className:`lightbox-body`,children:(0,j.jsx)(`img`,{src:e.url,alt:e.name||`图片大图`,className:`lightbox-image`})})]})}),document.body)}function nr(){let[e,t]=(0,l.useState)(`12 * (3 + 4)`),[n,r]=(0,l.useState)(!1),i=Qt(e),a=e=>{r(!1),t(t=>n?e:t+e)};return(0,j.jsxs)(`div`,{className:`tool-calc`,"data-tool-calc":`1`,children:[(0,j.jsx)(`input`,{className:`tool-input tool-calc-input`,"data-calc-input":`1`,value:e,maxLength:240,"aria-label":`算式`,spellCheck:!1,autoComplete:`off`,placeholder:`例如 (12 + 8) / 4`,onChange:e=>{r(!1),t(e.target.value)},onKeyDown:e=>{e.key===`Enter`&&e.preventDefault()}}),(0,j.jsx)(`div`,{className:`tool-calc-keys`,"data-calc-keys":`1`,children:[[`7`,`7`],[`8`,`8`],[`9`,`9`],[`÷`,`/`],[`(`,`(`],[`)`,`)`],[`4`,`4`],[`5`,`5`],[`6`,`6`],[`×`,`*`],[`^`,`^`],[`%`,`%`],[`1`,`1`],[`2`,`2`],[`3`,`3`],[`-`,`-`],[`←`,`back`],[`C`,`clear`],[`0`,`0`],[`.`,`.`],[`+`,`+`]].map(([e,n])=>(0,j.jsx)(`button`,{type:`button`,className:`tool-calc-key`,"data-calc-key":n,"aria-label":e===`C`?`清空`:e===`←`?`退格`:`输入 ${e}`,onClick:()=>{n===`clear`?(t(``),r(!1)):n===`back`?(t(e=>e.slice(0,-1)),r(!1)):a(n)},children:e},e))}),i.ok?(0,j.jsx)(`p`,{className:`tool-calc-result`,"data-calc-result":`1`,"data-calc-value":String(i.value),children:$t(i.value)}):(0,j.jsx)(`p`,{className:`tool-calc-error`,"data-calc-error":`1`,role:`alert`,children:i.reason})]})}function rr(){let[e,t]=(0,l.useState)(``),n=en(e),r=n.ok?nn(n.ms):null;return(0,j.jsxs)(`div`,{className:`tool-stamp`,"data-tool-stamp":`1`,children:[(0,j.jsx)(`input`,{className:`tool-input`,"data-stamp-input":`1`,value:e,maxLength:64,spellCheck:!1,"aria-label":`时间戳或日期`,placeholder:`1757000000 或 2026-10-08T09:00:00`,onChange:e=>t(e.target.value)}),r?(0,j.jsxs)(`dl`,{className:`tool-stamp-out`,"data-stamp-result":`1`,children:[(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`本地时间`}),(0,j.jsx)(`dd`,{"data-stamp-local":`1`,children:r.local})]}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`ISO(UTC)`}),(0,j.jsx)(`dd`,{"data-stamp-iso":`1`,children:r.iso})]}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`秒`}),(0,j.jsx)(`dd`,{"data-stamp-seconds":`1`,children:r.seconds})]}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`dt`,{children:`毫秒`}),(0,j.jsx)(`dd`,{"data-stamp-ms":`1`,children:r.milliseconds})]})]}):(0,j.jsx)(`p`,{className:`tool-stamp-error`,"data-stamp-error":`1`,role:`alert`,children:n.ok?`这个日期无法显示。`:n.reason})]})}function ir({tool:e}){return(0,j.jsxs)(`div`,{className:`tool-link`,"data-tool-link":e.id,children:[(0,j.jsx)(`p`,{className:`tool-hint`,children:`这个网址工具保存了一个地址。点下面的按钮由浏览器在新标签页打开它。`}),(0,j.jsx)(`code`,{className:`tool-link-url`,"data-tool-link-url":e.id,children:e.url}),(0,j.jsx)(`a`,{className:`tool-link-open`,"data-tool-link-open":e.id,href:e.url,target:`_blank`,rel:`noopener noreferrer`,title:e.url,children:`在新标签页打开 ↗`})]})}var ar=`(max-width: 1100px)`,or=(e,t,n)=>Math.min(Math.max(e,t),Math.max(t,n));function sr(e,t,n){let r=Math.max(0,Math.round(n)-480),i=or(520,180,Math.max(180,r-240)),a=or(Math.round(e),180,i),o=or(640,240,Math.max(240,r-a));return{sidebar:a,rail:or(Math.round(t),240,o),sidebarMin:180,sidebarMax:i,railMin:240,railMax:o,sumCap:r}}var cr=`super-pi.rail-widths.v1`;function lr(){try{if(typeof window>`u`)return{};let e=window.localStorage.getItem(cr);if(e===null)return{};let t=JSON.parse(e),n=e=>typeof e==`number`&&Number.isFinite(e)&&e>0?Math.round(e):void 0;return{sidebar:n(t.sidebar),rail:n(t.rail)}}catch{return{}}}function ur(e){try{if(typeof window>`u`)return;window.localStorage.setItem(cr,JSON.stringify(e))}catch{}}function dr({side:e,width:t,min:n,max:r,label:i,onWidth:a}){let[o,s]=(0,l.useState)(!1),c=e=>e.shiftKey?64:16;return(0,j.jsx)(`div`,{className:`rail-resizer rail-resizer-${e}${o?` rail-resizer-dragging`:``}`,"data-rail-resizer":e,"data-rail-resizer-dragging":o?`true`:`false`,"data-rail-resizer-width":t,role:`separator`,"aria-orientation":`vertical`,"aria-label":i,"aria-valuenow":t,"aria-valuemin":n,"aria-valuemax":r,tabIndex:0,onMouseDown:i=>{i.preventDefault(),i.currentTarget.focus();let o=i.clientX,c=t;s(!0);let l=document.body,u=l.style.cursor,d=l.style.userSelect;l.style.cursor=`col-resize`,l.style.userSelect=`none`;let f=t=>{let i=e===`left`?t.clientX-o:o-t.clientX;a(or(c+i,n,r))},p=()=>{l.style.cursor=u,l.style.userSelect=d,s(!1),window.removeEventListener(`mousemove`,f),window.removeEventListener(`mouseup`,p)};window.addEventListener(`mousemove`,f),window.addEventListener(`mouseup`,p)},onKeyDown:i=>{let o=c(i);i.key===`ArrowLeft`?(i.preventDefault(),a(or(e===`left`?t-o:t+o,n,r))):i.key===`ArrowRight`?(i.preventDefault(),a(or(e===`left`?t+o:t-o,n,r))):i.key===`Home`?(i.preventDefault(),a(n)):i.key===`End`&&(i.preventDefault(),a(r))}})}function fr(){let[e,t]=(0,l.useState)(rn),[n,r]=(0,l.useState)(),[i,a]=(0,l.useState)(``),[o,s]=(0,l.useState)(!1),[c,u]=(0,l.useState)(),[d,f]=(0,l.useState)({}),[p,m]=(0,l.useState)(),[h,g]=(0,l.useState)(!1),_=(0,l.useRef)(void 0),[v,y]=(0,l.useState)({}),[b,x]=(0,l.useState)([]),[S,C]=(0,l.useState)([]),[ee,w]=(0,l.useState)(new Map),[te,T]=(0,l.useState)(new Map),[ne,re]=(0,l.useState)(),[E,ie]=(0,l.useState)(),[ae,oe]=(0,l.useState)(),[se,ce]=(0,l.useState)(),[le,ue]=(0,l.useState)(()=>typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(`(max-width: 1100px)`).matches),[de,fe]=(0,l.useState)(()=>typeof window>`u`?1440:window.innerWidth);(0,l.useEffect)(()=>{let e=()=>fe(window.innerWidth);return window.addEventListener(`resize`,e),e(),()=>window.removeEventListener(`resize`,e)},[]);let[pe,me]=(0,l.useState)(lr),he=sr(pe.sidebar??270,pe.rail??320,de);(0,l.useEffect)(()=>{ur({sidebar:he.sidebar,rail:he.rail})},[he.sidebar,he.rail]);let ge=e=>me(t=>({...t,sidebar:e})),_e=e=>me(t=>({...t,rail:e}));(0,l.useEffect)(()=>{if(typeof window>`u`||typeof window.matchMedia!=`function`)return;let e=window.matchMedia(ar),t=e=>{e.matches&&ue(!0)};return e.addEventListener(`change`,t),e.matches&&ue(!0),()=>e.removeEventListener(`change`,t)},[]);let[ve,ye]=(0,l.useState)(new Map),[be,xe]=(0,l.useState)({}),[Se,Ce]=(0,l.useState)({}),[D,O]=(0,l.useState)([]),[k,we]=(0,l.useState)(0),[Te,Ee]=(0,l.useState)(),[De,A]=(0,l.useState)(!1),Oe=(0,l.useRef)(null),Ae=(0,l.useRef)(0),je=(0,l.useRef)([]),Me=(0,l.useRef)(void 0),Ne=(0,l.useRef)(!1),[Pe,Fe]=(0,l.useState)(()=>Date.now());(0,l.useEffect)(()=>{let e=window.setInterval(()=>Fe(Date.now()),3e4);return()=>window.clearInterval(e)},[]);let Ie=(0,l.useMemo)(()=>e.conversations.filter(e=>!e.archivedAt),[e.conversations]),M=(0,l.useMemo)(()=>Ie.find(e=>e.id===n)??Ie[0],[n,Ie]);(0,l.useEffect)(()=>{Me.current=M?.id}),(0,l.useEffect)(()=>{O([])},[M?.id]);let[Le,Re]=(0,l.useState)([]),ze=Le.length>0?Le:M?[M.id]:[],Be=(0,l.useMemo)(()=>ze.map(e=>Ie.find(t=>t.id===e)).filter(e=>e!==void 0),[ze,Ie]),Ve=(0,l.useCallback)(e=>{r(e),Ge(`session`),Re(t=>t.includes(e)?t:t.length>0?[...t,e]:[...M?.id&&M.id!==e?[M.id]:[],e])},[M]),He=(0,l.useCallback)(e=>{let t=Le.indexOf(e);if(t<0)return;let n=Le.filter(t=>t!==e);if(Re(n),M?.id!==e)return;let i=n[Math.min(t,n.length-1)];i&&r(i)},[Le,M]),N=Ze(p),[Ue,We]=(0,l.useState)(Hn[0].id),[P,Ge]=(0,l.useState)(`session`);(0,l.useEffect)(()=>{P===`file`&&!N.active&&Ge(`session`)},[P,N.active]);let Ke=(0,l.useCallback)(e=>{N.setActivePath(e),Ge(`file`),We(`files`)},[N.setActivePath]),qe=(0,l.useCallback)(async e=>{await N.openFile(e),Ge(`file`)},[N.openFile]),Je=(0,l.useMemo)(()=>Be.map(e=>({id:`session:${e.id}`,rawId:e.id,kind:`session`,label:e.title,title:e.title,closable:Be.length>1||N.open.length>0})),[Be,N.open.length]),Xe=(0,l.useMemo)(()=>N.open.map(e=>({id:`file:${e.path}`,rawId:e.path,kind:`file`,label:e.name,title:e.path,closable:!0,badge:e.dirty?(0,j.jsx)(`span`,{className:`file-tab-badge`,"data-file-tab-dirty":e.path,"aria-label":`未保存`,children:`●`}):void 0})),[N.open]),Qe=(0,l.useMemo)(()=>[...Je,...Xe],[Je,Xe]),$e=P===`file`&&N.activePath?`file:${N.activePath}`:M?.id?`session:${M.id}`:void 0,et=(0,l.useCallback)(e=>{if(e.startsWith(`file:`)){let t=e.slice(5);Ke(t)}else if(e.startsWith(`session:`)){let t=e.slice(8);Ve(t)}},[Ke,Ve]),tt=(0,l.useCallback)(e=>{if(e.startsWith(`file:`)){let t=e.slice(5);N.closeFile(t),N.activePath===t&&N.open.length<=1&&Ge(`session`)}else if(e.startsWith(`session:`)){let t=e.slice(8);He(t)}},[N,He]),rt=N.active,it=M?.id;(0,l.useEffect)(()=>{it&&I({type:`conversation.select`,conversationId:it})},[it]);let F=(e,t=`info`)=>{if(!e)return;let n=++Ae.current;C(r=>[...r,{key:n,text:e,kind:t}]),je.current.push(window.setTimeout(()=>C(e=>e.filter(e=>e.key!==n)),7e3))},at=(e,t)=>{let n=e.findIndex(e=>e.id===t.id);if(n<0)return[t,...e];let r=[...e];return r[n]=t,r},ot=(e,t)=>{let n=e.findIndex(e=>e.id===t.id);if(n<0)return[t,...e];let r=[...e];return r[n]=t,r},st=(e,t)=>{if(t.blocking)x(n=>[...n.filter(n=>n.conversationId!==e||n.request.requestId!==t.requestId),{conversationId:e,request:t}]);else if(t.method===`notify`)F(t.message||t.title,t.notifyType??`info`);else if(t.method===`setStatus`){let e=t.statusKey??``;w(n=>{let r=new Map(n);return t.statusText===void 0?r.delete(e):r.set(e,t.statusText),r})}else if(t.method===`setWidget`){let e=t.widgetKey??``;T(n=>{let r=new Map(n);return t.widgetLines===void 0?r.delete(e):r.set(e,{lines:t.widgetLines,placement:t.widgetPlacement??`aboveEditor`}),r})}else t.method===`setTitle`?re(t.title):t.method===`set_editor_text`&&e===Me.current&&a(t.text??``)},ct=(e,t,n)=>{x(n=>n.filter(n=>n.conversationId!==e||n.request.requestId!==t));let r=Dn[n];r&&F(r,`warning`)};(0,l.useEffect)(()=>{let e=!1,n=0,i,a=()=>{if(e)return;let o=location.protocol===`https:`?`wss`:`ws`,c=new WebSocket(`${o}://${location.host}/ws`);_.current=c,c.onopen=()=>{e||(n=0,s(!0),c.send(JSON.stringify({type:`catalog.fetch`})),c.send(JSON.stringify({type:`agent.catalog.fetch`})),c.send(JSON.stringify({type:`subagent.catalog.fetch`})))},c.onclose=()=>{e||(Ne.current=!1,s(!1),i=window.setTimeout(a,Math.min(_n,gn*2**n++)))},c.onmessage=({data:n})=>{if(e)return;let i=JSON.parse(n);i.type===`state`?(Ne.current=!1,t(i.state),r(e=>{let t=i.state.conversations.filter(e=>!e.archivedAt);return e&&t.some(t=>t.id===e)?e:t[0]?.id}),m(e=>e&&i.state.workspaces.some(t=>t.id===e)?e:i.state.workspaces[0]?.id)):i.type===`message.delta`?t(e=>({...e,conversations:e.conversations.map(e=>e.id===i.conversationId?{...e,messages:e.messages.map(e=>e.id===i.messageId?{...e,content:e.content+i.delta}:e)}:e)})):i.type===`error`?(u(i.message),Ne.current&&(Ne.current=!1,F(`重命名失败:${i.message}`,`error`))):i.type===`extension.ui`?st(i.conversationId,i.request):i.type===`extension.ui.closed`?ct(i.conversationId,i.requestId,i.reason):i.type===`model.catalog`?ie(i.catalog):i.type===`agent.catalog`?oe(i.catalog):i.type===`subagent.catalog`?ce(i.catalog):i.type===`subagent.event`?t(e=>({...e,subagentRuns:at(e.subagentRuns??[],i.run)})):i.type===`workflow.event`?t(e=>({...e,workflows:ot(e.workflows??[],i.workflow)})):i.type===`message.tools`?t(e=>({...e,conversations:e.conversations.map(e=>e.id===i.conversationId?{...e,messages:e.messages.map(e=>e.id===i.messageId?{...e,toolCalls:i.toolCalls}:e)}:e)})):i.type===`pi.queue`?ye(e=>{let t=new Map(e);return t.set(i.conversationId,{steering:i.steering,followUp:i.followUp}),t}):i.type===`conversation.fork.result`&&(Jn(e=>e===i.conversationId?void 0:e),F(i.ok?`已从「${i.title}」分叉出新会话,放在侧边栏最上面;没有切换过去。${i.messagesCopied?`复制了 ${i.messagesCopied} 条消息。`:`原会话还没有消息,只复制了会话本身。`}`:`分叉失败:${i.message}`,i.ok?`info`:`error`))}};return a(),()=>{e=!0,window.clearTimeout(i);for(let e of je.current)window.clearTimeout(e);_.current?.close()}},[]);let I=e=>_.current?.readyState===WebSocket.OPEN&&(_.current.send(JSON.stringify(e)),!0),dt=(e,t,n)=>I({type:`extension.ui.answer`,conversationId:e,requestId:t,...n}),ft=M?.model??E?.defaultModel,pt=M?.thinkingLevel??E?.defaultThinkingLevel,mt=E?.source===`pi`,ht=!!E?.models.find(e=>e.provider===ft?.provider&&e.modelId===ft?.modelId)?.imageInput,gt=(E?.models??[]).map(e=>({key:`${e.provider}/${e.modelId}`,label:e.label,detail:e.detail,badge:Cn(e),selected:ft?.provider===e.provider&&ft.modelId===e.modelId})),_t=(E?.levels??[]).map(e=>({key:e,label:e,selected:e===pt})),vt=e=>{if(!M)return;let[t,n]=e.split(`/`);t&&n&&I({type:`conversation.model`,conversationId:M.id,provider:t,modelId:n})},yt=e=>{M&&I({type:`conversation.thinking`,conversationId:M.id,level:e})},bt=ae?.agents.find(e=>e.id===M?.agentId),xt=[{key:Bn,label:`跟随 Pi 默认`,detail:`不使用任何 agent 角色`,selected:!M?.agentId},...(ae?.agents??[]).map(e=>({key:e.id,label:e.name,detail:e.toolSummary,color:e.color,selected:M?.agentId===e.id}))],Ct=bt?.model,wt=!!(Ct&&M?.model&&M.model.provider===Ct.provider&&M.model.modelId===Ct.modelId);bt?.thinkingLevel&&(M?.thinkingLevel,bt.thinkingLevel);let Tt=e=>{M&&I({type:`conversation.agent`,conversationId:M.id,agentId:e===Bn?null:e})},Et=b.filter(e=>e.conversationId===M?.id),Dt=(0,l.useMemo)(()=>(e.subagentRuns??[]).filter(e=>e.conversationId===M?.id),[e.subagentRuns,M?.id]),kt=(0,l.useMemo)(()=>(e.workflows??[]).filter(e=>e.conversationId===M?.id),[e.workflows,M?.id]),At=(0,l.useMemo)(()=>new Map(kt.map(e=>[e.id,e])),[kt]),jt=(0,l.useMemo)(()=>new Map((se?.agents??[]).map(e=>[e.id,e.name])),[se]),Mt=(0,l.useMemo)(()=>new Map((M?.messages??[]).map(e=>[e.id,e])),[M?.messages]),Nt=(0,l.useMemo)(()=>new Map(Dt.map(e=>[e.id,e])),[Dt]),Pt=(0,l.useMemo)(()=>{if(!M)return[];let e=M.messages.map((e,t)=>({at:Date.parse(e.createdAt)||0,seq:t,key:`m:${e.id}`}));return Dt.forEach((t,n)=>e.push({at:Date.parse(t.startedAt)||0,seq:e.length+n,key:`r:${t.id}`})),kt.forEach((t,n)=>e.push({at:Date.parse(t.startedAt)||0,seq:e.length+n,key:`w:${t.id}`})),e.sort((e,t)=>e.at-t.at||e.seq-t.seq).map(e=>e.key)},[M,Dt,kt]),Ft=e=>xe(t=>({...t,[e]:!t[e]})),It=(e,t)=>Ce(n=>({...n,[`${e}:${t}`]:!n[`${e}:${t}`]})),Lt=e=>{I({type:`subagent.stop`,runId:e})||F(`连接断开,无法停止子智能体,请重试`,`error`)},Rt=e=>{I({type:`workflow.stop`,workflowId:e})||F(`连接断开,无法停止编排,请重试`,`error`)},zt=e=>[...te].filter(([,t])=>t.placement===e).map(([e,t])=>{let n=t.lines;return(0,j.jsxs)(`div`,{className:`extui-widget`,"data-widget-key":e,"data-widget-lines":n.length,children:[n.slice(0,On).map((e,t)=>(0,j.jsx)(`div`,{children:e},`${t}:${e}`)),n.length>On&&(0,j.jsx)(`div`,{children:`… (widget truncated)`})]},e)}),Bt=(e,t)=>{I({type:`workspace.create`,name:e,path:t}),g(!1)},[Vt,Ht]=(0,l.useState)(),Ut=(e,t)=>Ht(n=>n?.kind===e&&n.id===t?n:{kind:e,id:t}),Wt=()=>Ht(void 0),Gt=(e,t)=>Vt?.kind===e&&Vt.id===t,Kt=(e,t,n)=>I(e===`workspace`?{type:`workspace.rename`,workspaceId:t,name:n}:{type:`conversation.rename`,conversationId:t,name:n})?(Ne.current=!0,Wt(),!0):(F(`连接断开,改名未保存,请重试`,`error`),!1),qt=t=>{let n=e.conversations.filter(e=>e.workspaceId===t.id).length;window.confirm(`删除工作区「${t.name}」?${n?`其中 ${n} 条会话将一并删除,`:``}此操作不可撤销。`)&&I({type:`workspace.delete`,workspaceId:t.id})},[L,Jt]=(0,l.useState)(),Yt=L?e.workspaces.find(e=>e.id===L):void 0,{theme:Xt,setTheme:Zt}=St(),[Qt,$t]=(0,l.useState)(!1),[en,tn]=(0,l.useState)(!1),nn=(e,t,n,r)=>{I({type:`workspace.settings`,workspaceId:e,model:n?{provider:n.provider,modelId:n.modelId}:null,thinkingLevel:r??null,agentId:t??null})?Jt(void 0):F(`连接断开,设置未保存,请重试`,`error`)},on=e=>{m(e),I({type:`conversation.create`,workspaceId:e})},sn=e=>{r(t=>t===e?void 0:t),I({type:`conversation.archive`,conversationId:e})},cn=e=>I({type:`conversation.unarchive`,conversationId:e}),ln=async e=>{if(!M){F(`请先选择或创建会话`,`error`);return}if(!ht){F(`当前模型不支持图片输入`,`error`);return}let t=[`image/png`,`image/jpeg`,`image/gif`,`image/webp`],n=e.filter(e=>t.includes(e.type)?e.size>5242880?(F(`图片「${e.name}」超过 5MB 上限`,`error`),!1):!0:(F(`不支持的文件格式「${e.name}」,仅支持 PNG/JPEG/GIF/WebP`,`error`),!1));if(n.length===0)return;let r=M.id;we(e=>e+n.length);for(let e of n)try{let t=await new Promise((t,n)=>{let r=new FileReader;r.onload=()=>{let e=r.result,n=e.indexOf(`,`);t(n>=0?e.slice(n+1):e)},r.onerror=n,r.readAsDataURL(e)}),n=await fetch(`/api/upload`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({conversationId:r,name:e.name,mimeType:e.type,data:t})});if(!(n.headers.get(`content-type`)??``).includes(`application/json`)){F(`服务器未返回 JSON 响应,请刷新或重启服务`,`error`);continue}if(n.ok){let e=await n.json();O(t=>[...t,{id:e.id,name:e.name,mimeType:e.mimeType,bytes:e.bytes}])}else{let e=await n.json().catch(()=>({error:`上传失败`}));F(e.error||`上传失败: ${n.status}`,`error`)}}catch(e){F(`上传错误: ${e instanceof Error?e.message:`网络错误`}`,`error`)}finally{we(e=>Math.max(0,e-1))}},un=e=>{let t=e.clipboardData?.items;if(!t)return;let n=[];for(let e=0;e<t.length;e++){let r=t[e];if(r.type.startsWith(`image/`)){let e=r.getAsFile();e&&n.push(e)}}if(n.length>0){if(!ht){F(`当前模型不支持图片输入`,`error`);return}e.preventDefault(),ln(n)}},dn=e=>{e.dataTransfer?.types?.includes(`Files`)&&(e.preventDefault(),A(!0))},yn=e=>{e.currentTarget.contains(e.relatedTarget)||A(!1)},bn=e=>{A(!1);let t=Array.from(e.dataTransfer?.files??[]).filter(e=>e.type.startsWith(`image/`));if(t.length>0){if(e.preventDefault(),!ht){F(`当前模型不支持图片输入`,`error`);return}ln(t)}},xn=e=>{e.preventDefault(),M&&(i.trim()||D.length!==0)&&(D.length>0&&!ht?F(`当前模型不支持图片输入,请移除图片或切换至支持图文的模型`,`error`):k>0?F(`图片正在上传中,请稍候…`,`info`):(I({type:`message.send`,conversationId:M.id,content:i,...D.length>0?{images:D}:{}}),a(``),O([])))},Sn=(0,l.useMemo)(()=>(e.queuedMessages??[]).filter(e=>e.conversationId===M?.id),[e.queuedMessages,M?.id]),wn=e=>{I({type:`message.cancel`,conversationId:M?.id??``,queueId:e})||F(`连接断开,取消没有生效,请重试`,`error`)},Tn=e=>{I({type:`message.steer`,conversationId:M?.id??``,queueId:e})||F(`连接断开,插队没有生效,请重试`,`error`)},[jn,Mn]=(0,l.useState)(),Nn=e=>{M&&!jn&&(I({type:`message.revert`,conversationId:M.id,messageId:e})?Mn(e):F(`连接断开,回退未执行,请重试`,`error`))};(0,l.useEffect)(()=>{M?.status!==`running`&&Mn(void 0)},[M?.id,M?.status]);let[Un,Wn]=(0,l.useState)(),Gn=(0,l.useRef)(void 0),Kn=async(e,t)=>{Gn.current&&clearTimeout(Gn.current);let n=await vn(t);Wn({id:e,kind:n?`copied`:`error`}),n||F(`复制失败:浏览器拒绝了剪贴板写入,可以手动选中这条消息的文字复制`,`error`),Gn.current=setTimeout(()=>Wn(void 0),2e3)};(0,l.useEffect)(()=>()=>{Gn.current&&clearTimeout(Gn.current)},[]);let[qn,Jn]=(0,l.useState)(),Xn=e=>{qn||(I({type:`conversation.fork`,conversationId:e})?Jn(e):F(`连接断开,分叉没有执行,请重试`,`error`))};return(0,j.jsxs)(`main`,{className:`shell${le?` shell-rail-collapsed`:``}`,"data-rail-collapsed":le,style:{"--sidebar-width":`${he.sidebar}px`,"--rail-col":le?void 0:`${he.rail}px`},children:[(0,j.jsxs)(`aside`,{children:[(0,j.jsxs)(`div`,{className:`brand`,children:[(0,j.jsx)(`span`,{children:`π`}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`strong`,{children:`SUPER PI`}),(0,j.jsx)(`small`,{children:`agent workspace`})]})]}),(0,j.jsx)(`div`,{className:`sidebar-actions`,children:(0,j.jsx)(`button`,{className:`workspace-new`,onClick:()=>g(!0),children:`+ 工作区`})}),(0,j.jsx)(`div`,{className:`label`,children:`工作区`}),(0,j.jsx)(`nav`,{children:e.workspaces.map(t=>{let n=e.conversations.filter(e=>e.workspaceId===t.id),r=n.filter(e=>!e.archivedAt).sort(pn),i=n.filter(e=>e.archivedAt).sort(mn),a=d[t.id]??!1,o=v[t.id]??!0;return(0,j.jsxs)(`section`,{className:`workspace-group`,children:[(0,j.jsx)(`div`,{className:`workspace-header`,children:Gt(`workspace`,t.id)?(0,j.jsx)(Rn,{initial:t.name,label:`重命名工作区 ${t.name}`,onCommit:e=>Kt(`workspace`,t.id,e),onClose:Wt}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`button`,{className:`workspace-toggle`,title:t.path,onClick:()=>{m(t.id),f(e=>({...e,[t.id]:!a}))},children:[(0,j.jsx)(`span`,{className:`chevron`,children:a?`▸`:`▾`}),(0,j.jsxs)(`span`,{children:[(0,j.jsx)(`strong`,{onDoubleClick:()=>Ut(`workspace`,t.id),children:t.name}),(0,j.jsx)(`small`,{children:t.path})]})]}),(0,j.jsx)(`button`,{className:`workspace-add`,title:`在此工作区新建会话`,onClick:()=>on(t.id),children:`+`}),(0,j.jsx)(`button`,{className:`workspace-settings`,title:`工作区设置(默认智能体 / 模型 / 思考强度)`,"aria-label":`工作区设置 ${t.name}`,onClick:()=>Jt(t.id),children:`⚙`}),(0,j.jsx)(`button`,{className:`workspace-delete`,title:`删除工作区`,onClick:()=>qt(t),children:`×`})]})}),!a&&(r.length?r.map(e=>(0,j.jsx)(`div`,{className:`conversation-row`,children:Gt(`conversation`,e.id)?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(Rn,{initial:e.title,label:`重命名会话 ${e.title}`,onCommit:t=>Kt(`conversation`,e.id,t),onClose:Wt}),(0,j.jsx)(`small`,{className:`conversation-time`,children:fn(e.updatedAt,Pe)})]}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`button`,{className:`conversation ${M?.id===e.id?`selected`:``}`,"data-conversation":e.id,title:e.title,"aria-label":`打开会话 ${e.title}`,onClick:()=>{Ve(e.id),m(t.id)},children:[(0,j.jsxs)(`span`,{onDoubleClick:()=>Ut(`conversation`,e.id),children:[`· `,e.title]}),(0,j.jsx)(`small`,{children:fn(e.updatedAt,Pe)})]}),(0,j.jsx)(`button`,{type:`button`,className:`conversation-fork`,"data-fork-conversation":e.id,"data-fork-state":qn===e.id?`pending`:`idle`,disabled:!!qn,title:`从此会话分叉出一个新会话`,"aria-label":`从会话 ${e.title} 分叉出一个新会话`,onClick:()=>Xn(e.id),children:`⑂`}),(0,j.jsx)(`button`,{className:`conversation-archive`,title:`归档会话`,"aria-label":`归档会话 ${e.title}`,onClick:()=>sn(e.id),children:`×`})]})},e.id)):(0,j.jsx)(`div`,{className:`conversation-empty`,children:`暂无会话`})),!a&&i.length>0&&(0,j.jsxs)(`div`,{className:`archived-group`,"data-archived-count":i.length,children:[(0,j.jsxs)(`button`,{className:`archived-toggle`,title:o?`展开已归档会话`:`收起已归档会话`,"aria-expanded":!o,onClick:()=>y(e=>({...e,[t.id]:!o})),children:[(0,j.jsx)(`span`,{className:`chevron`,children:o?`▸`:`▾`}),(0,j.jsxs)(`span`,{className:`archived-label`,children:[`Archived (`,i.length,`)`]})]}),!o&&i.map(e=>(0,j.jsx)(`div`,{className:`conversation-archived`,"data-archived-at":e.archivedAt,children:Gt(`conversation`,e.id)?(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(Rn,{initial:e.title,label:`重命名已归档会话 ${e.title}`,onCommit:t=>Kt(`conversation`,e.id,t),onClose:Wt}),(0,j.jsx)(`small`,{children:hn(e.archivedAt)})]}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`span`,{onDoubleClick:()=>Ut(`conversation`,e.id),children:[`· `,e.title]}),(0,j.jsx)(`small`,{children:hn(e.archivedAt)}),(0,j.jsx)(`button`,{type:`button`,className:`conversation-fork`,"data-fork-conversation":e.id,"data-fork-state":qn===e.id?`pending`:`idle`,disabled:!!qn,title:`从此会话分叉出一个新会话`,"aria-label":`从已归档会话 ${e.title} 分叉出一个新会话`,onClick:()=>Xn(e.id),children:`⑂`}),(0,j.jsx)(`button`,{className:`conversation-restore`,title:`恢复为正常会话`,"aria-label":`恢复会话 ${e.title}`,onClick:()=>cn(e.id),children:`↑`})]})},e.id))]})]},t.id)})}),(0,j.jsxs)(`footer`,{children:[(0,j.jsxs)(`div`,{className:`footer-status`,children:[(0,j.jsx)(`i`,{className:o?`online`:`offline`}),o?`已连接`:`正在连接`,(0,j.jsx)(`span`,{children:`本地持久化`})]}),(0,j.jsxs)(`button`,{type:`button`,className:`theme-settings-trigger`,"data-theme-open":`1`,"aria-haspopup":`dialog`,"aria-expanded":Qt,onClick:()=>$t(!0),children:[(0,j.jsx)(`span`,{"aria-hidden":`true`,children:`⚙`}),`设置`]}),(0,j.jsxs)(`button`,{type:`button`,className:`theme-settings-trigger`,"data-help-open":`1`,"aria-haspopup":`dialog`,"aria-expanded":en,onClick:()=>tn(!0),children:[(0,j.jsx)(`span`,{"aria-hidden":`true`,children:`📖`}),`使用指南`]})]})]}),(0,j.jsx)(dr,{side:`left`,width:he.sidebar,min:he.sidebarMin,max:he.sidebarMax,label:`调整左侧栏宽度`,onWidth:ge}),(0,j.jsxs)(`section`,{className:`chat`,"data-main-view":P,"data-main-view-kind":P,children:[Qe.length>0&&(0,j.jsx)(`div`,{className:`chat-tab-strip`,"data-chat-tab-strip":`1`,"data-session-count":Be.length,"data-file-count":N.open.length,children:(0,j.jsx)(nt,{tabs:Qe,prefix:`workspace-tab`,ariaLabel:`工作区标签页`,activeId:$e,onSelect:et,onClose:tt,minWidth:120,maxWidth:320})}),(0,j.jsxs)(`header`,{children:[(0,j.jsxs)(`div`,{className:`chat-head`,children:[(0,j.jsx)(`h1`,{children:M?.title??`准备开始`}),ee.size>0?[...ee].map(([e,t])=>(0,j.jsx)(`p`,{"data-role":`run-status`,"data-status-key":e,children:`扩展状态:${e?`${e} · `:``}${t}`},e)):(0,j.jsx)(`p`,{"data-role":`run-status`,children:M?.status===`running`?`Agent 正在工作`:`Pi runtime · Web 控制台`})]}),(0,j.jsxs)(`span`,{className:`chat-view chat-view-${P}`,"data-main-view-indicator":P,"data-main-view-kind":P,title:P===`file`?`中间主画面正在显示文件 ${N.active?.path??``}`:`中间主画面正在显示这个会话的消息流`,children:[(0,j.jsx)(`span`,{className:`chat-view-label`,children:`主区显示`}),(0,j.jsx)(`span`,{className:`chat-view-kind`,children:P===`file`?`文件`:`会话`}),P===`file`&&N.active&&(0,j.jsx)(`span`,{className:`chat-view-name`,"data-main-view-name":N.active.name,children:N.active.name})]}),(0,j.jsx)(`div`,{className:`badge`,children:M?.status??`idle`})]}),c&&(0,j.jsx)(`div`,{className:`error`,children:c}),M?.error&&(0,j.jsx)(`div`,{className:`error`,"data-role":`conversation-error`,children:M.error}),ne&&(0,j.jsxs)(`div`,{className:`extui-title-note`,children:[`扩展建议标题:`,ne]}),S.length>0&&(0,j.jsx)(`div`,{className:`toasts`,role:`status`,"aria-live":`polite`,"data-toast-count":S.length,children:S.map(e=>(0,j.jsx)(`div`,{className:`toast toast-${e.kind}`,"data-toast-kind":e.kind,children:e.text},e.key))}),P===`file`?(0,j.jsx)(`div`,{className:`chat-file-view`,"data-main-file-view":rt?.path,"data-file-view-kind":`editor`,children:rt?(0,j.jsx)(Ye,{file:rt,state:N.saves[rt.path]?.state??`idle`,message:N.saves[rt.path]?.message??``,external:N.external[rt.path]===!0,onChange:e=>N.updateBuffer(rt.path,e),onSave:()=>void N.save(rt.path,!1),onReload:()=>void N.reload(rt.path),onOverwrite:()=>void N.save(rt.path,!0)}):(0,j.jsx)(`p`,{className:`rail-empty`,"data-main-file-empty":`1`,children:`没有选中的文件。`})}):(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`messages`,children:[!M&&(0,j.jsxs)(`div`,{className:`empty`,children:[(0,j.jsx)(`div`,{className:`orb`,children:`π`}),(0,j.jsx)(`h2`,{children:`开始一个新会话`}),(0,j.jsx)(`p`,{children:e.workspaces.length?`选择一个工作区创建会话,即可从浏览器向 Super Pi 发送任务。`:`先创建一个工作区,再开始会话。`}),e.workspaces.map(e=>(0,j.jsxs)(`button`,{onClick:()=>on(e.id),children:[`在「`,e.name,`」中创建会话`]},e.id)),(0,j.jsx)(`button`,{onClick:()=>g(!0),children:`+ 新建工作区`})]}),Pt.map(e=>{if(e.startsWith(`m:`)){let t=Mt.get(e.slice(2));if(!t)return null;let n=t.role===`user`&&!!t.piEntryId&&e!==Pt.at(-1)&&M?.status!==`running`&&jn!==t.id,r=t.content?(0,j.jsx)(ke,{source:t.content}):(0,j.jsx)(`span`,{className:`typing`,children:`正在思考`}),i=t.toolCalls??[];if(t.role===`user`){let i=Un?.id===t.id?Un.kind:void 0,a=t.content||(t.images?.length?`[图片]`:``);return(0,j.jsxs)(`article`,{className:`message user`,children:[(0,j.jsxs)(`div`,{className:`message-body`,children:[(0,j.jsxs)(`div`,{className:`bubble`,children:[(0,j.jsxs)(`div`,{className:`meta`,children:[`你`,(0,j.jsx)(`time`,{children:an(t.createdAt)})]}),t.images&&t.images.length>0&&(0,j.jsx)(`div`,{className:`message-images`,"data-message-images":`1`,children:t.images.map(e=>(0,j.jsx)(`button`,{type:`button`,className:`message-image-btn`,"data-message-image-id":e.id,onClick:()=>Ee({url:`/api/upload/${encodeURIComponent(M.id)}/${encodeURIComponent(e.id)}`,name:e.name,bytes:e.bytes}),title:e.name?`查看大图:${e.name}`:`查看大图`,children:(0,j.jsx)(`img`,{src:`/api/upload/${encodeURIComponent(M.id)}/${encodeURIComponent(e.id)}`,alt:e.name||`图片`,className:`message-image-thumb`,loading:`lazy`})},e.id))}),(0,j.jsx)(`div`,{className:`content`,children:r})]}),(0,j.jsxs)(`div`,{className:`message-actions`,children:[(0,j.jsx)(`button`,{type:`button`,className:`message-copy`,"data-copy-message":t.id,"data-copy-state":i,"aria-label":`复制这条消息:${a}`,onClick:()=>Kn(t.id,a),children:i===`copied`?`已复制`:i===`error`?`复制失败`:`复制`}),n&&(0,j.jsx)(`button`,{type:`button`,className:`message-revert`,"data-revert-message":t.id,title:`回退到这里:删除这条消息之后的全部内容(Pi 的记录和这里的历史一起清掉,不会新建会话,也不动任何代码文件)`,onClick:()=>Nn(t.id),children:`⟲ 回退`})]})]}),(0,j.jsx)(`div`,{className:`avatar`,children:`你`})]},e)}return(0,j.jsxs)(`article`,{className:`message assistant`,children:[(0,j.jsx)(`div`,{className:`avatar`,children:`π`}),(0,j.jsxs)(`div`,{className:`message-body`,children:[(0,j.jsxs)(`div`,{className:`meta`,children:[`Super Pi`,(0,j.jsx)(`time`,{children:an(t.createdAt)})]}),(0,j.jsx)(`div`,{className:`content`,children:r}),i.length>0&&(0,j.jsx)(`div`,{className:`call-blocks`,"data-call-block-count":i.length,children:i.map((e,n)=>(0,j.jsx)(Pn,{call:e,index:n,expanded:!!Se[`${t.id}:${n}`],onToggle:()=>It(t.id,n)},`${t.id}:${n}:${e.label}`))})]})]},e)}if(e.startsWith(`w:`)){let t=At.get(e.slice(2));return t?(0,j.jsx)(lt,{workflow:t,names:jt,onStop:()=>Rt(t.id)},e):null}let t=Nt.get(e.slice(2));return t?(0,j.jsx)(Fn,{run:t,name:jt.get(t.agentId)??``,expanded:!!be[t.id],onToggle:()=>Ft(t.id),onStop:()=>Lt(t.id)},e):null})]}),(0,j.jsx)(In,{items:Sn,pi:ve.get(M?.id??``),running:M?.status===`running`,onCancel:wn,onSteer:Tn}),(Et.length>0||[...te.values()].some(e=>e.placement===`aboveEditor`))&&(0,j.jsxs)(`div`,{className:`extui`,"data-extui-count":Et.length,children:[Et.map(e=>(0,j.jsx)(Ln,{request:e.request,onAnswer:t=>dt(e.conversationId,e.request.requestId,t)},e.request.requestId)),zt(`aboveEditor`)]}),(0,j.jsxs)(`form`,{onSubmit:xn,onPaste:un,onDragOver:dn,onDragLeave:yn,onDrop:bn,className:De?`composer-dropzone-active`:void 0,children:[(0,j.jsxs)(`div`,{className:`session-picker`,"data-session-picker":`1`,children:[(0,j.jsx)(zn,{kind:`agent`,label:bt?.name??`跟随 Pi 默认`,value:M?.agentId??Bn,detail:bt?.description||void 0,options:xt,disabled:!ae||ae.source===`unavailable`,note:An(ae),onChoose:Tt}),(0,j.jsx)(zn,{kind:`model`,label:ft?.label??(E?`Pi 默认`:`读取中…`),value:ft?`${ft.provider}/${ft.modelId}`:void 0,detail:wt?`来自 ${bt?.name}`:ft&&E?.source===`pi`&&!M?.model?`Pi 默认模型`:ft?`${ft.provider}/${ft.modelId}`:void 0,options:gt,disabled:!mt,note:kn(`模型`,E),onChoose:vt}),(0,j.jsx)(zn,{kind:`thinking`,label:pt??(E?`Pi 默认`:`读取中…`),value:pt,options:_t,disabled:!mt,note:kn(`思考等级`,E),onChoose:yt})]}),(0,j.jsx)(`textarea`,{value:i,onChange:e=>a(e.target.value),placeholder:M?ht?`描述你要完成的任务(支持粘贴/拖放图片)…`:`描述你要完成的任务…`:`先创建会话`,disabled:!M,onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),e.currentTarget.form?.requestSubmit())}}),(D.length>0||k>0)&&(0,j.jsxs)(`div`,{className:`composer-attachments`,"data-composer-attachments":`1`,children:[D.map((e,t)=>(0,j.jsxs)(`div`,{className:`composer-attachment-item`,"data-composer-attachment-id":e.id,children:[(0,j.jsx)(`img`,{src:`/api/upload/${encodeURIComponent(M.id)}/${encodeURIComponent(e.id)}`,alt:e.name||`已附图片`,className:`composer-attachment-thumb`,onClick:()=>Ee({url:`/api/upload/${encodeURIComponent(M.id)}/${encodeURIComponent(e.id)}`,name:e.name,bytes:e.bytes}),title:`点击查看大图`}),(0,j.jsx)(`span`,{className:`composer-attachment-name`,title:e.name,children:e.name||`图片`}),(0,j.jsx)(`button`,{type:`button`,className:`composer-attachment-remove`,"data-composer-attachment-remove":e.id,onClick:()=>O(e=>e.filter((e,n)=>n!==t)),"aria-label":`移除 ${e.name||`图片`}`,title:`移除图片`,children:`✕`})]},e.id)),k>0&&(0,j.jsx)(`div`,{className:`composer-attachment-item composer-attachment-uploading`,children:(0,j.jsxs)(`span`,{children:[`图片上传中 (`,k,`)…`]})})]}),(0,j.jsxs)(`div`,{className:`composer`,children:[(0,j.jsxs)(`div`,{className:`composer-hints`,children:[(0,j.jsxs)(`button`,{type:`button`,className:`composer-attach-btn`,"data-composer-attach":`1`,onClick:()=>Oe.current?.click(),disabled:!M||!ht||k>0,title:M?ht?`添加图片(支持剪贴板粘贴与拖拽)`:`当前模型不支持图片输入`:`请先创建或选择会话`,"aria-label":`添加图片`,children:[(0,j.jsx)(`span`,{"aria-hidden":`true`,children:`+`}),` 图片`]}),(0,j.jsx)(`input`,{ref:Oe,type:`file`,accept:`image/png,image/jpeg,image/gif,image/webp`,multiple:!0,style:{display:`none`},onChange:e=>{e.target.files?.length&&(ln(Array.from(e.target.files)),e.target.value=``)}}),(0,j.jsx)(`span`,{children:`Enter 发送 · Shift + Enter 换行`})]}),(0,j.jsxs)(`div`,{className:`composer-actions`,children:[M?.status===`running`&&(0,j.jsx)(`button`,{type:`button`,className:`stop`,"data-stop-run":M.id,onClick:()=>I({type:`run.stop`,conversationId:M.id}),children:`停止`}),(0,j.jsx)(`button`,{className:`send ${M?.status===`running`?`send-queued`:``}`,"data-send-mode":M?.status===`running`?`queued`:`direct`,disabled:!i.trim()&&D.length===0||!M||k>0,title:M?!i.trim()&&D.length===0?`请输入消息或添加图片后发送`:k>0?`图片上传中…`:M.status===`running`?`这一轮结束后发送(发送后可在上面的排队区取消或插队)`:void 0:`请先创建或选择会话`,children:M?.status===`running`?`排队发送 ↑`:`发送 ↑`})]})]})]}),zt(`belowEditor`)]})]}),(0,j.jsx)(dr,{side:`right`,width:le?30:he.rail,min:he.railMin,max:he.railMax,label:`调整右侧栏宽度`,onWidth:_e}),h&&(0,j.jsx)(En,{onClose:()=>g(!1),onCreate:Bt}),Qt&&(0,j.jsx)(Ot,{theme:Xt,onChooseTheme:e=>Zt(e),onClose:()=>$t(!1),agentCatalog:ae,subagentCatalog:se,customAgentDirs:e.customAgentDirs??[],onSetCustomAgentDirs:e=>I({type:`agents.setCustomDirs`,dirs:e}),onRescanAgents:()=>I({type:`agents.rescan`})}),en&&(0,j.jsx)(ut,{onClose:()=>tn(!1)}),Yt&&(0,j.jsx)(Vn,{workspace:Yt,catalog:E,agents:ae,onClose:()=>Jt(void 0),onRename:()=>{let e=Yt.id;Jt(void 0),Ut(`workspace`,e)},onSave:(e,t,n)=>nn(Yt.id,e,t,n)}),Te&&(0,j.jsx)(tr,{image:Te,onClose:()=>Ee(void 0)}),(0,j.jsx)(Yn,{todos:e.todos??[],tasks:e.backgroundTasks??[],collapsed:le,onToggle:()=>ue(e=>!e),workspaceId:p,files:N,onOpenFile:e=>void qe(e),activeTab:Ue,onSelectTab:We})]})}xt(bt()),(0,d.createRoot)(document.getElementById(`root`)).render((0,j.jsx)(l.StrictMode,{children:(0,j.jsx)(fr,{})}));
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta name="theme-color" content="#101828" />
7
7
  <title>Super Pi</title>
8
- <script type="module" crossorigin src="/assets/index-CHw4ZoY4.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-WlIFA_Dt.css">
8
+ <script type="module" crossorigin src="/assets/index-D_VwFuME.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-BhFeQ1E-.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
@@ -146,7 +146,26 @@ export type AgentModeFilter = "primary" | "subagent";
146
146
  * so the split is a filter on the parsed field, never a second directory or a second parser. A caller
147
147
  * with no argument gets exactly what it always got.
148
148
  */
149
- export declare function readAgents(directory: string, options?: {
149
+ /**
150
+ * Expands a leading tilde (`~` or `~/...` or `~\...`) to the user's home directory.
151
+ */
152
+ export declare function expandTilde(filepath: string): string;
153
+ export interface ResolveAgentDirectoriesOptions {
154
+ customDirs?: readonly string[];
155
+ env?: NodeJS.ProcessEnv;
156
+ rootDir?: string;
157
+ }
158
+ /**
159
+ * Resolves the ordered list of directories to discover agents from:
160
+ * 1. Custom directories configured by the user in app settings (or options)
161
+ * 2. SUPER_PI_AGENTS_DIR environment variable if set
162
+ * 3. User global agent directories (~/.super_pi/agents, ~/.super-pi/agents, ~/.pi/agents)
163
+ * 4. Built-in repository/package agents directory (<rootDir>/agents)
164
+ *
165
+ * Duplicate paths are preserved in order of first appearance.
166
+ */
167
+ export declare function resolveAgentDirectories(options?: ResolveAgentDirectoriesOptions): string[];
168
+ export declare function readAgents(directory: string | readonly string[], options?: {
150
169
  mode?: AgentModeFilter;
151
170
  }): Promise<AgentScan>;
152
171
  /** Parses one definition file, or returns the reason it is not a usable agent. */
@@ -1,5 +1,6 @@
1
1
  import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
2
- import { join } from "node:path";
2
+ import { homedir } from "node:os";
3
+ import { join, resolve } from "node:path";
3
4
  /**
4
5
  * A guard rather than a cast: it is the only thing that lets `tools:` be checked once and then used as
5
6
  * a map everywhere without the compiler complaining. It narrows to the index-signature shape that
@@ -332,32 +333,105 @@ export function parseAgentModel(model) {
332
333
  * so the split is a filter on the parsed field, never a second directory or a second parser. A caller
333
334
  * with no argument gets exactly what it always got.
334
335
  */
335
- export async function readAgents(directory, options = {}) {
336
- const mode = options.mode ?? "primary";
337
- let entries;
338
- try {
339
- entries = await readdir(directory);
336
+ /**
337
+ * Expands a leading tilde (`~` or `~/...` or `~\...`) to the user's home directory.
338
+ */
339
+ export function expandTilde(filepath) {
340
+ if (filepath === "~")
341
+ return homedir();
342
+ if (filepath.startsWith("~/") || filepath.startsWith("~\\")) {
343
+ return join(homedir(), filepath.slice(2));
340
344
  }
341
- catch (error) {
342
- if (error.code === "ENOENT")
343
- return { agents: [], problems: [] };
344
- throw error;
345
+ return filepath;
346
+ }
347
+ /**
348
+ * Resolves the ordered list of directories to discover agents from:
349
+ * 1. Custom directories configured by the user in app settings (or options)
350
+ * 2. SUPER_PI_AGENTS_DIR environment variable if set
351
+ * 3. User global agent directories (~/.super_pi/agents, ~/.super-pi/agents, ~/.pi/agents)
352
+ * 4. Built-in repository/package agents directory (<rootDir>/agents)
353
+ *
354
+ * Duplicate paths are preserved in order of first appearance.
355
+ */
356
+ export function resolveAgentDirectories(options = {}) {
357
+ const dirs = [];
358
+ const add = (dir) => {
359
+ if (!dir)
360
+ return;
361
+ const trimmed = dir.trim();
362
+ if (!trimmed)
363
+ return;
364
+ const expanded = expandTilde(trimmed);
365
+ const resolved = resolve(expanded);
366
+ if (!dirs.includes(resolved)) {
367
+ dirs.push(resolved);
368
+ }
369
+ };
370
+ if (options.customDirs) {
371
+ for (const d of options.customDirs)
372
+ add(d);
345
373
  }
374
+ const env = options.env ?? process.env;
375
+ if (env.SUPER_PI_AGENTS_DIR) {
376
+ add(env.SUPER_PI_AGENTS_DIR);
377
+ }
378
+ else {
379
+ try {
380
+ const home = homedir();
381
+ add(join(home, ".super_pi", "agents"));
382
+ add(join(home, ".super-pi", "agents"));
383
+ add(join(home, ".pi", "agents"));
384
+ }
385
+ catch {
386
+ // homedir() might throw in restricted sandbox environments
387
+ }
388
+ const root = options.rootDir ?? resolve(import.meta.dirname, "../..");
389
+ add(join(root, "agents"));
390
+ }
391
+ return dirs;
392
+ }
393
+ export async function readAgents(directory, options = {}) {
394
+ const mode = options.mode ?? "primary";
395
+ const rawDirs = Array.isArray(directory) ? directory : [directory];
396
+ const dirs = rawDirs.filter(Boolean);
346
397
  const agents = [];
347
398
  const problems = [];
348
- for (const file of entries.filter((name) => name.toLowerCase().endsWith(".md")).sort()) {
349
- const source = await readFile(join(directory, file), "utf8");
350
- const parsed = parseDefinition(file, source);
351
- if ("message" in parsed)
352
- problems.push({ file, message: parsed.message });
353
- else
354
- agents.push(parsed);
399
+ const seenIds = new Set();
400
+ for (const dir of dirs) {
401
+ let entries;
402
+ try {
403
+ entries = await readdir(dir);
404
+ }
405
+ catch (error) {
406
+ if (error.code === "ENOENT")
407
+ continue;
408
+ throw error;
409
+ }
410
+ for (const file of entries.filter((name) => name.toLowerCase().endsWith(".md")).sort()) {
411
+ const source = await readFile(join(dir, file), "utf8");
412
+ const parsed = parseDefinition(file, source);
413
+ if ("message" in parsed) {
414
+ const fileId = file.replace(/\.md$/i, "");
415
+ if (!seenIds.has(fileId)) {
416
+ problems.push({ file, message: parsed.message });
417
+ }
418
+ }
419
+ else {
420
+ if (!seenIds.has(parsed.id)) {
421
+ seenIds.add(parsed.id);
422
+ agents.push({ ...parsed, sourceDir: dir });
423
+ }
424
+ }
425
+ }
355
426
  }
356
427
  // The half that was NOT asked for is filtered out here rather than marked in the UI: sub-agents are
357
428
  // invoked BY an agent and never chosen by a human, so listing one in the picker would promise a role
358
429
  // the runtime cannot honour. The remainder is alphabetical by id, so either roster reads as a list
359
430
  // rather than as a directory listing.
360
- return { agents: agents.filter((agent) => agent.mode === mode).sort((a, b) => a.id.localeCompare(b.id)), problems };
431
+ return {
432
+ agents: agents.filter((agent) => agent.mode === mode).sort((a, b) => a.id.localeCompare(b.id)),
433
+ problems,
434
+ };
361
435
  }
362
436
  /** Only `#rgb` and `#rrggbb`. A `color:` frontmatter value is rendered as a CSS background, so it has to
363
437
  * be a colour and nothing else - accepting an arbitrary string would put author-controlled text into a