aims-workstation 0.1.7 → 0.1.9

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.
@@ -94,10 +94,10 @@ Error generating stack: `+e.message+`
94
94
  [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_pre_code]:break-normal
95
95
  [&_table]:my-1.5 [&_table]:block [&_table]:w-full [&_table]:max-w-full [&_table]:overflow-x-auto [&_table]:border-collapse [&_table]:text-[11px]
96
96
  [&_th]:border [&_th]:border-border [&_th]:bg-muted/50 [&_th]:px-2 [&_th]:py-1 [&_th]:text-left [&_th]:font-semibold
97
- [&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1 [&_td]:break-words`,children:(0,K.jsx)(Kw,{remarkPlugins:[QD],children:e})})}function eO({className:e,children:t,...n}){return(0,K.jsxs)(Bd,{"data-slot":`scroll-area`,className:mn(`relative`,e),...n,children:[(0,K.jsx)(Ud,{"data-slot":`scroll-area-viewport`,className:`size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1`,children:t}),(0,K.jsx)(tO,{}),(0,K.jsx)(lf,{})]})}function tO({className:e,orientation:t=`vertical`,...n}){return(0,K.jsx)(Jd,{"data-slot":`scroll-area-scrollbar`,orientation:t,className:mn(`flex touch-none p-px transition-colors select-none`,t===`vertical`&&`h-full w-2.5 border-l border-l-transparent`,t===`horizontal`&&`h-2.5 flex-col border-t border-t-transparent`,e),...n,children:(0,K.jsx)(of,{"data-slot":`scroll-area-thumb`,className:`relative flex-1 rounded-full bg-border`})})}function nO({className:e,...t}){return(0,K.jsx)(`textarea`,{"data-slot":`textarea`,className:mn(`flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:ring-destructive/40`,e),...t})}function rO({agentId:e,sessionId:t,wsId:n,injectedDevice:r,autonomy:i,onAutonomy:a}){let[o,s]=(0,v.useState)([]),[c,l]=(0,v.useState)(``),[u,d]=(0,v.useState)(!1),[f,p]=(0,v.useState)(null),[m,h]=(0,v.useState)(``),[g,_]=(0,v.useState)(!1),[y,b]=(0,v.useState)(``),[x,S]=(0,v.useState)(``),C=(0,v.useRef)(null),w=(0,v.useRef)(null),T=(0,v.useRef)(!1);(0,v.useEffect)(()=>{T.current=u},[u]);let E=(0,v.useRef)(!1),D=(0,v.useRef)(!1);(0,v.useEffect)(()=>{let e=!0,n=async()=>{if(T.current||!e)return;let n;try{n=await ot(`/api/chat/history?sessionId=${encodeURIComponent(t)}`)}catch{return}if(!e||!n.exists)return;let r=!!(n.running||n.pending);(!E.current||r||D.current)&&(E.current=!0,D.current=r,s([...n.msgs||[],...n.pending?[{kind:`pending`,intro:`(恢复现场)待确认操作:${n.pending.tool}`}]:[]]),p(n.pending||null),h(r?`后台进行中:${n.statusText||(n.pending?`等待人工确认`:``)}`:``))};n();let r=setInterval(n,2500);return()=>{e=!1,clearInterval(r)}},[t]);let O=(0,v.useRef)(!0),k=(0,v.useCallback)(()=>{let e=C.current?.closest(`[data-slot="scroll-area-viewport"]`);e&&(e.scrollTop=e.scrollHeight)},[]);(0,v.useEffect)(()=>{let e=C.current?.closest(`[data-slot="scroll-area-viewport"]`);if(!e)return;let t=()=>{O.current=e.scrollHeight-e.scrollTop-e.clientHeight<80};return e.addEventListener(`scroll`,t),()=>e.removeEventListener(`scroll`,t)},[]),(0,v.useEffect)(()=>{O.current&&k()},[o,m,k]),(0,v.useEffect)(()=>{O.current=!0},[t]);let A=e=>s(t=>[...t,e]),j=(0,v.useRef)(null),M=()=>{j.current?.abort(),st(`/api/chat/interrupt`,{sessionId:t}).catch(()=>{})},N=e=>{let t=e.type;if(t===`status`)h(String(e.text||``));else if(t===`text_delta`){let t=e.delta;h(``),s(e=>{let n=e[e.length-1];return n?.kind===`bot`?[...e.slice(0,-1),{...n,text:(n.text||``)+t}]:[...e,{kind:`bot`,text:t}]})}else t===`tool_start`?A({kind:`evt`,evt:{tool:e.tool,args:e.args,result:`…`,status:`start`}}):t===`tool_end`?s(t=>{let n=[...t].reverse().findIndex(t=>t.kind===`evt`&&t.evt?.tool===e.tool&&t.evt?.status===`start`);if(n<0)return[...t,{kind:`evt`,evt:e}];let r=t.length-1-n;return t.map((t,n)=>n===r?{kind:`evt`,evt:e}:t)}):t===`pending`?(p(e.pending),A({kind:`pending`,intro:e.intro}),h(``)):t===`done`?(h(``),e.reply&&s(t=>{let n=t[t.length-1];return n?.kind===`bot`&&n.text&&e.reply&&n.text.trim()===String(e.reply).trim()?t:[...t,{kind:`bot`,text:String(e.reply)}]})):t===`interrupted`?(h(``),s(e=>{let t=e[e.length-1];return t?.kind===`bot`?[...e.slice(0,-1),{...t,text:(t.text||``)+`
97
+ [&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1 [&_td]:break-words`,children:(0,K.jsx)(Kw,{remarkPlugins:[QD],children:e})})}function eO({className:e,children:t,...n}){return(0,K.jsxs)(Bd,{"data-slot":`scroll-area`,className:mn(`relative`,e),...n,children:[(0,K.jsx)(Ud,{"data-slot":`scroll-area-viewport`,className:`size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1`,children:t}),(0,K.jsx)(tO,{}),(0,K.jsx)(lf,{})]})}function tO({className:e,orientation:t=`vertical`,...n}){return(0,K.jsx)(Jd,{"data-slot":`scroll-area-scrollbar`,orientation:t,className:mn(`flex touch-none p-px transition-colors select-none`,t===`vertical`&&`h-full w-2.5 border-l border-l-transparent`,t===`horizontal`&&`h-2.5 flex-col border-t border-t-transparent`,e),...n,children:(0,K.jsx)(of,{"data-slot":`scroll-area-thumb`,className:`relative flex-1 rounded-full bg-border`})})}function nO({className:e,...t}){return(0,K.jsx)(`textarea`,{"data-slot":`textarea`,className:mn(`flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:ring-destructive/40`,e),...t})}function rO({agentId:e,sessionId:t,wsId:n,injectedDevice:r,autonomy:i,onAutonomy:a}){let[o,s]=(0,v.useState)([]),[c,l]=(0,v.useState)(``),[u,d]=(0,v.useState)(!1),[f,p]=(0,v.useState)(null),[m,h]=(0,v.useState)(``),[g,_]=(0,v.useState)(!1),[y,b]=(0,v.useState)(``),[x,S]=(0,v.useState)(``),C=(0,v.useRef)(null),w=(0,v.useRef)(null),T=(0,v.useRef)(!1);(0,v.useEffect)(()=>{T.current=u},[u]);let E=(0,v.useRef)(!1),D=(0,v.useRef)(!1);(0,v.useEffect)(()=>{let e=!0,n=async()=>{if(T.current||!e)return;let n;try{n=await ot(`/api/chat/history?sessionId=${encodeURIComponent(t)}`)}catch{return}if(!e||!n.exists)return;let r=!!(n.running||n.pending);(!E.current||r||D.current)&&(E.current=!0,D.current=r,s([...n.msgs||[],...n.pending?[{kind:`pending`,intro:`(恢复现场)待确认操作:${n.pending.tool}`}]:[]]),p(n.pending||null),h(r?`后台进行中:${n.statusText||(n.pending?`等待人工确认`:``)}`:``))};n();let r=setInterval(n,2500);return()=>{e=!1,clearInterval(r)}},[t]);let O=(0,v.useRef)(!0),k=(0,v.useCallback)(()=>{let e=C.current?.closest(`[data-slot="scroll-area-viewport"]`);e&&(e.scrollTop=e.scrollHeight)},[]);(0,v.useEffect)(()=>{let e=C.current?.closest(`[data-slot="scroll-area-viewport"]`);if(!e)return;let t=()=>{O.current=e.scrollHeight-e.scrollTop-e.clientHeight<80};return e.addEventListener(`scroll`,t),()=>e.removeEventListener(`scroll`,t)},[]),(0,v.useEffect)(()=>{O.current&&k()},[o,m,k]),(0,v.useEffect)(()=>{O.current=!0},[t]);let A=e=>s(t=>[...t,e]),j=(0,v.useRef)(null),M=()=>{j.current?.abort(),st(`/api/chat/interrupt`,{sessionId:t}).catch(()=>{})},N=async()=>{if(u)Z.info(`对话进行中,请先中断再清空`);else if(window.confirm(`清空当前会话?服务端上下文与待确认操作将被丢弃,从零开始对话。`))try{await st(`/api/session/reset`,{scope:`chat`,sessionId:t}),s([]),p(null),h(``),E.current=!1,Z.success(`会话已清空`)}catch(e){Z.error(String(e.message))}},P=e=>{let t=e.type;if(t===`status`)h(String(e.text||``));else if(t===`text_delta`){let t=e.delta;h(``),s(e=>{let n=e[e.length-1];return n?.kind===`bot`?[...e.slice(0,-1),{...n,text:(n.text||``)+t}]:[...e,{kind:`bot`,text:t}]})}else t===`tool_start`?A({kind:`evt`,evt:{tool:e.tool,args:e.args,result:`…`,status:`start`}}):t===`tool_end`?s(t=>{let n=[...t].reverse().findIndex(t=>t.kind===`evt`&&t.evt?.tool===e.tool&&t.evt?.status===`start`);if(n<0)return[...t,{kind:`evt`,evt:e}];let r=t.length-1-n;return t.map((t,n)=>n===r?{kind:`evt`,evt:e}:t)}):t===`pending`?(p(e.pending),A({kind:`pending`,intro:e.intro}),h(``)):t===`done`?(h(``),e.reply&&s(t=>{let n=t[t.length-1];return n?.kind===`bot`&&n.text&&e.reply&&n.text.trim()===String(e.reply).trim()?t:[...t,{kind:`bot`,text:String(e.reply)}]})):t===`interrupted`?(h(``),s(e=>{let t=e[e.length-1];return t?.kind===`bot`?[...e.slice(0,-1),{...t,text:(t.text||``)+`
98
98
 
99
- (已中断)`}]:[...e,{kind:`bot`,text:`(已中断)`}]})):t===`error`&&(Z.error(String(e.message)),h(``))},P=async()=>{let e=c.trim();e&&!u&&(l(``),await F(e))},F=async a=>{if(u)return;d(!0),O.current=!0,A({kind:`user`,text:a});let o=new AbortController;j.current=o;try{await ut(`/api/chat`,{sessionId:t,agentId:e,message:a,autonomyLevel:i,ws_id:n,context:r?{device:r}:null},N,o.signal)}catch(e){o.signal.aborted||Z.error(String(e.message))}finally{d(!1),j.current===o&&(j.current=null)}},I=async e=>{if(!f)return;p(null),d(!0),O.current=!0,s(e=>e.filter(e=>e.kind!==`pending`));let n=new AbortController;j.current=n;try{await ut(`/api/chat/confirm`,{sessionId:t,approved:e},N,n.signal)}catch(e){n.signal.aborted||Z.error(String(e.message))}finally{d(!1),j.current===n&&(j.current=null)}};return(0,K.jsxs)(`div`,{className:`flex h-full flex-col`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2 border-b px-3 py-1`,children:[(0,K.jsx)(th,{className:`h-3.5 w-3.5 text-primary`}),(0,K.jsx)(`span`,{className:`text-xs font-medium`,children:`诊断对话`}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:r?`上下文:${r}(点选设备自动注入)`:`点击左侧设备可注入上下文`}),(0,K.jsxs)(`div`,{className:`ml-auto flex items-center gap-1.5`,children:[(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`自主级别`}),(0,K.jsxs)(h_,{value:String(i),onValueChange:e=>a(+e),children:[(0,K.jsx)(__,{className:`h-7 w-[118px] text-xs`,children:(0,K.jsx)(g_,{})}),(0,K.jsxs)(v_,{children:[(0,K.jsx)(y_,{value:`0`,className:`text-xs`,children:`L0 只读问答`}),(0,K.jsx)(y_,{value:`1`,className:`text-xs`,children:`L1 诊断建议`}),(0,K.jsx)(y_,{value:`2`,className:`text-xs`,children:`L2 确认执行`}),(0,K.jsx)(y_,{value:`3`,className:`text-xs text-red-400`,children:`L3 完全自主(免确认)`})]})]})]})]}),(0,K.jsx)(eO,{className:`min-h-0 flex-1 [&>div>div]:block!`,children:(0,K.jsxs)(`div`,{className:`space-y-2.5 p-3`,ref:C,children:[o.length===0&&(0,K.jsxs)(`div`,{className:`flex h-40 flex-col items-center justify-center gap-1 text-xs text-muted-foreground`,children:[(0,K.jsx)(Vh,{className:`h-5 w-5 opacity-50`}),`试试:「STK-R3 什么情况?帮我处理」 / 「服务器 CPU 高,怎么处理」`]}),o.map((e,t)=>{if(e.kind===`user`)return(0,K.jsx)(`div`,{className:`ml-auto max-w-[85%] rounded-lg bg-primary/20 px-3 py-1.5 text-xs leading-relaxed break-words`,children:e.text},t);if(e.kind===`bot`)return(0,K.jsx)(`div`,{className:`max-w-[92%] rounded-lg bg-card px-3 py-2 text-xs leading-relaxed break-words`,children:(e.text||``).split(/```a2ui\s*\n?([\s\S]*?)```/g).map((e,t)=>t%2==0?e.trim()?(0,K.jsx)($D,{text:e},t):null:(0,K.jsx)(av,{raw:e,onSend:F},t))},t);if(e.kind===`evt`&&e.evt){let n=e.evt.status,r={ok:`✅`,executed:`▶`,blocked:`⛔`,cancelled:`🚫`,rejected:`❌`,start:`⏳`}[n]||`•`;return(0,K.jsxs)(`div`,{className:it(`max-w-[92%] rounded-md border border-dashed px-2.5 py-1.5 text-[11px]`,n===`blocked`?`border-red-500/50 text-red-300`:n===`start`?`border-border text-muted-foreground`:`border-border`),children:[(0,K.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5`,children:[(0,K.jsx)(`span`,{className:`shrink-0`,children:r}),(0,K.jsx)(t_,{className:`h-3 w-3 shrink-0`}),(0,K.jsx)(`span`,{className:`shrink-0 font-mono font-semibold`,children:e.evt.tool}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground`,children:JSON.stringify(e.evt.args)})]}),n!==`start`&&(0,K.jsx)(`pre`,{className:`mt-1 max-h-40 overflow-auto whitespace-pre-wrap break-all text-[10px] leading-relaxed text-muted-foreground`,children:String(e.evt.result).slice(0,700)})]},t)}return e.kind===`pending`?(0,K.jsx)(bm,{className:`max-w-[92%] border-amber-500/50 bg-amber-500/5`,children:(0,K.jsxs)(Cm,{className:`space-y-2 p-3`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs font-semibold text-amber-300`,children:[(0,K.jsx)(jg,{className:`h-3.5 w-3.5`}),`人工确认(L2)· 助手请求执行写操作`]}),e.intro&&(0,K.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:(0,K.jsx)($D,{text:e.intro})}),(0,K.jsxs)(`div`,{className:`flex gap-2`,children:[(0,K.jsx)(Y,{size:`sm`,variant:`destructive`,onClick:()=>I(!1),children:`取消`}),(0,K.jsx)(Y,{size:`sm`,onClick:()=>I(!0),children:`确认执行`})]})]})},t):null}),m&&(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 px-1 text-[11px] text-muted-foreground`,children:[(0,K.jsx)(`span`,{className:`h-1.5 w-1.5 animate-pulse rounded-full bg-primary`}),m,m.startsWith(`后台进行中`)&&(0,K.jsx)(Y,{size:`sm`,variant:`ghost`,className:`h-5 gap-1 px-1.5 text-[10px] text-red-400 hover:text-red-300`,onClick:()=>{h(``),M()},children:`⏹ 中断`}),(0,K.jsx)(`span`,{ref:w})]})]})}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2 border-t p-2`,children:[(0,K.jsx)(nO,{value:c,onChange:e=>l(e.target.value),rows:1,placeholder:`描述问题…(Enter 发送,Shift+Enter 换行)`,className:`min-h-[38px] resize-none text-xs`,onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),P())}}),u?(0,K.jsx)(Y,{size:`icon`,variant:`destructive`,title:`中断当前对话`,onClick:M,children:(0,K.jsx)(Vg,{className:`h-3.5 w-3.5`})}):(0,K.jsx)(Y,{size:`icon`,disabled:!c.trim(),onClick:P,children:(0,K.jsx)(Cg,{className:`h-3.5 w-3.5`})}),(0,K.jsx)(Y,{size:`sm`,variant:`outline`,className:`shrink-0 text-[11px]`,onClick:async()=>{try{let e=await st(`/api/experience/draft`,{sessionId:t});S(e.markdown),b(``),_(!0)}catch(e){Z.error(String(e.message))}},children:`📥 沉淀经验`})]}),(0,K.jsx)(a_,{open:g,onOpenChange:_,children:(0,K.jsxs)(c_,{className:`max-w-xl`,children:[(0,K.jsx)(l_,{children:(0,K.jsx)(d_,{children:`经验回流 · AI 起草 → 人工审阅 → 写入 ARM`})}),(0,K.jsx)(p_,{value:y,onChange:e=>b(e.target.value),placeholder:`经验标题(留空自动生成)`,className:`text-xs`}),(0,K.jsx)(nO,{value:x,onChange:e=>S(e.target.value),className:`min-h-[260px] font-mono text-[11px]`}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,onClick:()=>_(!1),children:`取消`}),(0,K.jsx)(Y,{onClick:async()=>{try{let t=await st(`/api/experience/commit`,{agentId:e,name:y.trim()||`MVP经验-${gt(new Date().toISOString())}`,description:`工作台人工审阅沉淀`,content:x});_(!1),Z.success(`已回流 ARM 知识库`,{description:t.result.slice(0,90)})}catch(e){Z.error(String(e.message))}},children:`确认沉淀到 ARM 知识库`})]})]})})]})}var iO=function(e,t,n,r){var i;t[0]=0;for(var a=1;a<t.length;a++){var o=t[a++],s=t[a]?(t[0]|=o?1:2,n[t[a++]]):t[++a];o===3?r[0]=s:o===4?r[1]=Object.assign(r[1]||{},s):o===5?(r[1]=r[1]||{})[t[++a]]=s:o===6?r[1][t[++a]]+=s+``:o?(i=e.apply(s,iO(e,s,n,[``,null])),r.push(i),s[0]?t[0]|=2:(t[a-2]=0,t[a]=i)):r.push(s)}return r},aO=new Map;function oO(e){var t=aO.get(this);return t||(t=new Map,aO.set(this,t)),(t=iO(this,t.get(e)||(t.set(e,t=function(e){for(var t,n,r=1,i=``,a=``,o=[0],s=function(e){r===1&&(e||(i=i.replace(/^\s*\n\s*|\s*\n\s*$/g,``)))?o.push(0,e,i):r===3&&(e||i)?(o.push(3,e,i),r=2):r===2&&i===`...`&&e?o.push(4,e,0):r===2&&i&&!e?o.push(5,0,!0,i):r>=5&&((i||!e&&r===5)&&(o.push(r,0,i,n),r=6),e&&(o.push(r,e,0,n),r=6)),i=``},c=0;c<e.length;c++){c&&(r===1&&s(),s(c));for(var l=0;l<e[c].length;l++)t=e[c][l],r===1?t===`<`?(s(),o=[o],r=3):i+=t:r===4?i===`--`&&t===`>`?(r=1,i=``):i=t+i[0]:a?t===a?a=``:i+=t:t===`"`||t===`'`?a=t:t===`>`?(s(),r=1):r&&(t===`=`?(r=5,n=i,i=``):t===`/`&&(r<5||e[c][l+1]===`>`)?(s(),r===3&&(o=o[0]),r=o,(o=o[0]).push(2,0,r),r=0):t===` `||t===` `||t===`
100
- `||t===`\r`?(s(),r=2):i+=t),r===3&&i===`!--`&&(r=4,o=o[0])}return s(),o}(e)),t),arguments,[])).length>1?t:t[0]}var sO=oO.bind(v.createElement),cO=class extends v.Component{state={err:null};static getDerivedStateFromError(e){return{err:String(e?.message||e)}}componentDidCatch(e){try{this.props.onError?.(String(e?.message||e))}catch{}}render(){return this.state.err?(0,K.jsxs)(`div`,{className:`p-3 text-[11px] leading-relaxed text-red-400`,children:[`面板运行错误:`,this.state.err,(0,K.jsx)(`br`,{}),`可在「定制工作台」中修正代码后重新发布。`]}):this.props.children}};function lO(e){return Function(`React`,`html`,`useState`,`useEffect`,`useRef`,`useMemo`,`"use strict";\n${e}\n;if (typeof Panel !== "function") throw new Error("插件代码必须定义 function Panel(props)");\nreturn Panel;`)(v,sO,v.useState,v.useEffect,v.useRef,v.useMemo)}function uO(e,t,n){if(e)try{fetch(`/api/panel-error`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({...e,kind:t,message:n})}).catch(()=>{})}catch{}}function dO({code:e,data:t,meta:n}){let r=n?.agentId,i=n?.panelId,a=n?.pluginId,o=(0,v.useMemo)(()=>{let t={agentId:r,panelId:i,pluginId:a};try{return lO(e)}catch(e){return uO(t,`compile`,String(e.message)),()=>(0,K.jsxs)(`div`,{className:`p-3 text-[11px] text-red-400`,children:[`编译失败:`,String(e.message)]})}},[e,r,i,a]);return(0,K.jsx)(cO,{onError:e=>uO(n,`runtime`,e),children:(0,K.jsx)(o,{...t})})}var fO=12;function pO({dsl:e,renderPanel:t,renderDialog:n,renderPlaceholder:r,edit:i,className:a}){let o=(0,v.useRef)(null),s=(0,v.useRef)(null),c=e.panels.reduce((e,t)=>Math.max(e,(t.grid?.y||1)+(t.grid?.h||1)-1),1),l=()=>{let e=o.current?.getBoundingClientRect();return{col:e?(e.width+fO)/12:100,row:e?(e.height+fO)/c:178}},u=(t,n,r)=>{if(!i||t.button!==0)return;t.stopPropagation();let a=e.panels[n].grid||{x:1,y:1,w:6,h:1};s.current={i:n,mode:r,sx:t.clientX,sy:t.clientY,g:{...a},moved:!1};try{t.currentTarget.setPointerCapture(t.pointerId)}catch{}},d=e=>{let t=s.current;if(!i||!t)return;let n=e.clientX-t.sx,r=e.clientY-t.sy;if(!t.moved&&Math.abs(n)<4&&Math.abs(r)<4)return;t.moved=!0;let{col:a,row:o}=l(),c=Math.round(n/a),u=Math.round(r/o);t.mode===`move`?i.onGrid(t.i,{x:Math.min(Math.max(1,t.g.x+c),12-t.g.w+1),y:Math.max(1,t.g.y+u)}):i.onGrid(t.i,{w:Math.min(Math.max(1,t.g.w+c),12-t.g.x+1),h:Math.min(Math.max(1,t.g.h+u),12)})},f=()=>{setTimeout(()=>{s.current=null},0)};return(0,K.jsx)(`div`,{ref:o,className:it(`grid gap-3`,i&&`touch-none select-none`,a),style:{gridTemplateColumns:`repeat(12, minmax(0, 1fr))`,gridTemplateRows:`repeat(${c}, minmax(120px, 1fr))`},onPointerDown:()=>{i&&i.onSelect(null)},children:e.panels.map((e,a)=>{let o=e.grid||{x:1,y:1,w:6,h:1},s=Math.round(o.w/12*100),c=e.type===`agent_dialog`?n?n(e):null:e.type===`placeholder`?r?r(e):null:t(e);return(0,K.jsxs)(`div`,{style:{gridColumn:`${o.x} / span ${o.w}`,gridRow:`${o.y} / span ${o.h}`},className:it(`relative flex min-h-0 flex-col overflow-hidden rounded-lg border bg-card`,i?i.sel===a?`border-primary ring-2 ring-primary/50`:`border-border hover:border-primary/50`:`border-border`,i&&`cursor-grab active:cursor-grabbing`),onPointerDown:e=>{i&&(e.stopPropagation(),i.onSelect(a),u(e,a,`move`))},onPointerMove:d,onPointerUp:f,onPointerCancel:f,children:[i&&(0,K.jsxs)(`div`,{className:`pointer-events-none absolute inset-x-0 top-0 z-10 flex items-center gap-1.5 border-b bg-background/85 px-2 py-1 text-[10px] backdrop-blur-sm`,children:[(0,K.jsx)(`span`,{className:`font-medium`,children:e.title}),(0,K.jsx)(J,{variant:`secondary`,className:`h-4 px-1 text-[9px]`,children:e.panel||e.type}),(0,K.jsxs)(`span`,{className:`ml-auto font-mono text-muted-foreground`,children:[s,`%宽·`,o.h,`行`]})]}),(0,K.jsx)(`div`,{className:it(`min-h-0 flex-1 overflow-auto`,i&&`pointer-events-none pt-4`),children:c}),i&&(0,K.jsx)(`span`,{onPointerDown:e=>u(e,a,`resize`),onPointerMove:d,onPointerUp:f,onPointerCancel:f,className:`absolute bottom-0 right-0 z-10 h-4 w-4 cursor-nwse-resize rounded-br-md border-b border-r border-primary/60 bg-primary/25 hover:bg-primary/50`,title:`拖拽调跨列/跨行(当前 ${s}% 宽)`,children:(0,K.jsx)(rg,{className:`h-2.5 w-2.5 translate-x-[3px] translate-y-[3px] text-primary`})})]},e.id)})})}function mO(){return(0,K.jsxs)(`div`,{className:`relative mb-1 h-4 select-none text-[9px] text-muted-foreground`,children:[(0,K.jsx)(`div`,{className:`grid h-full grid-cols-12`,children:[...Array(12)].map((e,t)=>(0,K.jsx)(`div`,{className:`border-l border-border/60 pl-0.5 pt-0.5 font-mono`,children:t+1},t))}),[25,50,75].map(e=>(0,K.jsxs)(`span`,{className:`absolute -top-0 font-mono`,style:{left:`${e}%`},children:[e,`%`]},e))]})}function hO({open:e,onOpenChange:t,onPick:n}){let[r,i]=(0,v.useState)(null),[a,o]=(0,v.useState)(!1),[s,c]=(0,v.useState)(``),l=e=>{o(!0),c(``),ot(`/api/fs/dirs${e?`?path=${encodeURIComponent(e)}`:``}`).then(e=>i(e)).catch(e=>c(String(e.message))).finally(()=>o(!1))};return(0,v.useEffect)(()=>{e&&!r&&l()},[e]),(0,K.jsx)(a_,{open:e,onOpenChange:t,children:(0,K.jsxs)(c_,{className:`max-w-md`,children:[(0,K.jsx)(l_,{children:(0,K.jsx)(d_,{children:`选择工作区目录`})}),(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-7 gap-1 px-2 text-[11px]`,disabled:!r?.parent,onClick:()=>r?.parent&&l(r.parent),title:`上级目录`,children:[(0,K.jsx)(Zm,{className:`h-3 w-3`}),`上级`]}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-7 gap-1 px-2 text-[11px]`,onClick:()=>l(),children:[(0,K.jsx)(zh,{className:`h-3 w-3`}),`主目录`]}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate rounded-md border bg-muted/40 px-2 py-1.5 font-mono text-[11px] text-muted-foreground`,title:r?.path,children:r?.path||`…`})]}),(0,K.jsxs)(eO,{className:`h-64 rounded-md border`,children:[a&&(0,K.jsxs)(`div`,{className:`flex h-full items-center justify-center gap-2 text-xs text-muted-foreground`,children:[(0,K.jsx)($h,{className:`h-4 w-4 animate-spin`}),`读取中…`]}),!a&&s&&(0,K.jsx)(`div`,{className:`p-3 text-xs text-red-400`,children:s}),!a&&!s&&r&&r.dirs.length===0&&(0,K.jsx)(`div`,{className:`p-3 text-xs text-muted-foreground`,children:`此目录下没有子目录——可直接点「选择当前目录」。`}),!a&&!s&&r&&r.dirs.map(e=>(0,K.jsxs)(`button`,{onClick:()=>l(`${r.path}/${e}`),className:`flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent`,children:[(0,K.jsx)(Fh,{className:`h-3.5 w-3.5 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`truncate`,children:e})]},e))]}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,onClick:()=>t(!1),children:`取消`}),(0,K.jsxs)(Y,{className:`gap-1`,disabled:!r||a,onClick:()=>{r&&(n(r.path),t(!1))},children:[(0,K.jsx)(rh,{className:`h-3.5 w-3.5`}),`选择当前目录`]})]})]})})}function gO({agentId:e,onName:t,onEdit:n}){let[r,i]=(0,v.useState)(null),[a,o]=(0,v.useState)(null),[s,c]=(0,v.useState)(null),[l,u]=(0,v.useState)([]),[d,f]=(0,v.useState)(null),[p,m]=(0,v.useState)(2),[h,g]=(0,v.useState)(null),[_,y]=(0,v.useState)(!1),[b,x]=(0,v.useState)(``),[S,C]=(0,v.useState)(``),[w,T]=(0,v.useState)(!1),[E,D]=(0,v.useState)(!1),[O,k]=(0,v.useState)(null),[A,j]=(0,v.useState)(!1),M=(0,v.useMemo)(()=>h?.workspaces.find(e=>e.id===h.current)||null,[h]),N=M?.id||`default`,P=(0,v.useMemo)(()=>`chat-${e}-${N}`,[e,N]),F=()=>ot(`/api/state`).then(c).catch(()=>{}),I=()=>ot(`/api/workspaces?agent_id=${e}`).then(g).catch(()=>{});(0,v.useEffect)(()=>{ot(`/api/workbench?agent_id=${e}`).then(e=>{i(e.dsl),e.dsl&&t(e.dsl.workbench)}),ot(`/api/deployment?agent_id=${e}`).then(e=>{o(e.deployment),m({L0:0,L1:1,L2:2,L3:3}[e.deployment?.default_autonomy||`L2`]??2)}),ot(`/api/panels?with_code=1`).then(e=>u(e.plugins||[])),I(),F();let n=setInterval(F,5e3);return()=>clearInterval(n)},[e]);let L=async t=>{try{g(await st(`/api/workspaces/select`,{agent_id:e,ws_id:t}))}catch(e){Z.error(String(e.message))}},R=async()=>{D(!0);try{let t=await st(`/api/workspaces`,{agent_id:e,name:b||void 0,...S?{path:S}:{}});g(t),y(!1),x(``),C(``),Z.success(`工作区已创建${S?`(登记外部目录)`:``}`),await L(t.workspaces[t.workspaces.length-1].id)}catch(e){Z.error(String(e.message))}finally{D(!1)}},ee=async()=>{if(O)try{g(await lt(`/api/workspaces/${O.id}?agent_id=${e}`,{purge:A})),Z.success(`工作区已删除${A?`(目录已清除)`:`(仅移除登记)`}`),k(null),j(!1)}catch(e){Z.error(String(e.message))}},te=(0,v.useMemo)(()=>r?.panels||[],[r]).filter(e=>e.type===`custom`||e.type===`custom_panel`).map(e=>({panel:e,code:e.type===`custom`?e.code||``:l.find(t=>t.id===e.panel)?.code||``})).filter(e=>e.code),z=t=>({devices:s?.devices||[],alarms:s?.alarms||[],kpi:s?.kpi||{},work_orders:s?.work_orders||[],inspections:s?.inspections||{},selected:d,onSelect:f,agentId:e,store:mt(e,N),runAction:(n,r)=>ht(e,String(t?.id||``),n,r),params:{...t?.params||{},agentId:e,wsId:N}});return!r||!s?(0,K.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:`工作台加载中…`}):(0,K.jsxs)(`div`,{className:`flex h-full flex-col gap-2 overflow-hidden px-4 py-2.5`,children:[(0,K.jsx)(`h1`,{className:`sr-only`,children:r.workbench}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px]`,children:[(0,K.jsx)(J,{variant:`secondary`,className:`h-5 shrink-0 text-[10px]`,children:r.version}),te.length>0&&(0,K.jsxs)(J,{variant:`outline`,className:`h-5 shrink-0 text-[10px] text-violet-400 border-violet-500/40`,children:[(0,K.jsx)(pg,{className:`mr-0.5 h-2.5 w-2.5`}),`插件 ×`,te.length]}),(0,K.jsxs)(`span`,{className:`shrink-0 text-muted-foreground`,children:[a?.name,` · 工具 `,a?.toolset.length,` 个`]}),M&&(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(jh,{className:`h-3 w-3 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-muted-foreground`,title:M.path,children:M.path}),(0,K.jsx)(`span`,{className:`shrink-0 text-[10px] text-muted-foreground`,children:`(exec 工作目录 · 数据与文件随工作区隔离)`})]}),(0,K.jsxs)(`div`,{className:`ml-auto flex items-center gap-1.5`,children:[(0,K.jsx)(qh,{className:`h-3.5 w-3.5 text-muted-foreground`}),(0,K.jsxs)(h_,{value:N,onValueChange:L,children:[(0,K.jsx)(__,{className:`h-8 w-52 text-xs`,title:M?.path,children:(0,K.jsx)(g_,{children:(0,K.jsx)(`span`,{className:`truncate`,children:M?`${M.name}${M.external?`(外部)`:``}`:`默认工作区`})})}),(0,K.jsx)(v_,{children:(h?.workspaces||[]).map(e=>(0,K.jsx)(y_,{value:e.id,className:`text-xs`,children:(0,K.jsxs)(`span`,{className:`max-w-64 truncate`,title:e.path,children:[e.name,e.external?` · 外部目录`:``,e.id===h?.current?` ✓`:``]})},e.id))})]}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-8 gap-1 text-xs`,onClick:()=>y(!0),title:`新建工作区(默认目录或自定义路径)`,children:[(0,K.jsx)(Nh,{className:`h-3.5 w-3.5`}),`新建`]}),M&&M.id!=="default"&&(0,K.jsx)(Y,{size:`sm`,variant:`ghost`,className:`h-8 w-8 p-0 text-muted-foreground`,onClick:()=>k(M),title:`删除当前工作区`,children:(0,K.jsx)(qg,{className:`h-3.5 w-3.5`})}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-8 gap-1 text-xs`,onClick:n,children:[(0,K.jsx)(Dg,{className:`h-3.5 w-3.5`}),`编辑布局`]})]})]}),(0,K.jsx)(`div`,{className:`relative min-h-0 flex-1`,children:(0,K.jsx)(pO,{className:`absolute inset-0 overflow-auto p-0.5`,dsl:r,renderPanel:t=>{let n=te.find(e=>e.panel.id===t.id);return n?(0,K.jsx)(dO,{code:n.code,data:z(t),meta:{agentId:e,panelId:t.id,pluginId:t.panel}},`${t.id}:${N}`):null},renderDialog:()=>(0,K.jsx)(rO,{agentId:e,sessionId:P,wsId:N,injectedDevice:d,autonomy:p,onAutonomy:m},`${e}:${N}`),renderPlaceholder:()=>(0,K.jsx)(`div`,{className:`flex h-full items-center justify-center p-4 text-center text-[11px] text-muted-foreground`,children:`空区块——到「编辑布局」添加插件或让 AI 定制`})})}),(0,K.jsx)(a_,{open:_,onOpenChange:y,children:(0,K.jsxs)(c_,{children:[(0,K.jsx)(l_,{children:(0,K.jsx)(d_,{children:`新建工作区`})}),(0,K.jsxs)(`div`,{className:`space-y-3`,children:[(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`名称`}),(0,K.jsx)(p_,{value:b,onChange:e=>x(e.target.value),placeholder:`如:产线B改造`,className:`text-xs`})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`自定义目录(可选,留空则在平台 workspace 目录下动态新增)`}),(0,K.jsxs)(`div`,{className:`flex gap-1.5`,children:[(0,K.jsx)(p_,{value:S,onChange:e=>C(e.target.value),placeholder:`/Users/you/projects/line-b 或点浏览选择`,className:`font-mono text-xs`}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-8 shrink-0 gap-1 text-xs`,onClick:()=>T(!0),children:[(0,K.jsx)(jh,{className:`h-3.5 w-3.5`}),`浏览…`]})]}),(0,K.jsx)(`p`,{className:`text-[10px] text-amber-400`,children:`⚠ 助手将能读写该目录(exec 工作目录即此处);目录须已存在,平台不会在其中写入数据库文件。`})]})]}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,disabled:E,onClick:()=>y(!1),children:`取消`}),(0,K.jsx)(Y,{disabled:E,onClick:R,children:E?`创建中…`:`创建并切换`})]}),(0,K.jsx)(hO,{open:w,onOpenChange:T,onPick:e=>C(e)})]})}),(0,K.jsx)(a_,{open:!!O,onOpenChange:e=>{e||(k(null),j(!1))},children:(0,K.jsxs)(c_,{children:[(0,K.jsx)(l_,{children:(0,K.jsxs)(d_,{children:[`删除工作区 · `,O?.name]})}),(0,K.jsxs)(`div`,{className:`space-y-2 text-xs`,children:[(0,K.jsx)(`p`,{className:`font-mono text-[11px] text-muted-foreground`,children:O?.path}),O?.external?(0,K.jsxs)(`p`,{children:[`外部目录工作区:仅移除登记,`,(0,K.jsx)(`b`,{children:`不删除`}),`你的文件;该工作区的数据集库将一并删除。`]}):(0,K.jsxs)(`label`,{className:`flex items-start gap-2 rounded-md border border-red-500/30 bg-red-500/5 p-2.5`,children:[(0,K.jsx)(i_,{checked:A,onCheckedChange:e=>j(!!e)}),(0,K.jsx)(`span`,{children:`同时删除平台目录下的工作区文件夹(数据集库始终删除)`})]})]}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,onClick:()=>k(null),children:`取消`}),(0,K.jsx)(Y,{variant:`destructive`,onClick:ee,children:`确认删除`})]})]})})]})}function _O({className:e,orientation:t=`horizontal`,decorative:n=!0,...r}){return(0,K.jsx)(Fp,{"data-slot":`separator`,decorative:n,orientation:t,className:mn(`shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px`,e),...r})}function vO({className:e,orientation:t=`horizontal`,...n}){return(0,K.jsx)(lm,{"data-slot":`tabs`,"data-orientation":t,orientation:t,className:mn(`group/tabs flex gap-2 data-[orientation=horizontal]:flex-col`,e),...n})}var yO=yt(`group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=line]:rounded-none`,{variants:{variant:{default:`bg-muted`,line:`gap-1 bg-transparent`}},defaultVariants:{variant:`default`}});function bO({className:e,variant:t=`default`,...n}){return(0,K.jsx)(dm,{"data-slot":`tabs-list`,"data-variant":t,className:mn(yO({variant:t}),e),...n})}function xO({className:e,...t}){return(0,K.jsx)(pm,{"data-slot":`tabs-trigger`,className:mn(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent`,`data-[state=active]:bg-background data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100`,e),...t})}function SO({className:e,...t}){return(0,K.jsx)(hm,{"data-slot":`tabs-content`,className:mn(`flex-1 outline-none`,e),...t})}function CO({...e}){return(0,K.jsx)(gd,{"data-slot":`dropdown-menu`,...e})}function wO({...e}){return(0,K.jsx)(vd,{"data-slot":`dropdown-menu-trigger`,...e})}function TO({className:e,sideOffset:t=4,...n}){return(0,K.jsx)(yd,{children:(0,K.jsx)(xd,{"data-slot":`dropdown-menu-content`,sideOffset:t,className:mn(`z-50 min-w-36 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95`,e),...n})})}function EO({className:e,...t}){return(0,K.jsx)(Sd,{"data-slot":`dropdown-menu-item`,className:mn(`relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-xs outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:h-3.5 [&_svg]:w-3.5 [&_svg]:shrink-0`,e),...t})}function DO({className:e,...t}){return(0,K.jsx)(Cd,{"data-slot":`dropdown-menu-separator`,className:mn(`-mx-1 my-1 h-px bg-border`,e),...t})}async function OO(e,t){let n=e.usage.length?`插件「${e.name}」被 ${e.usage.length} 处引用,删除将从这些工作台摘除该面板。确认删除?`:`删除插件「${e.name}」?`;if(window.confirm(n))try{await lt(`/api/panels`,{id:e.id,force:!0}),Z.success(`已删除`),t()}catch(e){Z.error(String(e.message))}}function kO({target:e,onClose:t,agents:n}){let[r,i]=(0,v.useState)(null),[a,o]=(0,v.useState)(``),[s,c]=(0,v.useState)(!0),[l,u]=(0,v.useState)(!1);(0,v.useEffect)(()=>{if(!e){i(null);return}let n=e.type===`panel`?`id=${encodeURIComponent(e.id||``)}`:`agentId=${encodeURIComponent(e.agentId||``)}`;ot(`/api/assets/preview?type=${e.type}&${n}`).then(e=>{i(e),o(e.name)}).catch(e=>{Z.error(String(e.message)),t()})},[e]);let d=async()=>{if(e){u(!0);try{let n=await st(`/api/assets/share`,{type:e.type,id:e.id,agentId:e.agentId,name:a,bind_agent:s&&e.agentId?e.agentId:void 0}),i=r?.manifest.requires.apis.length||0,o=r?.manifest.requires.actions.length||0;Z.success(`已发布 ${n.name}@${n.version}${n.bound?`,已绑定到助手`:``}`,{description:`外部 API ×${i} · 交互脚本 ×${o}${o?`(命令全文已在 ARM 资产包 SKILL.md 留档)`:``}`}),t()}catch(e){Z.error(String(e.message))}finally{u(!1)}}};if(!e)return null;let f=r?.manifest.requires;return(0,K.jsx)(a_,{open:!!e,onOpenChange:e=>{!e&&!l&&t()},children:(0,K.jsxs)(c_,{children:[(0,K.jsx)(l_,{children:(0,K.jsxs)(d_,{className:`flex items-center gap-2`,children:[(0,K.jsx)(_h,{className:`h-4 w-4 text-primary`}),`发布为 UI 资产 · `,e.title]})}),(0,K.jsx)(eO,{className:`max-h-96`,children:(0,K.jsxs)(`div`,{className:`space-y-3 pr-2 text-xs`,children:[(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`资产名(全局唯一锚,同名发布追加新版本)`}),(0,K.jsx)(p_,{value:a,onChange:e=>o(e.target.value),className:`font-mono text-xs`})]}),r&&(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`div`,{className:`rounded-md border bg-muted/30 p-2.5`,children:[(0,K.jsx)(`div`,{className:`font-medium`,children:`包含内容`}),(0,K.jsxs)(`div`,{className:`mt-1 text-muted-foreground`,children:[`面板插件:`,r.manifest.provides.panels.join(`、`)||`无`,(0,K.jsx)(`br`,{}),`数据集 schema:`,r.manifest.provides.collections.join(`、`)||`无`,`(仅建表定义,不含数据)`,r.manifest.provides.workbench&&(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(`br`,{}),`工作台 DSL:workbench.json`]})]}),(0,K.jsx)(`div`,{className:`mt-1 font-mono text-[10px] text-muted-foreground`,children:r.files.join(` · `)})]}),!!f?.apis.length&&(0,K.jsxs)(`div`,{className:`rounded-md border border-blue-500/30 bg-blue-500/5 p-2.5`,children:[(0,K.jsx)(`div`,{className:`font-medium text-blue-300`,children:`外部 API 依赖(安装后环境需可达)`}),(0,K.jsx)(`ul`,{className:`mt-1 list-disc pl-4 text-muted-foreground`,children:f.apis.map(e=>(0,K.jsxs)(`li`,{children:[(0,K.jsx)(`span`,{className:`font-mono`,children:e.host}),`:`,e.usage]},e.host))})]}),!!f?.actions.length&&(0,K.jsxs)(`div`,{className:`rounded-md border border-amber-500/30 bg-amber-500/5 p-2.5`,children:[(0,K.jsx)(`div`,{className:`font-medium text-amber-300`,children:`交互脚本(真实 shell 命令,随包公开)`}),(0,K.jsx)(`ul`,{className:`mt-1 space-y-1`,children:f.actions.map(e=>(0,K.jsxs)(`li`,{className:`text-muted-foreground`,children:[`[`,e.panel,`/`,e.id,`] `,e.label,e.has_credentials&&(0,K.jsx)(J,{className:`ml-1 h-4 bg-amber-500/15 px-1 text-[9px] text-amber-300`,children:`⚠️ 疑似含凭据`}),(0,K.jsx)(`div`,{className:`mt-0.5 break-all rounded bg-muted/50 p-1 font-mono text-[10px]`,children:e.exec})]},`${e.panel}/${e.id}`))}),(0,K.jsx)(`p`,{className:`mt-1.5 text-[10px] text-amber-400`,children:`命令明文将进入资产包——含密码/令牌的命令请先改用环境变量或凭据占位,再发布。`})]}),e.agentId&&n&&n.length>0&&(0,K.jsxs)(`label`,{className:`flex items-center gap-2 rounded-md border p-2.5`,children:[(0,K.jsx)(i_,{checked:s,onCheckedChange:e=>c(!!e)}),(0,K.jsx)(`span`,{children:`发布后同时绑定到当前助手(下载该助手的其他现场将自动物化此工作台)`})]})]})]})}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,disabled:l,onClick:t,children:`取消`}),(0,K.jsx)(Y,{disabled:l||!a,onClick:d,children:l?`发布中…`:`发布到 ARM`})]})]})})}function AO({open:e,onClose:t,onInstalled:n,agents:r}){let[i,a]=(0,v.useState)(``),[o,s]=(0,v.useState)([]),[c,l]=(0,v.useState)(!1),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(0);(0,v.useEffect)(()=>{if(!e)return;let t=setTimeout(()=>{let e=++m.current;l(!0),ot(`/api/assets/arm-library${i?`?keyword=${encodeURIComponent(i)}`:``}`).then(t=>{e===m.current&&s(t.items||[])}).catch(e=>Z.error(String(e.message))).finally(()=>{e===m.current&&l(!1)})},400);return()=>clearTimeout(t)},[i,e]),(0,v.useEffect)(()=>{e&&!f&&r.length&&p(r[0].agent_id)},[e,r]);let h=async e=>{if(e.asset_type===`workbench`&&!f)Z.warning(`请先选择目标助手`);else{d(e.name);try{let r=await st(`/api/assets/install`,{name:e.name,agentId:e.asset_type===`workbench`?f:void 0}),i=r.workbench?`,工作台已导入为草稿(审阅后在「定制工作台」发布)`:``,a=r.skipped_collections.length?`;同名数据集保留本地:${r.skipped_collections.join(`、`)}`:``;Z.success(`已安装 ${e.name}:面板 ×${r.panels.length}${i}${a}`),n(),t()}catch(e){Z.error(String(e.message))}finally{d(null)}}};return(0,K.jsx)(a_,{open:e,onOpenChange:e=>{!e&&!u&&t()},children:(0,K.jsxs)(c_,{children:[(0,K.jsx)(l_,{children:(0,K.jsxs)(d_,{className:`flex items-center gap-2`,children:[(0,K.jsx)(Yh,{className:`h-4 w-4 text-primary`}),`从 ARM 安装 UI 资产`]})}),(0,K.jsxs)(`div`,{className:`relative`,children:[(0,K.jsx)(xg,{className:`absolute left-3 top-2.5 h-3.5 w-3.5 text-muted-foreground`}),(0,K.jsx)(p_,{placeholder:`搜索资产名 / 描述…`,value:i,onChange:e=>a(e.target.value),className:`pl-9`,autoFocus:!0})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,K.jsx)(`span`,{className:`shrink-0`,children:`工作台资产安装到:`}),(0,K.jsx)(`select`,{value:f,onChange:e=>p(e.target.value),className:`h-8 flex-1 rounded-md border bg-background px-2 text-xs`,children:r.map(e=>(0,K.jsx)(`option`,{value:e.agent_id,children:e.name},e.agent_id))})]}),(0,K.jsx)(eO,{className:`max-h-80`,children:(0,K.jsxs)(`div`,{className:`space-y-1.5 pr-2`,children:[c&&!o.length&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:`加载中…`}),!c&&!o.length&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:i?`没有匹配资产`:`ARM 上暂无 UI 资产`}),o.map(e=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2.5 rounded-md border p-2.5`,children:[e.asset_type===`workbench`?(0,K.jsx)(Yh,{className:`h-4 w-4 shrink-0 text-violet-400`}):(0,K.jsx)(pg,{className:`h-4 w-4 shrink-0 text-primary`}),(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs font-medium`,children:[(0,K.jsx)(`span`,{className:`truncate font-mono`,children:e.name}),e.latest_version&&(0,K.jsx)(J,{variant:`secondary`,className:`h-4 px-1 text-[9px]`,children:e.latest_version}),e.installed&&(0,K.jsx)(J,{className:`h-4 bg-emerald-500/15 px-1 text-[9px] text-emerald-400`,children:`本地已有`}),e.upgrade_available&&(0,K.jsx)(J,{className:`h-4 bg-amber-500/15 px-1 text-[9px] text-amber-300`,children:`⤴ 可升级`})]}),(0,K.jsxs)(`div`,{className:`truncate text-[10px] text-muted-foreground`,children:[e.description||`—`,` · 下载 `,e.download_count,` 次 · `,e.publisher]})]}),(0,K.jsx)(Y,{size:`sm`,variant:`secondary`,className:`h-7 text-[11px]`,disabled:u!==null,onClick:()=>h(e),children:u===e.name?`安装中…`:`安装`})]},e.name))]})}),(0,K.jsx)(u_,{children:(0,K.jsx)(Y,{variant:`outline`,onClick:t,children:`关闭`})})]})})}function jO(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(!1),[o,s]=(0,v.useState)([]),c=()=>ot(`/api/plugins/center`).then(t);if((0,v.useEffect)(()=>{c(),ot(`/api/agents`).then(e=>s((e.agents||[]).filter(e=>e.installed).map(({agent_id:e,name:t})=>({agent_id:e,name:t})))).catch(()=>{})},[]),!e)return(0,K.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:`插件中心加载中…`});let l=async(e,t,n)=>{let r=n===`deprecated`?`active`:`deprecated`;try{await st(`/api/plugins/lifecycle`,{kind:e,id:t,status:r}),Z.success(r===`deprecated`?`已停用(存量引用仍可渲染,新增被阻止)`:`已恢复`),c()}catch(e){Z.error(String(e.message))}},u=({icon:e,name:t,sub:n,status:r,usage:i,onToggle:a,tag:o,onDelete:s,onShare:c,armRef:l})=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2.5 rounded-md border p-2.5`,children:[(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs font-medium`,children:[e,t,(0,K.jsx)(J,{variant:`secondary`,className:`h-4 px-1 text-[9px]`,children:o}),(0,K.jsx)(J,{className:`h-4 px-1 text-[9px] ${r===`deprecated`?`bg-red-500/15 text-red-400 hover:bg-red-500/25`:`bg-emerald-500/15 text-emerald-400 hover:bg-emerald-500/25`}`,children:r===`deprecated`?`已停用`:`在用`}),l&&(0,K.jsxs)(J,{className:`h-4 bg-violet-500/15 px-1 text-[9px] text-violet-300`,title:`ARM ${l.skill_name}@${l.version||``}`,children:[`已发布`,l.version?` ${l.version}`:``]})]}),(0,K.jsx)(`div`,{className:`truncate text-[10px] text-muted-foreground`,children:n}),(0,K.jsxs)(`div`,{className:`mt-0.5 text-[10px] text-muted-foreground`,children:[`引用:`,i.length?i.map(e=>`${e.agent}${e.draft?`*`:``}`).join(`、`):`无`]})]}),c&&(0,K.jsxs)(Y,{size:`sm`,variant:`ghost`,className:`h-7 text-[11px] text-violet-400`,onClick:c,title:`发布到 ARM UI 资产市场`,children:[(0,K.jsx)(_h,{className:`h-3 w-3`}),l?`更新`:`发布`]}),s&&(0,K.jsx)(Y,{size:`sm`,variant:`ghost`,className:`h-7 text-[11px] text-red-400`,onClick:s,children:`删除`}),(0,K.jsx)(Y,{size:`sm`,variant:r===`deprecated`?`secondary`:`ghost`,className:`h-7 text-[11px] ${r===`deprecated`?``:`text-red-400`}`,onClick:a,children:r===`deprecated`?`恢复`:`停用`})]});return(0,K.jsxs)(`div`,{className:`h-full overflow-auto p-5`,children:[(0,K.jsxs)(`div`,{className:`mb-4`,children:[(0,K.jsxs)(`h1`,{className:`flex items-center gap-2 text-lg font-bold`,children:[(0,K.jsx)(pg,{className:`h-5 w-5 text-primary`}),`插件中心`]}),(0,K.jsxs)(`p`,{className:`mt-0.5 text-xs text-muted-foreground`,children:[`统一注册表:系统面板与契约插件同源治理 · 生命周期(在用/停用)· 引用追踪(* 为草稿引用)· `,(0,K.jsx)(`span`,{className:`text-violet-400`,children:`发布/安装 ARM UI 资产(三资产模型)`})]})]}),(0,K.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsxs)(Sm,{className:`flex items-center gap-1.5 text-xs`,children:[(0,K.jsx)(Dh,{className:`h-3.5 w-3.5`}),`系统插件(平台预装)`]})}),(0,K.jsx)(Cm,{className:`p-3`,children:(0,K.jsx)(`div`,{className:`space-y-1.5`,children:e.system.map(e=>(0,K.jsx)(u,{icon:(0,K.jsx)(`span`,{className:`font-mono text-[10px] text-muted-foreground`,children:e.id}),name:e.name,sub:e.note,status:e.status,usage:e.usage,tag:`system`,onToggle:()=>l(`system`,e.id,e.status)},e.id))})})]}),(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsxs)(Sm,{className:`flex items-center gap-1.5 text-xs`,children:[(0,K.jsx)(th,{className:`h-3.5 w-3.5`}),`插件库(AI 开发 / 人工沉淀)`]}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-7 gap-1 text-[11px]`,onClick:()=>a(!0),children:[(0,K.jsx)(Yh,{className:`h-3 w-3`}),`从 ARM 安装`]})]})}),(0,K.jsx)(Cm,{className:`p-3`,children:(0,K.jsxs)(`div`,{className:`space-y-1.5`,children:[e.library.map(e=>(0,K.jsx)(u,{icon:(0,K.jsx)(pg,{className:`h-3 w-3 text-primary`}),name:`${e.name} ${e.version}`,sub:`${e.author===`ai`?`AI 开发`:e.author===`arm`?`ARM 安装`:`人工`} · ${e.description||e.id}`,status:e.status,usage:e.usage,tag:e.author===`ai`?`ai`:e.author===`arm`?`arm`:`human`,onToggle:()=>l(`plugin`,e.id,e.status),onDelete:()=>OO(e,c),onShare:()=>r({type:`panel`,id:e.id,title:e.name}),armRef:e.arm_ref},e.id)),e.library.length===0&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:`插件库为空`})]})})]})]}),(0,K.jsx)(_O,{className:`my-4`}),(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsxs)(Sm,{className:`flex items-center gap-1.5 text-xs`,children:[(0,K.jsx)(Ng,{className:`h-3.5 w-3.5`}),`治理策略`]})}),(0,K.jsx)(Cm,{className:`p-3 text-[11px] leading-relaxed text-muted-foreground`,children:(0,K.jsx)(eO,{className:`max-h-40`,children:(0,K.jsxs)(`ul`,{className:`list-disc space-y-1 pl-4`,children:[(0,K.jsx)(`li`,{children:`一切面板进同一注册表:系统插件也有 manifest 与生命周期,不再是编译进前端的二等公民`}),(0,K.jsx)(`li`,{children:`停用(deprecate)不破坏存量:已引用的工作台继续渲染,但编辑器「添加面板」不再出现——安全下线`}),(0,K.jsx)(`li`,{children:`入库强制过校验器(check-panel.mjs):编译/契约/沙箱/模板四关 + 质量警告入审计——ARM 安装的插件同样过检`}),(0,K.jsx)(`li`,{children:`出网最小化:/api/proxy 仅放行插件代码中声明过的主机(防止面板成为任意内网跳板)`}),(0,K.jsx)(`li`,{children:`版本化与回滚:插件独立版本(同 id 覆盖自增),工作台按 id 引用,升级即时生效可回滚`}),(0,K.jsx)(`li`,{children:`数据隔离:插件数据集按助手分库(store-助手ID.db),共享需显式 scope=shared;资产包只带 schema 不带数据`}),(0,K.jsx)(`li`,{children:`UI 资产四红线(docs/08):包非运行时 · 数据必走 collection · 外部依赖必声明 · 单向 DAG`})]})})})]}),(0,K.jsx)(kO,{target:n,onClose:()=>{r(null),c()},agents:o}),(0,K.jsx)(AO,{open:i,onClose:()=>a(!1),onInstalled:c,agents:o})]})}function MO({pluginId:e,onRollback:t}){let[n,r]=(0,v.useState)(null);return(0,v.useEffect)(()=>{e&&ot(`/api/panels?id=${e}`).then(e=>r(e.plugin)).catch(()=>r(null))},[e]),n?(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[11px]`,children:[(0,K.jsx)(`span`,{className:`font-mono`,children:n.version}),(0,K.jsx)(`span`,{className:`text-muted-foreground`,children:`(当前)`})]}),(n.history||[]).slice().reverse().map(n=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px]`,children:[(0,K.jsx)(`span`,{className:`font-mono`,children:n.version}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:gt(n.at,`dts`)}),(0,K.jsx)(Y,{size:`sm`,variant:`ghost`,className:`ml-auto h-6 text-[10px]`,onClick:()=>t(e,n.version),children:`回退`})]},n.version)),!(n.history||[]).length&&(0,K.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,children:`无历史版本`})]}):(0,K.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,children:`(插件信息加载中…)`})}var NO=e=>({x:1,y:e.reduce((e,t)=>Math.max(e,t.grid?t.grid.y+t.grid.h-1:0),0)+1,w:6,h:1});function PO({agentId:e}){let[t,n]=(0,v.useState)(null),[r,i]=(0,v.useState)(!1),[a,o]=(0,v.useState)([]),[s,c]=(0,v.useState)(``),[l,u]=(0,v.useState)(!1),[d,f]=(0,v.useState)([]),[p,m]=(0,v.useState)(!1),[h,g]=(0,v.useState)(null),[_,y]=(0,v.useState)(null),[b,x]=(0,v.useState)(!1),[S,C]=(0,v.useState)(0),[w,T]=(0,v.useState)(null),[E,D]=(0,v.useState)([]),[O,k]=(0,v.useState)(null),A=(0,v.useRef)(`dev-${e.slice(0,8)}`).current,j=(0,v.useRef)(null),[M,N]=(0,v.useState)([]),[P,F]=(0,v.useState)(``),[I,L]=(0,v.useState)(!1),[R,ee]=(0,v.useState)(``),[te,z]=(0,v.useState)(null),[ne,re]=(0,v.useState)(!1),[ie,ae]=(0,v.useState)(null),oe=(0,v.useRef)(null),se=(0,v.useRef)(!0),ce=(0,v.useCallback)(()=>{let e=oe.current?.closest(`[data-slot="scroll-area-viewport"]`);e&&(e.scrollTop=e.scrollHeight)},[]);(0,v.useEffect)(()=>{let e=oe.current?.closest(`[data-slot="scroll-area-viewport"]`);if(!e)return;let t=()=>{se.current=e.scrollHeight-e.scrollTop-e.clientHeight<80};return e.addEventListener(`scroll`,t),()=>e.removeEventListener(`scroll`,t)},[]),(0,v.useEffect)(()=>{se.current&&ce()},[M,I,R,ce]);let le=()=>{ot(`/api/workbench?agent_id=${e}&draft=1`).then(e=>{n(e.dsl),i(e.isDraft),o(e.versions||[]),c(JSON.stringify(e.dsl,null,2))}),ot(`/api/panels`).then(e=>f(e.plugins||[]))};if((0,v.useEffect)(()=>{le()},[e]),(0,v.useEffect)(()=>{let e=()=>ot(`/api/state`).then(T).catch(()=>{});e();let t=setInterval(e,5e3);return ot(`/api/panels?with_code=1`).then(e=>D(e.plugins||[])),()=>clearInterval(t)},[]),!t)return(0,K.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:`加载工作台 DSL…`});let B=t.panels,V=_===null?null:B[_],H=e=>{let r=JSON.parse(JSON.stringify(t));e(r),n(r),c(JSON.stringify(r,null,2)),i(!0)},ue=(e,t)=>H(n=>{let r=n.panels[e].grid||{x:1,y:1,w:6,h:1};n.panels[e].grid={...r,...t}}),de=t=>({devices:w?.devices||[],alarms:w?.alarms||[],kpi:w?.kpi||{},work_orders:w?.work_orders||[],inspections:w?.inspections||{},selected:O,onSelect:k,agentId:e,store:mt(e),runAction:(n,r)=>ht(e,String(t.id),n,r),params:{...t.params||{},agentId:e,wsId:`default`}}),fe=e=>e.type===`custom`?e.code:E.find(t=>t.id===e.panel)?.code||``,pe=()=>H(e=>e.panels.push({id:`block_${Math.random().toString(36).slice(2,6)}`,type:`placeholder`,title:`空区块`,grid:NO(e.panels)})),me=(e,t)=>{H(n=>{if(e!==null&&e<n.panels.length){let r=n.panels[e];Object.assign(r,{type:`custom_panel`,panel:t.id,title:r.title===`空区块`?t.name:r.title})}else n.panels.push({id:`plug_${t.id}_${Math.random().toString(36).slice(2,5)}`,type:`custom_panel`,title:t.name,panel:t.id,grid:NO(n.panels)})}),m(!1),g(null),Z.success(`已插入「${t.name}」(草稿,待发布)`)},he=async e=>{let t=B[e];z(e);let n=``;try{let e=t.panel||t.id,r=await ot(`/api/panel-errors?key=${encodeURIComponent(e)}`);n=r.errors?.length?r.errors.map(e=>`[${e.kind}] ${e.message}`).join(` | `):``}catch{}F(`请调试该插件:${n?`最近运行错误:${n}。`:`暂无上报错误,请先 read_panel_plugin 审代码,重点检查结果处理与错误路径。`}请定位根因、修复并说明验证方式。`),Z.info(`已锁定调试目标并带上错误上下文,发送即开始`)},ge=async(e,t)=>{try{let n=await st(`/api/panels/rollback`,{id:e,version:t});Z.success(`已回退到 ${t}(新版本号 ${n.plugin.version},引用即时生效)`),le()}catch(e){Z.error(String(e.message))}},_e=()=>{if(te===null||!B[te])return``;let e=B[te],t=e.grid||{x:1,y:1,w:6,h:1},n=Math.round(t.w/12*100),r=t.w<=3?`窄条(紧凑单列列表/迷你卡)`:t.w>=9?`宽区块(表格/多列仪表)`:`中等宽度(两列卡/紧凑表)`;return`【定制目标】区块「${e.title}」(id=${e.id}):第${t.x}列起、跨${t.w}列(约${n}%宽)、跨${t.h}行(${r})。${e.panel?`当前引用插件 ${e.panel}——先 read_panel_plugin 再决定改造还是重写。`:`空区块,可新建插件。`}`},ve=e=>{z(e),F(``),Z.info(`已锁定定制目标「${B[e].title}」——在右侧描述需求即可`)},ye=async()=>{u(!0);try{let r=await ct(`/api/workbench`,{agent_id:e,dsl:t});n(r.dsl),o(r.versions),c(JSON.stringify(r.dsl,null,2)),i(!1),re(!1),Z.success(`已发布 ${r.dsl.version},工作台即时生效`)}catch(e){Z.error(String(e.message))}finally{u(!1)}},be=async()=>{await lt(`/api/workbench/draft`,{agent_id:e}),Z.success(`已放弃草稿`),le()},xe=async t=>{try{let r=await st(`/api/workbench/rollback`,{agent_id:e,version:t});n(r.dsl),o(r.versions),c(JSON.stringify(r.dsl,null,2)),i(!1),Z.success(`已回滚到 ${t}`)}catch(e){Z.error(String(e.message))}},U=()=>{j.current?.abort()},Se=async()=>{let t=P.trim();if(!t||I)return;let n=_e()?`${_e()}\n需求:${t}`:t;F(``),L(!0),re(!1),se.current=!0,N(e=>[...e,{role:`user`,text:t}]);let r=!1,i=new AbortController;j.current=i;try{await ut(`/api/dev/chat`,{sessionId:A,agentId:e,message:n},e=>{let t=e.type;t===`status`?ee(String(e.text||``)):t===`text_delta`?(ee(``),N(t=>{let n=t[t.length-1];return n?.role===`agent`&&n.streaming?[...t.slice(0,-1),{...n,text:n.text+String(e.delta)}]:[...t,{role:`agent`,text:String(e.delta),streaming:!0}]})):t===`tool_start`?(r=!0,N(t=>[...t,{role:`agent`,text:``,streaming:!1,events:[{tool:String(e.tool),args:e.args||{}}]}])):t===`tool_end`?N(t=>{for(let n=t.length-1;n>=0;n--){let r=t[n];if(r.role===`agent`&&r.events){for(let n=r.events.length-1;n>=0;n--)if(r.events[n].tool===e.tool&&r.events[n].result===void 0)return r.events[n].result=String(e.result||``),r.events[n].ok=e.ok!==!1,[...t]}}return t}):t===`interrupted`?(ee(``),N(e=>[...e,{role:`agent`,text:`(已中断)`}])):t===`meta`?e.hasDraft?(re(!0),le()):r&&le():t===`error`&&Z.error(String(e.message))},i.signal)}catch(e){i.signal.aborted?N(e=>[...e,{role:`agent`,text:`(已中断)`}]):N(t=>[...t,{role:`agent`,text:`❌ ${String(e.message)}`}])}finally{ee(``),L(!1),j.current===i&&(j.current=null)}};return(0,K.jsxs)(`div`,{className:`flex h-full flex-col gap-3 overflow-hidden p-5`,children:[(0,K.jsxs)(`div`,{className:`flex shrink-0 items-end justify-between`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h1`,{className:`text-lg font-bold`,children:`定制工作台`}),(0,K.jsx)(`p`,{className:`mt-0.5 text-xs text-muted-foreground`,children:`区块你规划 · 插件按区块占比定制 · 一切修改走草稿审阅发布`})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(J,{variant:`secondary`,children:r?`草稿(未发布)`:`线上 ${t.version}`}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,onClick:()=>{g(null),m(!0)},children:[(0,K.jsx)(pg,{className:`mr-1 h-3.5 w-3.5`}),`插件库`]}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,title:`把当前工作台(含依赖插件/数据集 schema/交互脚本)发布为 ARM UI 资产`,onClick:()=>ae({type:`workbench`,agentId:e,title:t.workbench}),children:[(0,K.jsx)(_h,{className:`mr-1 h-3.5 w-3.5 text-violet-400`}),`导出资产`]}),(0,K.jsxs)(Y,{size:`sm`,disabled:l||!r,onClick:ye,children:[(0,K.jsx)(yg,{className:`mr-1 h-3.5 w-3.5`}),l?`发布中…`:`审阅后发布`]})]})]}),r&&(0,K.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2 rounded-md border border-amber-500/50 bg-amber-500/10 px-3 py-2 text-xs text-amber-300`,children:[(0,K.jsx)(`span`,{children:`⚠`}),`草稿未发布——审阅后发布生效,或`,(0,K.jsx)(`button`,{className:`underline underline-offset-2`,onClick:be,children:`放弃草稿`})]}),(0,K.jsxs)(`div`,{className:`grid min-h-0 flex-1 grid-cols-[1fr_380px] gap-4`,children:[(0,K.jsx)(`div`,{className:`flex min-h-0 flex-col`,children:(0,K.jsxs)(vO,{defaultValue:`canvas`,className:`flex min-h-0 flex-1 flex-col`,children:[(0,K.jsxs)(bO,{className:`shrink-0`,children:[(0,K.jsxs)(xO,{value:`canvas`,className:`text-xs`,children:[(0,K.jsx)(Yh,{className:`mr-1 h-3.5 w-3.5`}),`布局画布`]}),(0,K.jsx)(xO,{value:`json`,className:`text-xs`,children:`JSON`})]}),(0,K.jsxs)(SO,{value:`canvas`,className:`mt-2 flex min-h-0 flex-1 flex-col gap-2`,children:[(0,K.jsxs)(`div`,{className:`flex shrink-0 flex-nowrap items-center gap-1.5 overflow-x-auto rounded-md border bg-card p-2`,children:[(0,K.jsxs)(Y,{size:`sm`,variant:`secondary`,className:`h-7 shrink-0 text-xs`,onClick:pe,children:[(0,K.jsx)(dg,{className:`mr-1 h-3 w-3`}),`添加区块`]}),(0,K.jsx)(_O,{orientation:`vertical`,className:`mx-1 h-5 shrink-0`}),V?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`span`,{className:`max-w-28 shrink-0 truncate text-[11px] text-muted-foreground`,title:V.title,children:[`「`,V.title,`」`]}),(0,K.jsx)(`span`,{className:`shrink-0 text-[11px]`,children:`列`}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`左移一列`,onClick:()=>ue(_,{x:Math.max(1,(V.grid?.x||1)-1)}),children:(0,K.jsx)(qm,{className:`h-3 w-3`})}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`右移一列`,onClick:()=>ue(_,{x:Math.min(12,(V.grid?.x||1)+1)}),children:(0,K.jsx)(Ym,{className:`h-3 w-3`})}),(0,K.jsx)(`span`,{className:`shrink-0 text-[11px]`,children:`跨列`}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`跨列减一`,onClick:()=>ue(_,{w:Math.max(1,(V.grid?.w||6)-1)}),children:`−`}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`跨列加一`,onClick:()=>ue(_,{w:Math.min(12,(V.grid?.w||6)+1)}),children:`+`}),(0,K.jsx)(`span`,{className:`shrink-0 text-[11px]`,children:`跨行`}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`跨行减一`,onClick:()=>ue(_,{h:Math.max(1,(V.grid?.h||1)-1)}),children:(0,K.jsx)(Zm,{className:`h-3 w-3`})}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`跨行加一`,onClick:()=>ue(_,{h:Math.min(8,(V.grid?.h||1)+1)}),children:(0,K.jsx)(Gm,{className:`h-3 w-3`})}),(0,K.jsxs)(Y,{size:`sm`,variant:`ghost`,className:`h-7 shrink-0 text-xs text-primary`,onClick:()=>ve(_),children:[(0,K.jsx)(th,{className:`mr-1 h-3 w-3`}),`AI 定制`]}),(0,K.jsxs)(CO,{children:[(0,K.jsx)(wO,{asChild:!0,children:(0,K.jsxs)(Y,{size:`sm`,variant:`ghost`,className:`h-7 shrink-0 text-xs`,children:[(0,K.jsx)(Th,{className:`h-3 w-3`}),`更多`]})}),(0,K.jsxs)(TO,{align:`end`,children:[(V.type===`custom`||V.type===`custom_panel`)&&(0,K.jsxs)(EO,{className:`text-amber-400 focus:text-amber-300`,onClick:()=>he(_),children:[(0,K.jsx)(t_,{}),`AI 调试`]}),(0,K.jsxs)(EO,{onClick:()=>ue(_,{x:1,w:12}),children:[(0,K.jsx)(Ug,{className:`text-muted-foreground`}),`占满宽度`]}),(0,K.jsxs)(EO,{onClick:()=>{let e=B.reduce((e,t)=>Math.max(e,(t.grid?.y||1)+(t.grid?.h||1)-1),1);ue(_,{h:Math.max(1,e-(V.grid?.y||1)+1)})},children:[(0,K.jsx)(Gg,{className:`text-muted-foreground`}),`延到底部`]}),(0,K.jsxs)(EO,{onClick:()=>ue(_,{x:1}),children:[(0,K.jsx)(Um,{className:`text-muted-foreground`}),`贴左`]}),(0,K.jsxs)(EO,{onClick:()=>ue(_,{x:12-(V.grid?.w||6)+1}),children:[(0,K.jsx)(Vm,{className:`text-muted-foreground`}),`贴右`]}),(0,K.jsx)(DO,{}),(0,K.jsxs)(EO,{onClick:()=>{g(_),m(!0)},children:[(0,K.jsx)(pg,{className:`text-muted-foreground`}),`换插件`]}),(0,K.jsxs)(EO,{onClick:()=>{C(_),x(!0)},children:[(0,K.jsx)(Dg,{className:`text-muted-foreground`}),`面板设置`]}),(0,K.jsxs)(EO,{className:`text-red-400 focus:text-red-300`,onClick:()=>{H(e=>e.panels.splice(_,1)),y(null)},children:[(0,K.jsx)(qg,{}),`删除区块`]})]})]})]}):(0,K.jsx)(`span`,{className:`shrink-0 text-[11px] text-muted-foreground`,children:`点击画布中的区块进行编辑`})]}),(0,K.jsx)(`div`,{className:`shrink-0`,children:(0,K.jsx)(mO,{})}),(0,K.jsx)(`div`,{className:`relative min-h-0 flex-1 overflow-hidden rounded-lg border bg-muted/20 p-2`,children:(0,K.jsx)(pO,{className:`absolute inset-0 overflow-auto`,dsl:t,edit:{sel:_,onSelect:y,onGrid:(e,t)=>ue(e,t)},renderPanel:t=>{let n=fe(t);return n?(0,K.jsx)(dO,{code:n,data:de(t),meta:{agentId:e,panelId:t.id,pluginId:t.panel}}):(0,K.jsx)(`div`,{className:`p-3 text-[11px] text-muted-foreground`,children:`(插件代码加载中…)`})},renderDialog:()=>(0,K.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-1 text-[11px] text-muted-foreground`,children:[(0,K.jsx)(th,{className:`h-5 w-5 text-primary`}),`诊断对话(内核)`,(0,K.jsx)(`span`,{className:`text-[10px]`,children:`发布后在工作台可交互`})]}),renderPlaceholder:()=>(0,K.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-1 text-[11px] text-muted-foreground`,children:[(0,K.jsx)(dg,{className:`h-4 w-4`}),`空区块`,(0,K.jsx)(`span`,{className:`text-[10px]`,children:`选中后「换插件」或「AI 定制」`})]})})}),(0,K.jsx)(`p`,{className:`shrink-0 text-[10px] text-muted-foreground`,children:`所见即所得(比例一致):画布 = 缩小的可视区,行高为可视区等分——跨 n 行即占 n/总行数,与实际浏览时任何屏幕尺寸下的比例完全一致;内容超高时面板内部滚动。拖拽移动(吸附网格)· 手柄调跨列跨行 · 右上角显示占比。`})]}),(0,K.jsxs)(SO,{value:`json`,className:`mt-2 flex min-h-0 flex-1 flex-col gap-2`,children:[(0,K.jsx)(`textarea`,{value:s,onChange:e=>c(e.target.value),spellCheck:!1,className:`min-h-0 w-full flex-1 resize-none rounded-md border bg-muted p-3 font-mono text-[11px] leading-relaxed`}),(0,K.jsxs)(`div`,{className:`flex shrink-0 gap-2`,children:[(0,K.jsx)(Y,{size:`sm`,onClick:()=>{try{let e=JSON.parse(s);if(!e.panels)throw Error(`缺少 panels`);n(e),i(!0),Z.success(`JSON 已应用(未发布)`)}catch(e){Z.error(`JSON 解析失败: ${e.message}`)}},children:`应用 JSON`}),(0,K.jsx)(Y,{size:`sm`,variant:`outline`,onClick:()=>c(JSON.stringify(t,null,2)),children:`从画布刷新`})]})]})]})}),(0,K.jsxs)(`div`,{className:`flex min-h-0 flex-col gap-4`,children:[(0,K.jsx)(bm,{className:`flex min-h-0 flex-1 flex-col py-0`,children:(0,K.jsxs)(Cm,{className:`flex min-h-0 flex-1 flex-col p-0`,children:[(0,K.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1.5 border-b px-3 py-2 text-xs font-semibold`,children:[(0,K.jsx)(Lg,{className:`h-3.5 w-3.5 text-primary`}),`二开助手`,(0,K.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:`· 描述需求,直接定制区块`})]}),te!==null&&B[te]&&(()=>{let e=B[te],t=e.grid||{x:1,y:1,w:6,h:1},n=Math.round(t.w/12*100);return(0,K.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1.5 border-b bg-primary/5 px-3 py-1.5 text-[11px]`,children:[(0,K.jsx)(yh,{className:`h-3.5 w-3.5 shrink-0 text-primary`}),(0,K.jsxs)(`span`,{className:`min-w-0 truncate`,children:[`定制目标:`,(0,K.jsx)(`b`,{children:e.title}),` · `,n,`% 宽 · `,t.h,` 行`,e.panel?(0,K.jsxs)(K.Fragment,{children:[` · `,(0,K.jsx)(`span`,{className:`font-mono`,children:e.panel})]}):` · 空区块`]}),(0,K.jsx)(`button`,{className:`ml-auto shrink-0 rounded p-0.5 text-muted-foreground hover:text-foreground`,title:`取消目标,改为自由描述`,onClick:()=>z(null),children:`×`})]})})(),ne&&r&&(0,K.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1.5 border-b bg-emerald-500/10 px-3 py-1.5 text-[11px] text-emerald-400`,children:[(0,K.jsx)(ph,{className:`h-3.5 w-3.5 shrink-0`}),`草稿已生成——到顶部「审阅后发布」生效`]}),(0,K.jsx)(eO,{className:`min-h-0 flex-1`,children:(0,K.jsxs)(`div`,{className:`space-y-2.5 p-3`,ref:oe,children:[M.length===0&&(0,K.jsx)(`div`,{className:`space-y-2`,children:(0,K.jsxs)(`div`,{className:`rounded-md border border-dashed border-primary/30 bg-primary/5 p-3 text-[11px] leading-relaxed`,children:[(0,K.jsx)(`div`,{className:`mb-1 text-xs font-semibold text-primary`,children:`✨ 两种玩法`}),(0,K.jsxs)(`div`,{children:[`① 画布选中区块 → 工具条「`,(0,K.jsx)(`b`,{children:`AI 定制`}),`」→ 目标钉在上方,只管补需求`]}),(0,K.jsx)(`div`,{children:`② 直接描述需求,助手自动建区块进草稿`}),(0,K.jsx)(`div`,{className:`mt-1.5 flex flex-wrap gap-1.5`,children:[[`窄条:最近告警`,`新建一个窄条区块(跨3列):最近活动告警列表,高级别标红,点击可选中设备`],[`横条:KPI 摘要`,`新建一个单行横条区块:关键指标摘要读数(props.kpi),异常着色`],[`宽表:设备台账`,`新建一个宽区块(跨9列以上):设备台账表格,显示全部字段,支持点击选中`]].map(([e,t])=>(0,K.jsx)(`button`,{onClick:()=>F(t),className:`rounded-full border px-2.5 py-1 text-[11px] text-muted-foreground transition-colors hover:border-primary/60 hover:text-primary`,children:e},e))})]})}),M.map((e,t)=>(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`div`,{className:e.role===`user`?`ml-auto max-w-[90%] rounded-lg bg-primary/20 px-2.5 py-1.5 text-xs break-words whitespace-pre-wrap`:`max-w-full rounded-lg bg-card px-2.5 py-1.5 text-xs leading-relaxed break-words whitespace-pre-wrap`,children:e.text}),(e.events||[]).map((e,t)=>(0,K.jsxs)(`div`,{className:`mt-1 min-w-0 rounded-md border border-dashed px-2 py-1 text-[10px]`,children:[(0,K.jsx)(`span`,{children:e.ok===!1?`❌`:`🛠`}),` `,(0,K.jsx)(`span`,{className:`font-mono font-semibold`,children:e.tool}),(0,K.jsx)(`pre`,{className:`mt-0.5 max-h-32 overflow-auto whitespace-pre-wrap break-all text-muted-foreground`,children:String(e.result||``).slice(0,260)})]},t))]},t)),(I||R)&&(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 px-1 text-[11px] text-muted-foreground`,children:[(0,K.jsx)(`span`,{className:`h-1.5 w-1.5 animate-pulse rounded-full bg-primary`}),R||`开发中…`]})]})}),(0,K.jsxs)(`div`,{className:`shrink-0 space-y-1 border-t p-2`,children:[(0,K.jsx)(`textarea`,{value:P,onChange:e=>F(e.target.value),rows:2,onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&!e.nativeEvent.isComposing&&(e.preventDefault(),Se())},placeholder:te===null?`描述需求,如「左上窄条做一个最近工单列表」(Enter 发送)…`:`描述对「${B[te]?.title}」的需求(Enter 发送,Shift+Enter 换行)…`,className:`min-h-[56px] w-full resize-none rounded-md border bg-background px-2 py-1.5 text-xs`}),(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:te===null?`未锁定目标——助手会自动规划区块位置`:`目标上下文(位置/几何/插件)发送时自动携带`}),I?(0,K.jsxs)(Y,{size:`sm`,variant:`destructive`,className:`h-7 gap-1 text-xs`,onClick:U,children:[(0,K.jsx)(Vg,{className:`h-3 w-3`}),`停止`]}):(0,K.jsxs)(Y,{size:`sm`,className:`h-7 gap-1 text-xs`,disabled:!P.trim(),onClick:Se,children:[(0,K.jsx)(Cg,{className:`h-3 w-3`}),`发送`]})]})]})]})}),(0,K.jsx)(bm,{className:`shrink-0 py-0`,children:(0,K.jsxs)(Cm,{className:`p-0`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 border-b px-3 py-2 text-xs font-semibold`,children:[(0,K.jsx)(_g,{className:`h-3.5 w-3.5`}),`版本历史`]}),(0,K.jsx)(`div`,{className:`max-h-40 overflow-y-auto`,children:(0,K.jsxs)(`div`,{className:`divide-y`,children:[a.length===0&&(0,K.jsx)(`div`,{className:`p-3 text-center text-xs text-muted-foreground`,children:`暂无历史`}),[...a].reverse().map((e,t)=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-1.5 text-xs`,children:[(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsx)(`span`,{className:`font-mono font-semibold`,children:e.version}),t===0&&!r&&(0,K.jsx)(J,{className:`ml-1 h-4 px-1 text-[9px]`,children:`线上`}),(0,K.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,children:gt(e.at,`dts`)})]}),t!==0&&(0,K.jsx)(Y,{size:`sm`,variant:`ghost`,className:`h-6 text-[10px]`,onClick:()=>xe(e.version),children:`回滚`})]},`${e.version}-${e.at}`))]})})]})})]})]}),(0,K.jsx)(a_,{open:b,onOpenChange:x,children:(0,K.jsxs)(c_,{className:`max-w-md`,children:[(0,K.jsx)(l_,{children:(0,K.jsxs)(d_,{children:[`区块设置 · `,B[S]?.title]})}),(0,K.jsxs)(`div`,{className:`space-y-2`,children:[(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`标题`}),(0,K.jsx)(p_,{defaultValue:B[S]?.title||``,className:`text-xs`,onBlur:e=>H(t=>{t.panels[S].title=e.target.value})})]}),B[S]?.type===`custom`&&(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`内联代码(契约:function Panel(props))`}),(0,K.jsx)(`textarea`,{defaultValue:B[S]?.code||``,spellCheck:!1,onBlur:e=>H(t=>{t.panels[S].code=e.target.value}),className:`h-40 w-full rounded-md border bg-muted p-2 font-mono text-[10px]`})]}),B[S]?.type===`custom_panel`&&(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`插件版本(可回退,回退即时生效)`}),(0,K.jsx)(MO,{pluginId:String(B[S]?.panel||``),onRollback:ge})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`params(插件经 props.params 读取)`}),(0,K.jsx)(`textarea`,{defaultValue:JSON.stringify(B[S]?.params||{},null,1),spellCheck:!1,onBlur:e=>{try{H(t=>{t.panels[S].params=JSON.parse(e.target.value||`{}`)})}catch{Z.error(`params JSON 无效`)}},className:`h-20 w-full rounded-md border bg-muted p-2 font-mono text-[10px]`})]})]}),(0,K.jsx)(u_,{children:(0,K.jsx)(Y,{onClick:()=>x(!1),children:`完成`})})]})}),(0,K.jsx)(a_,{open:p,onOpenChange:e=>{m(e),e||g(null)},children:(0,K.jsxs)(c_,{children:[(0,K.jsx)(l_,{children:(0,K.jsxs)(d_,{className:`flex items-center gap-1.5`,children:[(0,K.jsx)(pg,{className:`h-4 w-4`}),`插件库`,h===null?``:` · 插入到选中区块`]})}),(0,K.jsx)(`div`,{className:`max-h-72 overflow-y-auto`,children:(0,K.jsx)(`div`,{className:`space-y-1.5`,children:d.filter(e=>e.status!==`deprecated`).map(e=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border p-2.5`,children:[(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5 text-xs font-medium`,children:[(0,K.jsx)(`span`,{className:`min-w-0 truncate`,title:e.name,children:e.name}),(0,K.jsx)(J,{variant:`secondary`,className:`h-4 shrink-0 px-1 text-[9px]`,children:e.version}),(0,K.jsx)(J,{variant:`outline`,className:`h-4 shrink-0 px-1 text-[9px]`,children:e.author===`system`?`范本`:e.author===`ai`?`AI`:`人工`})]}),(0,K.jsx)(`div`,{className:`truncate text-[10px] text-muted-foreground`,children:e.description||e.id})]}),(0,K.jsx)(Y,{size:`sm`,variant:`secondary`,className:`h-7 shrink-0 text-[11px]`,onClick:()=>me(h,e),children:`插入`})]},e.id))})}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,size:`sm`,onClick:pe,children:`先加空区块`}),(0,K.jsx)(Y,{variant:`outline`,onClick:()=>m(!1),children:`关闭`})]})]})}),(0,K.jsx)(kO,{target:ie,onClose:()=>ae(null),agents:[{agent_id:e,name:t.workbench||`当前助手`}]}),(0,K.jsx)(`p`,{className:`shrink-0 text-center text-[11px] text-muted-foreground`,children:`区块几何 = 插件设计输入:宽≤3 列紧凑列表、≥9 列表格/仪表 · AI 定制锁定目标、上下文自动携带 · 草稿审阅发布。`})]})}var FO=[{key:`tool_calls`,label:`工具调用`,icon:(0,K.jsx)(t_,{className:`h-3.5 w-3.5`}),tone:`text-sky-400`},{key:`guardrail_blocks`,label:`守护栏拦截`,icon:(0,K.jsx)(jg,{className:`h-3.5 w-3.5`}),tone:`text-red-400`},{key:`human_confirms`,label:`人工确认执行`,icon:(0,K.jsx)(zm,{className:`h-3.5 w-3.5`}),tone:`text-amber-400`},{key:`orchestrations`,label:`编排执行`,icon:(0,K.jsx)(Lg,{className:`h-3.5 w-3.5`}),tone:`text-violet-400`},{key:`experiences`,label:`经验回流`,icon:(0,K.jsx)($m,{className:`h-3.5 w-3.5`}),tone:`text-emerald-400`},{key:`kb_searches`,label:`知识检索`,icon:(0,K.jsx)(xg,{className:`h-3.5 w-3.5`}),tone:`text-cyan-400`},{key:`ai_drafts`,label:`AI 起草`,icon:(0,K.jsx)(Yg,{className:`h-3.5 w-3.5`}),tone:`text-pink-400`}];function IO(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(``),[i,a]=(0,v.useState)(null),[o,s]=(0,v.useState)(!1),c=()=>ot(`/api/evolution`).then(t);(0,v.useEffect)(()=>{c();let e=setInterval(c,1e4);return()=>clearInterval(e)},[]);let l=async()=>{if(n.trim()){s(!0);try{let e=await ot(`/api/kb/search?q=${encodeURIComponent(n)}`);a(e.items),c()}finally{s(!1)}}};return e?(0,K.jsxs)(`div`,{className:`h-full overflow-auto p-5`,children:[(0,K.jsxs)(`div`,{className:`mb-4`,children:[(0,K.jsxs)(`h1`,{className:`flex items-center gap-2 text-lg font-bold`,children:[(0,K.jsx)(Yg,{className:`h-5 w-5 text-primary`}),`自进化看板`]}),(0,K.jsxs)(`p`,{className:`mt-0.5 text-xs text-muted-foreground`,children:[e.flywheel_note,` · 数据来自审计日志与指标流的实时聚合`]})]}),(0,K.jsx)(`div`,{className:`grid grid-cols-4 gap-3 xl:grid-cols-7`,children:FO.map(t=>(0,K.jsx)(bm,{className:`py-3`,children:(0,K.jsxs)(Cm,{className:`px-3`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[11px] text-muted-foreground`,children:[t.icon,t.label]}),(0,K.jsx)(`div`,{className:`mt-1 text-xl font-bold ${t.tone}`,children:e.totals[t.key]??0})]})},t.key))}),(0,K.jsxs)(`div`,{className:`mt-4 grid grid-cols-2 gap-4`,children:[(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsx)(Sm,{className:`text-xs text-muted-foreground`,children:`飞轮证据 · 检索相似度趋势(回流前后对比)`})}),(0,K.jsx)(Cm,{className:`p-0`,children:(0,K.jsx)(eO,{className:`h-64`,children:(0,K.jsxs)(`div`,{className:`space-y-1.5 p-3`,children:[e.similarity_trend.length===0&&(0,K.jsx)(`div`,{className:`py-8 text-center text-xs text-muted-foreground`,children:`尚无检索记录`}),e.similarity_trend.map((e,t)=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 text-xs`,children:[(0,K.jsx)(`span`,{className:`w-40 shrink-0 truncate text-muted-foreground`,title:e.query,children:e.query}),(0,K.jsx)(`div`,{className:`h-2 flex-1 overflow-hidden rounded bg-muted`,children:(0,K.jsx)(`div`,{className:`h-full rounded ${e.similarity>=75?`bg-emerald-500`:e.similarity>=55?`bg-amber-500`:`bg-slate-500`}`,style:{width:`${e.similarity}%`}})}),(0,K.jsxs)(`span`,{className:`w-9 text-right font-mono ${e.similarity>=75?`text-emerald-400`:`text-muted-foreground`}`,children:[e.similarity,`%`]})]},t))]})})})]}),(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsxs)(Sm,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,K.jsx)($m,{className:`h-3.5 w-3.5`}),`经验沉淀(写入 ARM 知识库)`]})}),(0,K.jsx)(Cm,{className:`p-0`,children:(0,K.jsx)(eO,{className:`h-64`,children:(0,K.jsxs)(`div`,{className:`divide-y`,children:[e.experiences.length===0&&(0,K.jsx)(`div`,{className:`p-8 text-center text-xs text-muted-foreground`,children:`尚无回流记录`}),e.experiences.map((e,t)=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-2 text-xs`,children:[(0,K.jsx)(kh,{className:`h-3 w-3 shrink-0 text-emerald-400`}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,title:e.title,children:e.title}),(0,K.jsx)(`span`,{className:`shrink-0 font-mono text-[10px] text-muted-foreground`,children:e.knowledge_id?e.knowledge_id.slice(0,8):`—`}),(0,K.jsx)(`span`,{className:`shrink-0 text-[10px] text-muted-foreground`,children:gt(e.ts)})]},t))]})})})]})]}),(0,K.jsxs)(`div`,{className:`mt-4 grid grid-cols-3 gap-4`,children:[(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsx)(Sm,{className:`text-xs text-muted-foreground`,children:`工具调用分布`})}),(0,K.jsxs)(Cm,{className:`p-3`,children:[Object.keys(e.by_tool).length===0&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:`暂无数据`}),Object.entries(e.by_tool).sort((e,t)=>t[1]-e[1]).map(([t,n])=>{let r=Math.max(...Object.values(e.by_tool));return(0,K.jsxs)(`div`,{className:`mb-1.5 flex items-center gap-2 text-xs`,children:[(0,K.jsx)(`span`,{className:`w-36 shrink-0 truncate font-mono`,children:t}),(0,K.jsx)(`div`,{className:`h-2 flex-1 overflow-hidden rounded bg-muted`,children:(0,K.jsx)(`div`,{className:`h-full rounded bg-sky-500`,style:{width:`${n/r*100}%`}})}),(0,K.jsx)(`span`,{className:`w-6 text-right font-mono`,children:n})]},t)})]})]}),(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsxs)(Sm,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,K.jsx)(xh,{className:`h-3.5 w-3.5`}),`ARM 知识库实检(真实 RAG)`]})}),(0,K.jsxs)(Cm,{className:`p-3`,children:[(0,K.jsxs)(`div`,{className:`flex gap-2`,children:[(0,K.jsx)(p_,{value:n,onChange:e=>r(e.target.value),onKeyDown:e=>e.key===`Enter`&&l(),placeholder:`如:堆垛机 货叉定位偏移`,className:`text-xs`}),(0,K.jsx)(Y,{size:`sm`,disabled:o,onClick:l,children:o?`检索中`:`检索`})]}),(0,K.jsx)(eO,{className:`mt-2 h-44`,children:(0,K.jsxs)(`div`,{className:`space-y-1.5`,children:[!i&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:`输入问题检索企业经验库(与助手使用同一数据源)`}),i?.length===0&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:`无命中`}),i?.map((e,t)=>(0,K.jsxs)(`div`,{className:`rounded-md bg-card px-2.5 py-1.5`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs`,children:[e.similarity!=null&&(0,K.jsxs)(J,{variant:`secondary`,className:`h-4 text-[9px] ${e.similarity>=75?`text-emerald-400`:``}`,children:[e.similarity,`%`]}),(0,K.jsx)(`span`,{className:`truncate font-medium`,children:e.title})]}),(0,K.jsx)(`p`,{className:`mt-0.5 line-clamp-2 text-[10px] leading-relaxed text-muted-foreground`,children:e.snippet})]},t))]})})]})]}),(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsx)(Sm,{className:`text-xs text-muted-foreground`,children:`审计流(实时)`})}),(0,K.jsx)(Cm,{className:`p-0`,children:(0,K.jsx)(eO,{className:`h-52`,children:(0,K.jsx)(`div`,{className:`divide-y font-mono text-[10px]`,children:e.recent_audit.map((e,t)=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-1.5`,children:[(0,K.jsx)(`span`,{className:`text-muted-foreground`,children:gt(e.ts,`t`)}),(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.actor}),(0,K.jsx)(`span`,{className:`truncate`,children:e.tool||e.logic||e.action||e.name||e.verdict||``})]},t))})})})]})]})]}):(0,K.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:`进化数据加载中…`})}function LO({className:e,size:t=`default`,...n}){return(0,K.jsx)(qp,{"data-slot":`switch`,"data-size":t,className:mn(`peer group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80`,e),...n,children:(0,K.jsx)(Yp,{"data-slot":`switch-thumb`,className:mn(`pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0 dark:data-[state=checked]:bg-primary-foreground dark:data-[state=unchecked]:bg-foreground`)})})}function RO(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(``),[o,s]=(0,v.useState)(``),[c,l]=(0,v.useState)(``),[u,d]=(0,v.useState)(!1),[f,p]=(0,v.useState)(null),[m,h]=(0,v.useState)(``),[g,_]=(0,v.useState)(``),[y,b]=(0,v.useState)(``),[x,S]=(0,v.useState)(!1),[C,w]=(0,v.useState)(null),[T,E]=(0,v.useState)(``),[D,O]=(0,v.useState)(!1),[k,A]=(0,v.useState)(``),[j,M]=(0,v.useState)(!1),[N,P]=(0,v.useState)([]),[F,I]=(0,v.useState)([]),[L,R]=(0,v.useState)(!1),[ee,te]=(0,v.useState)(``),[z,ne]=(0,v.useState)(``),[re,ie]=(0,v.useState)(!1),[ae,oe]=(0,v.useState)(null),se=()=>{ot(`/api/settings`).then(e=>{t(e),a(e.arm.api_base),s(e.arm.mcp_explicit?e.arm.mcp_url:``),h(e.llm.model),_(e.llm.base_url_runtime?e.llm.base_url:``),E(e.scene.profile),P(e.guard.deny),I(e.guard.ro),R(e.guard.sudo_u_l2)}),ot(`/api/arm/status`).then(r).catch(()=>r(null))};(0,v.useEffect)(()=>{se()},[]);let ce=async()=>{d(!0),p(null);try{let e=await ct(`/api/settings`,{arm_api_base:i.trim(),arm_mcp_url:o.trim(),...c.trim()?{arm_token:c.trim()}:{}});p(e.probe||null),l(``),e.probe?.online?Z.success(`已保存并连通(${e.probe.latency_ms}ms),源切换即时生效`):Z.warning(`已保存,但当前源不可达`,{description:e.note}),se()}catch(e){Z.error(String(e.message))}finally{d(!1)}},le=async()=>{S(!0),w(null);try{let e=await ct(`/api/settings`,{llm_model:m.trim(),llm_base_url:g.trim(),...y.trim()?{llm_api_key:y.trim()}:{}});b(``),w(e.llm_probe||null),e.llm_probe?.online?Z.success(`模型已切换(探针 ${e.llm_probe.latency_ms}ms:${e.llm_probe.reply||`ok`})`):e.note&&Z.warning(`已保存,但探针未通过`,{description:e.note}),se()}catch(e){Z.error(String(e.message))}finally{S(!1)}},B=async()=>{M(!0);try{if(await ct(`/api/settings`,{access_token:k}),k.trim()){if(!(await fetch(`/api/auth/login`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({token:k.trim()})})).ok)throw Error(`已保存但自动登录失败,刷新后输入令牌进入`);Z.success(`访问令牌已启用(当前浏览器已自动登录)`)}else Z.success(`访问令牌已关闭(恢复开放访问)`);A(``),se()}catch(e){Z.error(String(e.message))}finally{M(!1)}},V=async()=>{O(!0);try{await ct(`/api/settings`,{scene_profile:T}),Z.success(T.trim()?`场景画像已保存,对全部助手即时生效(新对话起)`:`场景画像已清空(不再注入)`),se()}catch(e){Z.error(String(e.message))}finally{O(!1)}},H=async()=>{ie(!0);try{await ct(`/api/settings`,{guard:{deny:N,ro:F,sudo_u_l2:L}}),Z.success(`守护栏已更新(危险规则 ${N.length} 条 · 白名单 ${F.length} 命令),即时生效`),oe(null),se()}catch(e){Z.error(String(e.message))}finally{ie(!1)}};return(0,K.jsxs)(`div`,{className:`h-full overflow-auto p-5`,children:[(0,K.jsxs)(`div`,{className:`mb-4`,children:[(0,K.jsxs)(`h1`,{className:`flex items-center gap-2 text-lg font-bold`,children:[(0,K.jsx)(kg,{className:`h-5 w-5 text-primary`}),`系统设置`]}),(0,K.jsx)(`p`,{className:`mt-0.5 text-xs text-muted-foreground`,children:`平台全局配置 · 修改保存后即时生效(无需重启)· 运行时配置优先于 .env`})]}),(0,K.jsxs)(vO,{defaultValue:`arm`,className:`max-w-2xl`,children:[(0,K.jsxs)(bO,{children:[(0,K.jsxs)(xO,{value:`arm`,className:`text-xs`,children:[(0,K.jsx)(Tg,{className:`mr-1 h-3.5 w-3.5`}),`ARM 源`,n&&(0,K.jsx)(`span`,{className:`ml-1 h-1.5 w-1.5 rounded-full ${n.online?`bg-emerald-500`:`bg-amber-500`}`})]}),(0,K.jsxs)(xO,{value:`llm`,className:`text-xs`,children:[(0,K.jsx)(th,{className:`mr-1 h-3.5 w-3.5`}),`LLM 模型服务`]}),(0,K.jsxs)(xO,{value:`scene`,className:`text-xs`,children:[(0,K.jsx)(Lh,{className:`mr-1 h-3.5 w-3.5`}),`场景画像`,e&&e.scene.length>0&&(0,K.jsx)(`span`,{className:`ml-1 h-1.5 w-1.5 rounded-full bg-emerald-500`})]}),(0,K.jsxs)(xO,{value:`auth`,className:`text-xs`,children:[(0,K.jsx)(tg,{className:`mr-1 h-3.5 w-3.5`}),`访问安全`,e?.auth.enabled&&(0,K.jsx)(`span`,{className:`ml-1 h-1.5 w-1.5 rounded-full bg-emerald-500`})]}),(0,K.jsxs)(xO,{value:`guard`,className:`text-xs`,children:[(0,K.jsx)(Fg,{className:`mr-1 h-3.5 w-3.5`}),`守护栏`,(0,K.jsxs)(`span`,{className:`ml-1 text-[9px] text-muted-foreground`,children:[N.length,`规`]})]})]}),(0,K.jsx)(SO,{value:`arm`,className:`mt-3`,children:(0,K.jsxs)(bm,{className:`mb-3 max-w-2xl`,children:[(0,K.jsxs)(xm,{className:`pb-2`,children:[(0,K.jsxs)(Sm,{className:`flex items-center gap-2 text-sm`,children:[(0,K.jsx)(Tg,{className:`h-4 w-4 text-primary`}),`ARM 源`,n&&(0,K.jsx)(J,{variant:`outline`,className:`text-[10px] ${n.online?`text-emerald-400`:`text-amber-400`}`,children:n.online?`在线 · ${n.latency_ms}ms`:`不可达(回落 MCP/本地库)`})]}),(0,K.jsx)(`p`,{className:`text-[11px] leading-relaxed text-muted-foreground`,children:`ARM 是可私有化部署的资源管理系统(助手档案 + 知识库):在此切换源(如 本地开发版 → 客户私有站点), 检索/下载/同步全部即时跟随;助手已下载的本地档案不受影响。`})]}),(0,K.jsxs)(Cm,{className:`space-y-3`,children:[e&&!e.arm.token_set&&e.arm.token_source===`none`&&(0,K.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 p-2.5 text-[11px] leading-relaxed text-amber-300`,children:[(0,K.jsx)(`span`,{className:`shrink-0`,children:`🔑`}),(0,K.jsxs)(`div`,{className:`flex-1`,children:[`尚未配置访问令牌——匿名仅能浏览目录,`,(0,K.jsx)(`b`,{children:`下载 / 上岗 / 新建 / 经验回流`}),`等操作会被 ARM 拒绝(401/403)。 请登录 ARM 站点生成访问令牌(arm_pat_… 开头),粘贴到下方「访问令牌」并保存。`,(0,K.jsx)(`a`,{href:e.arm.api_base,target:`_blank`,rel:`noreferrer`,className:`ml-1 underline underline-offset-2 hover:text-amber-200`,children:`打开 ARM 生成令牌 →`})]})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`flex items-center gap-2 text-xs`,children:[`站点地址(REST API 根地址)`,e&&(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.arm.api_base_runtime?`运行时配置`:`默认(${(e.arm.default_base||``).replace(/^https?:\/\//,``)})`})]}),(0,K.jsx)(p_,{value:i,onChange:e=>a(e.target.value),placeholder:`如 http://localhost:3001 或 https://arm.customer.com`,className:`font-mono text-xs`})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`MCP 端点(高级,留空自动 = 站点地址 + /api/mcp)`}),(0,K.jsx)(p_,{value:o,onChange:e=>s(e.target.value),placeholder:e?.arm.mcp_url||`/api/mcp`,className:`font-mono text-xs`})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`flex items-center gap-2 text-xs`,children:[`访问令牌(Token)`,e&&(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.arm.token_set?`${e.arm.token_masked} · ${e.arm.token_source}`:`未配置(${e.arm.token_source===`pat`?`回落 ~/.arm PAT`:`匿名/只读`})`})]}),(0,K.jsx)(p_,{type:`password`,value:c,onChange:e=>l(e.target.value),placeholder:e?.arm.token_set?`已配置(留空保持不变)`:`arm_pat_…`,className:`font-mono text-xs`})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(Y,{size:`sm`,className:`text-xs`,disabled:u,onClick:ce,children:u?`保存中…`:`保存并测试连接`}),f&&(0,K.jsx)(`span`,{className:`flex items-center gap-1 text-[11px] ${f.online?`text-emerald-400`:`text-amber-400`}`,children:f.online?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(ph,{className:`h-3.5 w-3.5`}),`连通 `,f.latency_ms,`ms,源已切换`]}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(hh,{className:`h-3.5 w-3.5`}),`不可达:`,f.error]})})]})]})]})}),(0,K.jsx)(SO,{value:`llm`,className:`mt-3`,children:(0,K.jsxs)(bm,{className:`mb-3 max-w-2xl`,children:[(0,K.jsxs)(xm,{className:`pb-2`,children:[(0,K.jsxs)(Sm,{className:`flex items-center gap-2 text-sm`,children:[(0,K.jsx)(th,{className:`h-4 w-4 text-primary`}),`LLM 模型服务`,e&&(0,K.jsx)(J,{variant:`outline`,className:`text-[10px]`,children:e.llm.model})]}),(0,K.jsx)(`p`,{className:`text-[11px] leading-relaxed text-muted-foreground`,children:`OpenAI 兼容端点:缺省公司内网 bifrost 网关(内网开箱可用),可切换模型 / 自建网关 / 公有云端点。保存后新对话即时使用新模型,应用失败自动回滚。`})]}),(0,K.jsxs)(Cm,{className:`space-y-3`,children:[(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`flex items-center gap-2 text-xs`,children:[`模型`,e&&(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.llm.model_runtime?`运行时配置`:`默认(.env)`})]}),(0,K.jsx)(p_,{value:m,onChange:e=>h(e.target.value),list:`llm-catalog`,placeholder:`如 def / glm-5.3 / 自定义名称`,className:`font-mono text-xs`}),(0,K.jsx)(`datalist`,{id:`llm-catalog`,children:(e?.llm.catalog||[]).map(e=>(0,K.jsx)(`option`,{value:e},e))})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`text-xs`,children:[`端点地址(留空 = `,e?.llm.default_base||`默认内网 bifrost`,`)`]}),(0,K.jsx)(p_,{value:g,onChange:e=>_(e.target.value),placeholder:`https://your-gateway/v1(OpenAI 兼容)`,className:`font-mono text-xs`})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`flex items-center gap-2 text-xs`,children:[`API Key`,e&&(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.llm.key_set?`${e.llm.key_masked} · ${e.llm.key_source}`:`未配置`})]}),(0,K.jsx)(p_,{type:`password`,value:y,onChange:e=>b(e.target.value),placeholder:e?.llm.key_set?`已配置(留空保持不变)`:`sk-… / api key`,className:`font-mono text-xs`})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(Y,{size:`sm`,className:`text-xs`,disabled:x,onClick:le,children:x?`切换中…`:`保存并测试模型`}),C&&(0,K.jsx)(`span`,{className:`flex items-center gap-1 text-[11px] ${C.online?`text-emerald-400`:`text-amber-400`}`,children:C.online?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(ph,{className:`h-3.5 w-3.5`}),`探针通过 `,C.latency_ms,`ms:`,C.reply]}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(hh,{className:`h-3.5 w-3.5`}),`未通过:`,C.error]})})]})]})]})}),(0,K.jsx)(SO,{value:`scene`,className:`mt-3`,children:(0,K.jsxs)(bm,{className:`mb-3 max-w-2xl`,children:[(0,K.jsxs)(xm,{className:`pb-2`,children:[(0,K.jsxs)(Sm,{className:`flex items-center gap-2 text-sm`,children:[(0,K.jsx)(Lh,{className:`h-4 w-4 text-primary`}),`场景画像`,e&&(0,K.jsx)(J,{variant:`outline`,className:`text-[10px] ${e.scene.length?`text-emerald-400`:``}`,children:e.scene.length?`已启用 · ${e.scene.length} 字`:`未配置(不注入)`})]}),(0,K.jsxs)(`p`,{className:`text-[11px] leading-relaxed text-muted-foreground`,children:[`平台级、全局一份的使用方场景描述(团队环境 / 系统清单 / 规范 / 联系人),作为常驻事实注入`,(0,K.jsx)(`b`,{children:`所有助手`}),`的上下文—— 助手不必每次重新探索环境。与知识检索互补(常驻事实 vs 按需检索)。⚠ 不放凭据:写"凭据在哪、找谁要"即可。`]})]}),(0,K.jsxs)(Cm,{className:`space-y-2`,children:[(0,K.jsx)(`textarea`,{value:T,onChange:e=>E(e.target.value),spellCheck:!1,rows:8,placeholder:`例如:
99
+ (已中断)`}]:[...e,{kind:`bot`,text:`(已中断)`}]})):t===`error`&&(Z.error(String(e.message)),h(``))},F=async()=>{let e=c.trim();e&&!u&&(l(``),await I(e))},I=async a=>{if(u)return;d(!0),O.current=!0,A({kind:`user`,text:a});let o=new AbortController;j.current=o;try{await ut(`/api/chat`,{sessionId:t,agentId:e,message:a,autonomyLevel:i,ws_id:n,context:r?{device:r}:null},P,o.signal)}catch(e){o.signal.aborted||Z.error(String(e.message))}finally{d(!1),j.current===o&&(j.current=null)}},L=async e=>{if(!f)return;p(null),d(!0),O.current=!0,s(e=>e.filter(e=>e.kind!==`pending`));let n=new AbortController;j.current=n;try{await ut(`/api/chat/confirm`,{sessionId:t,approved:e},P,n.signal)}catch(e){n.signal.aborted||Z.error(String(e.message))}finally{d(!1),j.current===n&&(j.current=null)}};return(0,K.jsxs)(`div`,{className:`flex h-full flex-col`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2 border-b px-3 py-1`,children:[(0,K.jsx)(th,{className:`h-3.5 w-3.5 text-primary`}),(0,K.jsx)(`span`,{className:`text-xs font-medium`,children:`诊断对话`}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:r?`上下文:${r}(点选设备自动注入)`:`点击左侧设备可注入上下文`}),(0,K.jsxs)(`div`,{className:`ml-auto flex items-center gap-1.5`,children:[(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`自主级别`}),(0,K.jsxs)(h_,{value:String(i),onValueChange:e=>a(+e),children:[(0,K.jsx)(__,{className:`h-7 w-[118px] text-xs`,children:(0,K.jsx)(g_,{})}),(0,K.jsxs)(v_,{children:[(0,K.jsx)(y_,{value:`0`,className:`text-xs`,children:`L0 只读问答`}),(0,K.jsx)(y_,{value:`1`,className:`text-xs`,children:`L1 诊断建议`}),(0,K.jsx)(y_,{value:`2`,className:`text-xs`,children:`L2 确认执行`}),(0,K.jsx)(y_,{value:`3`,className:`text-xs text-red-400`,children:`L3 完全自主(免确认)`})]})]})]})]}),(0,K.jsx)(eO,{className:`min-h-0 flex-1 [&>div>div]:block!`,children:(0,K.jsxs)(`div`,{className:`space-y-2.5 p-3`,ref:C,children:[o.length===0&&(0,K.jsxs)(`div`,{className:`flex h-40 flex-col items-center justify-center gap-1 text-xs text-muted-foreground`,children:[(0,K.jsx)(Vh,{className:`h-5 w-5 opacity-50`}),`试试:「STK-R3 什么情况?帮我处理」 / 「服务器 CPU 高,怎么处理」`]}),o.map((e,t)=>{if(e.kind===`user`)return(0,K.jsx)(`div`,{className:`ml-auto max-w-[85%] rounded-lg bg-primary/20 px-3 py-1.5 text-xs leading-relaxed break-words`,children:e.text},t);if(e.kind===`bot`)return(0,K.jsx)(`div`,{className:`max-w-[92%] rounded-lg bg-card px-3 py-2 text-xs leading-relaxed break-words`,children:(e.text||``).split(/```a2ui\s*\n?([\s\S]*?)```/g).map((e,t)=>t%2==0?e.trim()?(0,K.jsx)($D,{text:e},t):null:(0,K.jsx)(av,{raw:e,onSend:I},t))},t);if(e.kind===`evt`&&e.evt){let n=e.evt.status,r={ok:`✅`,executed:`▶`,blocked:`⛔`,cancelled:`🚫`,rejected:`❌`,start:`⏳`}[n]||`•`;return(0,K.jsxs)(`div`,{className:it(`max-w-[92%] rounded-md border border-dashed px-2.5 py-1.5 text-[11px]`,n===`blocked`?`border-red-500/50 text-red-300`:n===`start`?`border-border text-muted-foreground`:`border-border`),children:[(0,K.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5`,children:[(0,K.jsx)(`span`,{className:`shrink-0`,children:r}),(0,K.jsx)(t_,{className:`h-3 w-3 shrink-0`}),(0,K.jsx)(`span`,{className:`shrink-0 font-mono font-semibold`,children:e.evt.tool}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground`,children:JSON.stringify(e.evt.args)})]}),n!==`start`&&(0,K.jsx)(`pre`,{className:`mt-1 max-h-40 overflow-auto whitespace-pre-wrap break-all text-[10px] leading-relaxed text-muted-foreground`,children:String(e.evt.result).slice(0,700)})]},t)}return e.kind===`pending`?(0,K.jsx)(bm,{className:`max-w-[92%] border-amber-500/50 bg-amber-500/5`,children:(0,K.jsxs)(Cm,{className:`space-y-2 p-3`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs font-semibold text-amber-300`,children:[(0,K.jsx)(jg,{className:`h-3.5 w-3.5`}),`人工确认(L2)· 助手请求执行写操作`]}),e.intro&&(0,K.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:(0,K.jsx)($D,{text:e.intro})}),(0,K.jsxs)(`div`,{className:`flex gap-2`,children:[(0,K.jsx)(Y,{size:`sm`,variant:`destructive`,onClick:()=>L(!1),children:`取消`}),(0,K.jsx)(Y,{size:`sm`,onClick:()=>L(!0),children:`确认执行`})]})]})},t):null}),m&&(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 px-1 text-[11px] text-muted-foreground`,children:[(0,K.jsx)(`span`,{className:`h-1.5 w-1.5 animate-pulse rounded-full bg-primary`}),m,m.startsWith(`后台进行中`)&&(0,K.jsx)(Y,{size:`sm`,variant:`ghost`,className:`h-5 gap-1 px-1.5 text-[10px] text-red-400 hover:text-red-300`,onClick:()=>{h(``),M()},children:`⏹ 中断`}),(0,K.jsx)(`span`,{ref:w})]})]})}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2 border-t p-2`,children:[(0,K.jsx)(nO,{value:c,onChange:e=>l(e.target.value),rows:1,placeholder:`描述问题…(Enter 发送,Shift+Enter 换行)`,className:`min-h-[38px] resize-none text-xs`,onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),F())}}),u?(0,K.jsx)(Y,{size:`icon`,variant:`destructive`,title:`中断当前对话`,onClick:M,children:(0,K.jsx)(Vg,{className:`h-3.5 w-3.5`})}):(0,K.jsx)(Y,{size:`icon`,disabled:!c.trim(),onClick:F,children:(0,K.jsx)(Cg,{className:`h-3.5 w-3.5`})}),(0,K.jsx)(Y,{size:`icon`,variant:`outline`,title:`清空会话(丢弃服务端上下文,从零开始)`,disabled:u,onClick:N,children:(0,K.jsx)(qg,{className:`h-3.5 w-3.5`})}),(0,K.jsx)(Y,{size:`sm`,variant:`outline`,className:`shrink-0 text-[11px]`,onClick:async()=>{try{let e=await st(`/api/experience/draft`,{sessionId:t});S(e.markdown),b(``),_(!0)}catch(e){Z.error(String(e.message))}},children:`📥 沉淀经验`})]}),(0,K.jsx)(a_,{open:g,onOpenChange:_,children:(0,K.jsxs)(c_,{className:`max-w-xl`,children:[(0,K.jsx)(l_,{children:(0,K.jsx)(d_,{children:`经验回流 · AI 起草 → 人工审阅 → 写入 ARM`})}),(0,K.jsx)(p_,{value:y,onChange:e=>b(e.target.value),placeholder:`经验标题(留空自动生成)`,className:`text-xs`}),(0,K.jsx)(nO,{value:x,onChange:e=>S(e.target.value),className:`min-h-[260px] font-mono text-[11px]`}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,onClick:()=>_(!1),children:`取消`}),(0,K.jsx)(Y,{onClick:async()=>{try{let t=await st(`/api/experience/commit`,{agentId:e,name:y.trim()||`MVP经验-${gt(new Date().toISOString())}`,description:`工作台人工审阅沉淀`,content:x});_(!1),Z.success(`已回流 ARM 知识库`,{description:t.result.slice(0,90)})}catch(e){Z.error(String(e.message))}},children:`确认沉淀到 ARM 知识库`})]})]})})]})}var iO=function(e,t,n,r){var i;t[0]=0;for(var a=1;a<t.length;a++){var o=t[a++],s=t[a]?(t[0]|=o?1:2,n[t[a++]]):t[++a];o===3?r[0]=s:o===4?r[1]=Object.assign(r[1]||{},s):o===5?(r[1]=r[1]||{})[t[++a]]=s:o===6?r[1][t[++a]]+=s+``:o?(i=e.apply(s,iO(e,s,n,[``,null])),r.push(i),s[0]?t[0]|=2:(t[a-2]=0,t[a]=i)):r.push(s)}return r},aO=new Map;function oO(e){var t=aO.get(this);return t||(t=new Map,aO.set(this,t)),(t=iO(this,t.get(e)||(t.set(e,t=function(e){for(var t,n,r=1,i=``,a=``,o=[0],s=function(e){r===1&&(e||(i=i.replace(/^\s*\n\s*|\s*\n\s*$/g,``)))?o.push(0,e,i):r===3&&(e||i)?(o.push(3,e,i),r=2):r===2&&i===`...`&&e?o.push(4,e,0):r===2&&i&&!e?o.push(5,0,!0,i):r>=5&&((i||!e&&r===5)&&(o.push(r,0,i,n),r=6),e&&(o.push(r,e,0,n),r=6)),i=``},c=0;c<e.length;c++){c&&(r===1&&s(),s(c));for(var l=0;l<e[c].length;l++)t=e[c][l],r===1?t===`<`?(s(),o=[o],r=3):i+=t:r===4?i===`--`&&t===`>`?(r=1,i=``):i=t+i[0]:a?t===a?a=``:i+=t:t===`"`||t===`'`?a=t:t===`>`?(s(),r=1):r&&(t===`=`?(r=5,n=i,i=``):t===`/`&&(r<5||e[c][l+1]===`>`)?(s(),r===3&&(o=o[0]),r=o,(o=o[0]).push(2,0,r),r=0):t===` `||t===` `||t===`
100
+ `||t===`\r`?(s(),r=2):i+=t),r===3&&i===`!--`&&(r=4,o=o[0])}return s(),o}(e)),t),arguments,[])).length>1?t:t[0]}var sO=oO.bind(v.createElement),cO=class extends v.Component{state={err:null};static getDerivedStateFromError(e){return{err:String(e?.message||e)}}componentDidCatch(e){try{this.props.onError?.(String(e?.message||e))}catch{}}render(){return this.state.err?(0,K.jsxs)(`div`,{className:`p-3 text-[11px] leading-relaxed text-red-400`,children:[`面板运行错误:`,this.state.err,(0,K.jsx)(`br`,{}),`可在「定制工作台」中修正代码后重新发布。`]}):this.props.children}};function lO(e){return Function(`React`,`html`,`useState`,`useEffect`,`useRef`,`useMemo`,`"use strict";\n${e}\n;if (typeof Panel !== "function") throw new Error("插件代码必须定义 function Panel(props)");\nreturn Panel;`)(v,sO,v.useState,v.useEffect,v.useRef,v.useMemo)}function uO(e,t,n){if(e)try{fetch(`/api/panel-error`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({...e,kind:t,message:n})}).catch(()=>{})}catch{}}function dO({code:e,data:t,meta:n}){let r=n?.agentId,i=n?.panelId,a=n?.pluginId,o=(0,v.useMemo)(()=>{let t={agentId:r,panelId:i,pluginId:a};try{return lO(e)}catch(e){return uO(t,`compile`,String(e.message)),()=>(0,K.jsxs)(`div`,{className:`p-3 text-[11px] text-red-400`,children:[`编译失败:`,String(e.message)]})}},[e,r,i,a]);return(0,K.jsx)(cO,{onError:e=>uO(n,`runtime`,e),children:(0,K.jsx)(o,{...t})})}var fO=12;function pO({dsl:e,renderPanel:t,renderDialog:n,renderPlaceholder:r,edit:i,className:a}){let o=(0,v.useRef)(null),s=(0,v.useRef)(null),c=e.panels.reduce((e,t)=>Math.max(e,(t.grid?.y||1)+(t.grid?.h||1)-1),1),l=()=>{let e=o.current?.getBoundingClientRect();return{col:e?(e.width+fO)/12:100,row:e?(e.height+fO)/c:178}},u=(t,n,r)=>{if(!i||t.button!==0)return;t.stopPropagation();let a=e.panels[n].grid||{x:1,y:1,w:6,h:1};s.current={i:n,mode:r,sx:t.clientX,sy:t.clientY,g:{...a},moved:!1};try{t.currentTarget.setPointerCapture(t.pointerId)}catch{}},d=e=>{let t=s.current;if(!i||!t)return;let n=e.clientX-t.sx,r=e.clientY-t.sy;if(!t.moved&&Math.abs(n)<4&&Math.abs(r)<4)return;t.moved=!0;let{col:a,row:o}=l(),c=Math.round(n/a),u=Math.round(r/o);t.mode===`move`?i.onGrid(t.i,{x:Math.min(Math.max(1,t.g.x+c),12-t.g.w+1),y:Math.max(1,t.g.y+u)}):i.onGrid(t.i,{w:Math.min(Math.max(1,t.g.w+c),12-t.g.x+1),h:Math.min(Math.max(1,t.g.h+u),12)})},f=()=>{setTimeout(()=>{s.current=null},0)};return(0,K.jsx)(`div`,{ref:o,className:it(`grid gap-3`,i&&`touch-none select-none`,a),style:{gridTemplateColumns:`repeat(12, minmax(0, 1fr))`,gridTemplateRows:`repeat(${c}, minmax(120px, 1fr))`},onPointerDown:()=>{i&&i.onSelect(null)},children:e.panels.map((e,a)=>{let o=e.grid||{x:1,y:1,w:6,h:1},s=Math.round(o.w/12*100),c=e.type===`agent_dialog`?n?n(e):null:e.type===`placeholder`?r?r(e):null:t(e);return(0,K.jsxs)(`div`,{style:{gridColumn:`${o.x} / span ${o.w}`,gridRow:`${o.y} / span ${o.h}`},className:it(`relative flex min-h-0 flex-col overflow-hidden rounded-lg border bg-card`,i?i.sel===a?`border-primary ring-2 ring-primary/50`:`border-border hover:border-primary/50`:`border-border`,i&&`cursor-grab active:cursor-grabbing`),onPointerDown:e=>{i&&(e.stopPropagation(),i.onSelect(a),u(e,a,`move`))},onPointerMove:d,onPointerUp:f,onPointerCancel:f,children:[i&&(0,K.jsxs)(`div`,{className:`pointer-events-none absolute inset-x-0 top-0 z-10 flex items-center gap-1.5 border-b bg-background/85 px-2 py-1 text-[10px] backdrop-blur-sm`,children:[(0,K.jsx)(`span`,{className:`font-medium`,children:e.title}),(0,K.jsx)(J,{variant:`secondary`,className:`h-4 px-1 text-[9px]`,children:e.panel||e.type}),(0,K.jsxs)(`span`,{className:`ml-auto font-mono text-muted-foreground`,children:[s,`%宽·`,o.h,`行`]})]}),(0,K.jsx)(`div`,{className:it(`min-h-0 flex-1 overflow-auto`,i&&`pointer-events-none pt-4`),children:c}),i&&(0,K.jsx)(`span`,{onPointerDown:e=>u(e,a,`resize`),onPointerMove:d,onPointerUp:f,onPointerCancel:f,className:`absolute bottom-0 right-0 z-10 h-4 w-4 cursor-nwse-resize rounded-br-md border-b border-r border-primary/60 bg-primary/25 hover:bg-primary/50`,title:`拖拽调跨列/跨行(当前 ${s}% 宽)`,children:(0,K.jsx)(rg,{className:`h-2.5 w-2.5 translate-x-[3px] translate-y-[3px] text-primary`})})]},e.id)})})}function mO(){return(0,K.jsxs)(`div`,{className:`relative mb-1 h-4 select-none text-[9px] text-muted-foreground`,children:[(0,K.jsx)(`div`,{className:`grid h-full grid-cols-12`,children:[...Array(12)].map((e,t)=>(0,K.jsx)(`div`,{className:`border-l border-border/60 pl-0.5 pt-0.5 font-mono`,children:t+1},t))}),[25,50,75].map(e=>(0,K.jsxs)(`span`,{className:`absolute -top-0 font-mono`,style:{left:`${e}%`},children:[e,`%`]},e))]})}function hO({open:e,onOpenChange:t,onPick:n}){let[r,i]=(0,v.useState)(null),[a,o]=(0,v.useState)(!1),[s,c]=(0,v.useState)(``),l=e=>{o(!0),c(``),ot(`/api/fs/dirs${e?`?path=${encodeURIComponent(e)}`:``}`).then(e=>i(e)).catch(e=>c(String(e.message))).finally(()=>o(!1))};return(0,v.useEffect)(()=>{e&&!r&&l()},[e]),(0,K.jsx)(a_,{open:e,onOpenChange:t,children:(0,K.jsxs)(c_,{className:`max-w-md`,children:[(0,K.jsx)(l_,{children:(0,K.jsx)(d_,{children:`选择工作区目录`})}),(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-7 gap-1 px-2 text-[11px]`,disabled:!r?.parent,onClick:()=>r?.parent&&l(r.parent),title:`上级目录`,children:[(0,K.jsx)(Zm,{className:`h-3 w-3`}),`上级`]}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-7 gap-1 px-2 text-[11px]`,onClick:()=>l(),children:[(0,K.jsx)(zh,{className:`h-3 w-3`}),`主目录`]}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate rounded-md border bg-muted/40 px-2 py-1.5 font-mono text-[11px] text-muted-foreground`,title:r?.path,children:r?.path||`…`})]}),(0,K.jsxs)(eO,{className:`h-64 rounded-md border`,children:[a&&(0,K.jsxs)(`div`,{className:`flex h-full items-center justify-center gap-2 text-xs text-muted-foreground`,children:[(0,K.jsx)($h,{className:`h-4 w-4 animate-spin`}),`读取中…`]}),!a&&s&&(0,K.jsx)(`div`,{className:`p-3 text-xs text-red-400`,children:s}),!a&&!s&&r&&r.dirs.length===0&&(0,K.jsx)(`div`,{className:`p-3 text-xs text-muted-foreground`,children:`此目录下没有子目录——可直接点「选择当前目录」。`}),!a&&!s&&r&&r.dirs.map(e=>(0,K.jsxs)(`button`,{onClick:()=>l(`${r.path}/${e}`),className:`flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent`,children:[(0,K.jsx)(Fh,{className:`h-3.5 w-3.5 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`truncate`,children:e})]},e))]}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,onClick:()=>t(!1),children:`取消`}),(0,K.jsxs)(Y,{className:`gap-1`,disabled:!r||a,onClick:()=>{r&&(n(r.path),t(!1))},children:[(0,K.jsx)(rh,{className:`h-3.5 w-3.5`}),`选择当前目录`]})]})]})})}function gO({agentId:e,onName:t,onEdit:n}){let[r,i]=(0,v.useState)(null),[a,o]=(0,v.useState)(null),[s,c]=(0,v.useState)(null),[l,u]=(0,v.useState)([]),[d,f]=(0,v.useState)(null),[p,m]=(0,v.useState)(2),[h,g]=(0,v.useState)(null),[_,y]=(0,v.useState)(!1),[b,x]=(0,v.useState)(``),[S,C]=(0,v.useState)(``),[w,T]=(0,v.useState)(!1),[E,D]=(0,v.useState)(!1),[O,k]=(0,v.useState)(null),[A,j]=(0,v.useState)(!1),M=(0,v.useMemo)(()=>h?.workspaces.find(e=>e.id===h.current)||null,[h]),N=M?.id||`default`,P=(0,v.useMemo)(()=>`chat-${e}-${N}`,[e,N]),F=()=>ot(`/api/state`).then(c).catch(()=>{}),I=()=>ot(`/api/workspaces?agent_id=${e}`).then(g).catch(()=>{});(0,v.useEffect)(()=>{ot(`/api/workbench?agent_id=${e}`).then(e=>{i(e.dsl),e.dsl&&t(e.dsl.workbench)}),ot(`/api/deployment?agent_id=${e}`).then(e=>{o(e.deployment),m({L0:0,L1:1,L2:2,L3:3}[e.deployment?.default_autonomy||`L2`]??2)}),ot(`/api/panels?with_code=1`).then(e=>u(e.plugins||[])),I(),F();let n=setInterval(F,5e3);return()=>clearInterval(n)},[e]);let L=async t=>{try{g(await st(`/api/workspaces/select`,{agent_id:e,ws_id:t}))}catch(e){Z.error(String(e.message))}},R=async()=>{D(!0);try{let t=await st(`/api/workspaces`,{agent_id:e,name:b||void 0,...S?{path:S}:{}});g(t),y(!1),x(``),C(``),Z.success(`工作区已创建${S?`(登记外部目录)`:``}`),await L(t.workspaces[t.workspaces.length-1].id)}catch(e){Z.error(String(e.message))}finally{D(!1)}},ee=async()=>{if(O)try{g(await lt(`/api/workspaces/${O.id}?agent_id=${e}`,{purge:A})),Z.success(`工作区已删除${A?`(目录已清除)`:`(仅移除登记)`}`),k(null),j(!1)}catch(e){Z.error(String(e.message))}},te=(0,v.useMemo)(()=>r?.panels||[],[r]).filter(e=>e.type===`custom`||e.type===`custom_panel`).map(e=>({panel:e,code:e.type===`custom`?e.code||``:l.find(t=>t.id===e.panel)?.code||``})).filter(e=>e.code),z=t=>({devices:s?.devices||[],alarms:s?.alarms||[],kpi:s?.kpi||{},work_orders:s?.work_orders||[],inspections:s?.inspections||{},selected:d,onSelect:f,agentId:e,store:mt(e,N),runAction:(n,r)=>ht(e,String(t?.id||``),n,r),params:{...t?.params||{},agentId:e,wsId:N}});return!r||!s?(0,K.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:`工作台加载中…`}):(0,K.jsxs)(`div`,{className:`flex h-full flex-col gap-2 overflow-hidden px-4 py-2.5`,children:[(0,K.jsx)(`h1`,{className:`sr-only`,children:r.workbench}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px]`,children:[(0,K.jsx)(J,{variant:`secondary`,className:`h-5 shrink-0 text-[10px]`,children:r.version}),te.length>0&&(0,K.jsxs)(J,{variant:`outline`,className:`h-5 shrink-0 text-[10px] text-violet-400 border-violet-500/40`,children:[(0,K.jsx)(pg,{className:`mr-0.5 h-2.5 w-2.5`}),`插件 ×`,te.length]}),(0,K.jsxs)(`span`,{className:`shrink-0 text-muted-foreground`,children:[a?.name,` · 工具 `,a?.toolset.length,` 个`]}),M&&(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(jh,{className:`h-3 w-3 shrink-0 text-muted-foreground`}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-muted-foreground`,title:M.path,children:M.path}),(0,K.jsx)(`span`,{className:`shrink-0 text-[10px] text-muted-foreground`,children:`(exec 工作目录 · 数据与文件随工作区隔离)`})]}),(0,K.jsxs)(`div`,{className:`ml-auto flex items-center gap-1.5`,children:[(0,K.jsx)(qh,{className:`h-3.5 w-3.5 text-muted-foreground`}),(0,K.jsxs)(h_,{value:N,onValueChange:L,children:[(0,K.jsx)(__,{className:`h-8 w-52 text-xs`,title:M?.path,children:(0,K.jsx)(g_,{children:(0,K.jsx)(`span`,{className:`truncate`,children:M?`${M.name}${M.external?`(外部)`:``}`:`默认工作区`})})}),(0,K.jsx)(v_,{children:(h?.workspaces||[]).map(e=>(0,K.jsx)(y_,{value:e.id,className:`text-xs`,children:(0,K.jsxs)(`span`,{className:`max-w-64 truncate`,title:e.path,children:[e.name,e.external?` · 外部目录`:``,e.id===h?.current?` ✓`:``]})},e.id))})]}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-8 gap-1 text-xs`,onClick:()=>y(!0),title:`新建工作区(默认目录或自定义路径)`,children:[(0,K.jsx)(Nh,{className:`h-3.5 w-3.5`}),`新建`]}),M&&M.id!=="default"&&(0,K.jsx)(Y,{size:`sm`,variant:`ghost`,className:`h-8 w-8 p-0 text-muted-foreground`,onClick:()=>k(M),title:`删除当前工作区`,children:(0,K.jsx)(qg,{className:`h-3.5 w-3.5`})}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-8 gap-1 text-xs`,onClick:n,children:[(0,K.jsx)(Dg,{className:`h-3.5 w-3.5`}),`编辑布局`]})]})]}),(0,K.jsx)(`div`,{className:`relative min-h-0 flex-1`,children:(0,K.jsx)(pO,{className:`absolute inset-0 overflow-auto p-0.5`,dsl:r,renderPanel:t=>{let n=te.find(e=>e.panel.id===t.id);return n?(0,K.jsx)(dO,{code:n.code,data:z(t),meta:{agentId:e,panelId:t.id,pluginId:t.panel}},`${t.id}:${N}`):null},renderDialog:()=>(0,K.jsx)(rO,{agentId:e,sessionId:P,wsId:N,injectedDevice:d,autonomy:p,onAutonomy:m},`${e}:${N}`),renderPlaceholder:()=>(0,K.jsx)(`div`,{className:`flex h-full items-center justify-center p-4 text-center text-[11px] text-muted-foreground`,children:`空区块——到「编辑布局」添加插件或让 AI 定制`})})}),(0,K.jsx)(a_,{open:_,onOpenChange:y,children:(0,K.jsxs)(c_,{children:[(0,K.jsx)(l_,{children:(0,K.jsx)(d_,{children:`新建工作区`})}),(0,K.jsxs)(`div`,{className:`space-y-3`,children:[(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`名称`}),(0,K.jsx)(p_,{value:b,onChange:e=>x(e.target.value),placeholder:`如:产线B改造`,className:`text-xs`})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`自定义目录(可选,留空则在平台 workspace 目录下动态新增)`}),(0,K.jsxs)(`div`,{className:`flex gap-1.5`,children:[(0,K.jsx)(p_,{value:S,onChange:e=>C(e.target.value),placeholder:`/Users/you/projects/line-b 或点浏览选择`,className:`font-mono text-xs`}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-8 shrink-0 gap-1 text-xs`,onClick:()=>T(!0),children:[(0,K.jsx)(jh,{className:`h-3.5 w-3.5`}),`浏览…`]})]}),(0,K.jsx)(`p`,{className:`text-[10px] text-amber-400`,children:`⚠ 助手将能读写该目录(exec 工作目录即此处);目录须已存在,平台不会在其中写入数据库文件。`})]})]}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,disabled:E,onClick:()=>y(!1),children:`取消`}),(0,K.jsx)(Y,{disabled:E,onClick:R,children:E?`创建中…`:`创建并切换`})]}),(0,K.jsx)(hO,{open:w,onOpenChange:T,onPick:e=>C(e)})]})}),(0,K.jsx)(a_,{open:!!O,onOpenChange:e=>{e||(k(null),j(!1))},children:(0,K.jsxs)(c_,{children:[(0,K.jsx)(l_,{children:(0,K.jsxs)(d_,{children:[`删除工作区 · `,O?.name]})}),(0,K.jsxs)(`div`,{className:`space-y-2 text-xs`,children:[(0,K.jsx)(`p`,{className:`font-mono text-[11px] text-muted-foreground`,children:O?.path}),O?.external?(0,K.jsxs)(`p`,{children:[`外部目录工作区:仅移除登记,`,(0,K.jsx)(`b`,{children:`不删除`}),`你的文件;该工作区的数据集库将一并删除。`]}):(0,K.jsxs)(`label`,{className:`flex items-start gap-2 rounded-md border border-red-500/30 bg-red-500/5 p-2.5`,children:[(0,K.jsx)(i_,{checked:A,onCheckedChange:e=>j(!!e)}),(0,K.jsx)(`span`,{children:`同时删除平台目录下的工作区文件夹(数据集库始终删除)`})]})]}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,onClick:()=>k(null),children:`取消`}),(0,K.jsx)(Y,{variant:`destructive`,onClick:ee,children:`确认删除`})]})]})})]})}function _O({className:e,orientation:t=`horizontal`,decorative:n=!0,...r}){return(0,K.jsx)(Fp,{"data-slot":`separator`,decorative:n,orientation:t,className:mn(`shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px`,e),...r})}function vO({className:e,orientation:t=`horizontal`,...n}){return(0,K.jsx)(lm,{"data-slot":`tabs`,"data-orientation":t,orientation:t,className:mn(`group/tabs flex gap-2 data-[orientation=horizontal]:flex-col`,e),...n})}var yO=yt(`group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col data-[variant=line]:rounded-none`,{variants:{variant:{default:`bg-muted`,line:`gap-1 bg-transparent`}},defaultVariants:{variant:`default`}});function bO({className:e,variant:t=`default`,...n}){return(0,K.jsx)(dm,{"data-slot":`tabs-list`,"data-variant":t,className:mn(yO({variant:t}),e),...n})}function xO({className:e,...t}){return(0,K.jsx)(pm,{"data-slot":`tabs-trigger`,className:mn(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent`,`data-[state=active]:bg-background data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100`,e),...t})}function SO({className:e,...t}){return(0,K.jsx)(hm,{"data-slot":`tabs-content`,className:mn(`flex-1 outline-none`,e),...t})}function CO({...e}){return(0,K.jsx)(gd,{"data-slot":`dropdown-menu`,...e})}function wO({...e}){return(0,K.jsx)(vd,{"data-slot":`dropdown-menu-trigger`,...e})}function TO({className:e,sideOffset:t=4,...n}){return(0,K.jsx)(yd,{children:(0,K.jsx)(xd,{"data-slot":`dropdown-menu-content`,sideOffset:t,className:mn(`z-50 min-w-36 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95`,e),...n})})}function EO({className:e,...t}){return(0,K.jsx)(Sd,{"data-slot":`dropdown-menu-item`,className:mn(`relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-xs outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:h-3.5 [&_svg]:w-3.5 [&_svg]:shrink-0`,e),...t})}function DO({className:e,...t}){return(0,K.jsx)(Cd,{"data-slot":`dropdown-menu-separator`,className:mn(`-mx-1 my-1 h-px bg-border`,e),...t})}async function OO(e,t){let n=e.usage.length?`插件「${e.name}」被 ${e.usage.length} 处引用,删除将从这些工作台摘除该面板。确认删除?`:`删除插件「${e.name}」?`;if(window.confirm(n))try{await lt(`/api/panels`,{id:e.id,force:!0}),Z.success(`已删除`),t()}catch(e){Z.error(String(e.message))}}function kO({target:e,onClose:t,agents:n}){let[r,i]=(0,v.useState)(null),[a,o]=(0,v.useState)(``),[s,c]=(0,v.useState)(!0),[l,u]=(0,v.useState)(!1);(0,v.useEffect)(()=>{if(!e){i(null);return}let n=e.type===`panel`?`id=${encodeURIComponent(e.id||``)}`:`agentId=${encodeURIComponent(e.agentId||``)}`;ot(`/api/assets/preview?type=${e.type}&${n}`).then(e=>{i(e),o(e.name)}).catch(e=>{Z.error(String(e.message)),t()})},[e]);let d=async()=>{if(e){u(!0);try{let n=await st(`/api/assets/share`,{type:e.type,id:e.id,agentId:e.agentId,name:a,bind_agent:s&&e.agentId?e.agentId:void 0}),i=r?.manifest.requires.apis.length||0,o=r?.manifest.requires.actions.length||0;Z.success(`已发布 ${n.name}@${n.version}${n.bound?`,已绑定到助手`:``}`,{description:`外部 API ×${i} · 交互脚本 ×${o}${o?`(命令全文已在 ARM 资产包 SKILL.md 留档)`:``}`}),t()}catch(e){Z.error(String(e.message))}finally{u(!1)}}};if(!e)return null;let f=r?.manifest.requires;return(0,K.jsx)(a_,{open:!!e,onOpenChange:e=>{!e&&!l&&t()},children:(0,K.jsxs)(c_,{children:[(0,K.jsx)(l_,{children:(0,K.jsxs)(d_,{className:`flex items-center gap-2`,children:[(0,K.jsx)(_h,{className:`h-4 w-4 text-primary`}),`发布为 UI 资产 · `,e.title]})}),(0,K.jsx)(eO,{className:`max-h-96`,children:(0,K.jsxs)(`div`,{className:`space-y-3 pr-2 text-xs`,children:[(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`资产名(全局唯一锚,同名发布追加新版本)`}),(0,K.jsx)(p_,{value:a,onChange:e=>o(e.target.value),className:`font-mono text-xs`})]}),r&&(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`div`,{className:`rounded-md border bg-muted/30 p-2.5`,children:[(0,K.jsx)(`div`,{className:`font-medium`,children:`包含内容`}),(0,K.jsxs)(`div`,{className:`mt-1 text-muted-foreground`,children:[`面板插件:`,r.manifest.provides.panels.join(`、`)||`无`,(0,K.jsx)(`br`,{}),`数据集 schema:`,r.manifest.provides.collections.join(`、`)||`无`,`(仅建表定义,不含数据)`,r.manifest.provides.workbench&&(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(`br`,{}),`工作台 DSL:workbench.json`]})]}),(0,K.jsx)(`div`,{className:`mt-1 font-mono text-[10px] text-muted-foreground`,children:r.files.join(` · `)})]}),!!f?.apis.length&&(0,K.jsxs)(`div`,{className:`rounded-md border border-blue-500/30 bg-blue-500/5 p-2.5`,children:[(0,K.jsx)(`div`,{className:`font-medium text-blue-300`,children:`外部 API 依赖(安装后环境需可达)`}),(0,K.jsx)(`ul`,{className:`mt-1 list-disc pl-4 text-muted-foreground`,children:f.apis.map(e=>(0,K.jsxs)(`li`,{children:[(0,K.jsx)(`span`,{className:`font-mono`,children:e.host}),`:`,e.usage]},e.host))})]}),!!f?.actions.length&&(0,K.jsxs)(`div`,{className:`rounded-md border border-amber-500/30 bg-amber-500/5 p-2.5`,children:[(0,K.jsx)(`div`,{className:`font-medium text-amber-300`,children:`交互脚本(真实 shell 命令,随包公开)`}),(0,K.jsx)(`ul`,{className:`mt-1 space-y-1`,children:f.actions.map(e=>(0,K.jsxs)(`li`,{className:`text-muted-foreground`,children:[`[`,e.panel,`/`,e.id,`] `,e.label,e.has_credentials&&(0,K.jsx)(J,{className:`ml-1 h-4 bg-amber-500/15 px-1 text-[9px] text-amber-300`,children:`⚠️ 疑似含凭据`}),(0,K.jsx)(`div`,{className:`mt-0.5 break-all rounded bg-muted/50 p-1 font-mono text-[10px]`,children:e.exec})]},`${e.panel}/${e.id}`))}),(0,K.jsx)(`p`,{className:`mt-1.5 text-[10px] text-amber-400`,children:`命令明文将进入资产包——含密码/令牌的命令请先改用环境变量或凭据占位,再发布。`})]}),e.agentId&&n&&n.length>0&&(0,K.jsxs)(`label`,{className:`flex items-center gap-2 rounded-md border p-2.5`,children:[(0,K.jsx)(i_,{checked:s,onCheckedChange:e=>c(!!e)}),(0,K.jsx)(`span`,{children:`发布后同时绑定到当前助手(下载该助手的其他现场将自动物化此工作台)`})]})]})]})}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,disabled:l,onClick:t,children:`取消`}),(0,K.jsx)(Y,{disabled:l||!a,onClick:d,children:l?`发布中…`:`发布到 ARM`})]})]})})}function AO({open:e,onClose:t,onInstalled:n,agents:r}){let[i,a]=(0,v.useState)(``),[o,s]=(0,v.useState)([]),[c,l]=(0,v.useState)(!1),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),m=(0,v.useRef)(0);(0,v.useEffect)(()=>{if(!e)return;let t=setTimeout(()=>{let e=++m.current;l(!0),ot(`/api/assets/arm-library${i?`?keyword=${encodeURIComponent(i)}`:``}`).then(t=>{e===m.current&&s(t.items||[])}).catch(e=>Z.error(String(e.message))).finally(()=>{e===m.current&&l(!1)})},400);return()=>clearTimeout(t)},[i,e]),(0,v.useEffect)(()=>{e&&!f&&r.length&&p(r[0].agent_id)},[e,r]);let h=async e=>{if(e.asset_type===`workbench`&&!f)Z.warning(`请先选择目标助手`);else{d(e.name);try{let r=await st(`/api/assets/install`,{name:e.name,agentId:e.asset_type===`workbench`?f:void 0}),i=r.workbench?`,工作台已导入为草稿(审阅后在「定制工作台」发布)`:``,a=r.skipped_collections.length?`;同名数据集保留本地:${r.skipped_collections.join(`、`)}`:``;Z.success(`已安装 ${e.name}:面板 ×${r.panels.length}${i}${a}`),n(),t()}catch(e){Z.error(String(e.message))}finally{d(null)}}};return(0,K.jsx)(a_,{open:e,onOpenChange:e=>{!e&&!u&&t()},children:(0,K.jsxs)(c_,{children:[(0,K.jsx)(l_,{children:(0,K.jsxs)(d_,{className:`flex items-center gap-2`,children:[(0,K.jsx)(Yh,{className:`h-4 w-4 text-primary`}),`从 ARM 安装 UI 资产`]})}),(0,K.jsxs)(`div`,{className:`relative`,children:[(0,K.jsx)(xg,{className:`absolute left-3 top-2.5 h-3.5 w-3.5 text-muted-foreground`}),(0,K.jsx)(p_,{placeholder:`搜索资产名 / 描述…`,value:i,onChange:e=>a(e.target.value),className:`pl-9`,autoFocus:!0})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,K.jsx)(`span`,{className:`shrink-0`,children:`工作台资产安装到:`}),(0,K.jsx)(`select`,{value:f,onChange:e=>p(e.target.value),className:`h-8 flex-1 rounded-md border bg-background px-2 text-xs`,children:r.map(e=>(0,K.jsx)(`option`,{value:e.agent_id,children:e.name},e.agent_id))})]}),(0,K.jsx)(eO,{className:`max-h-80`,children:(0,K.jsxs)(`div`,{className:`space-y-1.5 pr-2`,children:[c&&!o.length&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:`加载中…`}),!c&&!o.length&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:i?`没有匹配资产`:`ARM 上暂无 UI 资产`}),o.map(e=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2.5 rounded-md border p-2.5`,children:[e.asset_type===`workbench`?(0,K.jsx)(Yh,{className:`h-4 w-4 shrink-0 text-violet-400`}):(0,K.jsx)(pg,{className:`h-4 w-4 shrink-0 text-primary`}),(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs font-medium`,children:[(0,K.jsx)(`span`,{className:`truncate font-mono`,children:e.name}),e.latest_version&&(0,K.jsx)(J,{variant:`secondary`,className:`h-4 px-1 text-[9px]`,children:e.latest_version}),e.installed&&(0,K.jsx)(J,{className:`h-4 bg-emerald-500/15 px-1 text-[9px] text-emerald-400`,children:`本地已有`}),e.upgrade_available&&(0,K.jsx)(J,{className:`h-4 bg-amber-500/15 px-1 text-[9px] text-amber-300`,children:`⤴ 可升级`})]}),(0,K.jsxs)(`div`,{className:`truncate text-[10px] text-muted-foreground`,children:[e.description||`—`,` · 下载 `,e.download_count,` 次 · `,e.publisher]})]}),(0,K.jsx)(Y,{size:`sm`,variant:`secondary`,className:`h-7 text-[11px]`,disabled:u!==null,onClick:()=>h(e),children:u===e.name?`安装中…`:`安装`})]},e.name))]})}),(0,K.jsx)(u_,{children:(0,K.jsx)(Y,{variant:`outline`,onClick:t,children:`关闭`})})]})})}function jO(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(!1),[o,s]=(0,v.useState)([]),c=()=>ot(`/api/plugins/center`).then(t);if((0,v.useEffect)(()=>{c(),ot(`/api/agents`).then(e=>s((e.agents||[]).filter(e=>e.installed).map(({agent_id:e,name:t})=>({agent_id:e,name:t})))).catch(()=>{})},[]),!e)return(0,K.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:`插件中心加载中…`});let l=async(e,t,n)=>{let r=n===`deprecated`?`active`:`deprecated`;try{await st(`/api/plugins/lifecycle`,{kind:e,id:t,status:r}),Z.success(r===`deprecated`?`已停用(存量引用仍可渲染,新增被阻止)`:`已恢复`),c()}catch(e){Z.error(String(e.message))}},u=({icon:e,name:t,sub:n,status:r,usage:i,onToggle:a,tag:o,onDelete:s,onShare:c,armRef:l})=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2.5 rounded-md border p-2.5`,children:[(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs font-medium`,children:[e,t,(0,K.jsx)(J,{variant:`secondary`,className:`h-4 px-1 text-[9px]`,children:o}),(0,K.jsx)(J,{className:`h-4 px-1 text-[9px] ${r===`deprecated`?`bg-red-500/15 text-red-400 hover:bg-red-500/25`:`bg-emerald-500/15 text-emerald-400 hover:bg-emerald-500/25`}`,children:r===`deprecated`?`已停用`:`在用`}),l&&(0,K.jsxs)(J,{className:`h-4 bg-violet-500/15 px-1 text-[9px] text-violet-300`,title:`ARM ${l.skill_name}@${l.version||``}`,children:[`已发布`,l.version?` ${l.version}`:``]})]}),(0,K.jsx)(`div`,{className:`truncate text-[10px] text-muted-foreground`,children:n}),(0,K.jsxs)(`div`,{className:`mt-0.5 text-[10px] text-muted-foreground`,children:[`引用:`,i.length?i.map(e=>`${e.agent}${e.draft?`*`:``}`).join(`、`):`无`]})]}),c&&(0,K.jsxs)(Y,{size:`sm`,variant:`ghost`,className:`h-7 text-[11px] text-violet-400`,onClick:c,title:`发布到 ARM UI 资产市场`,children:[(0,K.jsx)(_h,{className:`h-3 w-3`}),l?`更新`:`发布`]}),s&&(0,K.jsx)(Y,{size:`sm`,variant:`ghost`,className:`h-7 text-[11px] text-red-400`,onClick:s,children:`删除`}),(0,K.jsx)(Y,{size:`sm`,variant:r===`deprecated`?`secondary`:`ghost`,className:`h-7 text-[11px] ${r===`deprecated`?``:`text-red-400`}`,onClick:a,children:r===`deprecated`?`恢复`:`停用`})]});return(0,K.jsxs)(`div`,{className:`h-full overflow-auto p-5`,children:[(0,K.jsxs)(`div`,{className:`mb-4`,children:[(0,K.jsxs)(`h1`,{className:`flex items-center gap-2 text-lg font-bold`,children:[(0,K.jsx)(pg,{className:`h-5 w-5 text-primary`}),`插件中心`]}),(0,K.jsxs)(`p`,{className:`mt-0.5 text-xs text-muted-foreground`,children:[`统一注册表:系统面板与契约插件同源治理 · 生命周期(在用/停用)· 引用追踪(* 为草稿引用)· `,(0,K.jsx)(`span`,{className:`text-violet-400`,children:`发布/安装 ARM UI 资产(三资产模型)`})]})]}),(0,K.jsxs)(`div`,{className:`grid grid-cols-2 gap-4`,children:[(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsxs)(Sm,{className:`flex items-center gap-1.5 text-xs`,children:[(0,K.jsx)(Dh,{className:`h-3.5 w-3.5`}),`系统插件(平台预装)`]})}),(0,K.jsx)(Cm,{className:`p-3`,children:(0,K.jsx)(`div`,{className:`space-y-1.5`,children:e.system.map(e=>(0,K.jsx)(u,{icon:(0,K.jsx)(`span`,{className:`font-mono text-[10px] text-muted-foreground`,children:e.id}),name:e.name,sub:e.note,status:e.status,usage:e.usage,tag:`system`,onToggle:()=>l(`system`,e.id,e.status)},e.id))})})]}),(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsxs)(Sm,{className:`flex items-center gap-1.5 text-xs`,children:[(0,K.jsx)(th,{className:`h-3.5 w-3.5`}),`插件库(AI 开发 / 人工沉淀)`]}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,className:`h-7 gap-1 text-[11px]`,onClick:()=>a(!0),children:[(0,K.jsx)(Yh,{className:`h-3 w-3`}),`从 ARM 安装`]})]})}),(0,K.jsx)(Cm,{className:`p-3`,children:(0,K.jsxs)(`div`,{className:`space-y-1.5`,children:[e.library.map(e=>(0,K.jsx)(u,{icon:(0,K.jsx)(pg,{className:`h-3 w-3 text-primary`}),name:`${e.name} ${e.version}`,sub:`${e.author===`ai`?`AI 开发`:e.author===`arm`?`ARM 安装`:`人工`} · ${e.description||e.id}`,status:e.status,usage:e.usage,tag:e.author===`ai`?`ai`:e.author===`arm`?`arm`:`human`,onToggle:()=>l(`plugin`,e.id,e.status),onDelete:()=>OO(e,c),onShare:()=>r({type:`panel`,id:e.id,title:e.name}),armRef:e.arm_ref},e.id)),e.library.length===0&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:`插件库为空`})]})})]})]}),(0,K.jsx)(_O,{className:`my-4`}),(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsxs)(Sm,{className:`flex items-center gap-1.5 text-xs`,children:[(0,K.jsx)(Ng,{className:`h-3.5 w-3.5`}),`治理策略`]})}),(0,K.jsx)(Cm,{className:`p-3 text-[11px] leading-relaxed text-muted-foreground`,children:(0,K.jsx)(eO,{className:`max-h-40`,children:(0,K.jsxs)(`ul`,{className:`list-disc space-y-1 pl-4`,children:[(0,K.jsx)(`li`,{children:`一切面板进同一注册表:系统插件也有 manifest 与生命周期,不再是编译进前端的二等公民`}),(0,K.jsx)(`li`,{children:`停用(deprecate)不破坏存量:已引用的工作台继续渲染,但编辑器「添加面板」不再出现——安全下线`}),(0,K.jsx)(`li`,{children:`入库强制过校验器(check-panel.mjs):编译/契约/沙箱/模板四关 + 质量警告入审计——ARM 安装的插件同样过检`}),(0,K.jsx)(`li`,{children:`出网最小化:/api/proxy 仅放行插件代码中声明过的主机(防止面板成为任意内网跳板)`}),(0,K.jsx)(`li`,{children:`版本化与回滚:插件独立版本(同 id 覆盖自增),工作台按 id 引用,升级即时生效可回滚`}),(0,K.jsx)(`li`,{children:`数据隔离:插件数据集按助手分库(store-助手ID.db),共享需显式 scope=shared;资产包只带 schema 不带数据`}),(0,K.jsx)(`li`,{children:`UI 资产四红线(docs/08):包非运行时 · 数据必走 collection · 外部依赖必声明 · 单向 DAG`})]})})})]}),(0,K.jsx)(kO,{target:n,onClose:()=>{r(null),c()},agents:o}),(0,K.jsx)(AO,{open:i,onClose:()=>a(!1),onInstalled:c,agents:o})]})}function MO({pluginId:e,onRollback:t}){let[n,r]=(0,v.useState)(null);return(0,v.useEffect)(()=>{e&&ot(`/api/panels?id=${e}`).then(e=>r(e.plugin)).catch(()=>r(null))},[e]),n?(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[11px]`,children:[(0,K.jsx)(`span`,{className:`font-mono`,children:n.version}),(0,K.jsx)(`span`,{className:`text-muted-foreground`,children:`(当前)`})]}),(n.history||[]).slice().reverse().map(n=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px]`,children:[(0,K.jsx)(`span`,{className:`font-mono`,children:n.version}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:gt(n.at,`dts`)}),(0,K.jsx)(Y,{size:`sm`,variant:`ghost`,className:`ml-auto h-6 text-[10px]`,onClick:()=>t(e,n.version),children:`回退`})]},n.version)),!(n.history||[]).length&&(0,K.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,children:`无历史版本`})]}):(0,K.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,children:`(插件信息加载中…)`})}var NO=e=>({x:1,y:e.reduce((e,t)=>Math.max(e,t.grid?t.grid.y+t.grid.h-1:0),0)+1,w:6,h:1});function PO({agentId:e}){let[t,n]=(0,v.useState)(null),[r,i]=(0,v.useState)(!1),[a,o]=(0,v.useState)([]),[s,c]=(0,v.useState)(``),[l,u]=(0,v.useState)(!1),[d,f]=(0,v.useState)([]),[p,m]=(0,v.useState)(!1),[h,g]=(0,v.useState)(null),[_,y]=(0,v.useState)(null),[b,x]=(0,v.useState)(!1),[S,C]=(0,v.useState)(0),[w,T]=(0,v.useState)(null),[E,D]=(0,v.useState)([]),[O,k]=(0,v.useState)(null),A=(0,v.useRef)(`dev-${e.slice(0,8)}`).current,j=(0,v.useRef)(null),[M,N]=(0,v.useState)([]),[P,F]=(0,v.useState)(``),[I,L]=(0,v.useState)(!1),[R,ee]=(0,v.useState)(``),[te,z]=(0,v.useState)(null),[ne,re]=(0,v.useState)(!1),[ie,ae]=(0,v.useState)(null),oe=(0,v.useRef)(null),se=(0,v.useRef)(!0),ce=(0,v.useCallback)(()=>{let e=oe.current?.closest(`[data-slot="scroll-area-viewport"]`);e&&(e.scrollTop=e.scrollHeight)},[]);(0,v.useEffect)(()=>{let e=oe.current?.closest(`[data-slot="scroll-area-viewport"]`);if(!e)return;let t=()=>{se.current=e.scrollHeight-e.scrollTop-e.clientHeight<80};return e.addEventListener(`scroll`,t),()=>e.removeEventListener(`scroll`,t)},[]),(0,v.useEffect)(()=>{se.current&&ce()},[M,I,R,ce]);let le=()=>{ot(`/api/workbench?agent_id=${e}&draft=1`).then(e=>{n(e.dsl),i(e.isDraft),o(e.versions||[]),c(JSON.stringify(e.dsl,null,2))}),ot(`/api/panels`).then(e=>f(e.plugins||[]))};if((0,v.useEffect)(()=>{le()},[e]),(0,v.useEffect)(()=>{let e=()=>ot(`/api/state`).then(T).catch(()=>{});e();let t=setInterval(e,5e3);return ot(`/api/panels?with_code=1`).then(e=>D(e.plugins||[])),()=>clearInterval(t)},[]),!t)return(0,K.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:`加载工作台 DSL…`});let B=t.panels,V=_===null?null:B[_],H=e=>{let r=JSON.parse(JSON.stringify(t));e(r),n(r),c(JSON.stringify(r,null,2)),i(!0)},ue=(e,t)=>H(n=>{let r=n.panels[e].grid||{x:1,y:1,w:6,h:1};n.panels[e].grid={...r,...t}}),de=t=>({devices:w?.devices||[],alarms:w?.alarms||[],kpi:w?.kpi||{},work_orders:w?.work_orders||[],inspections:w?.inspections||{},selected:O,onSelect:k,agentId:e,store:mt(e),runAction:(n,r)=>ht(e,String(t.id),n,r),params:{...t.params||{},agentId:e,wsId:`default`}}),fe=e=>e.type===`custom`?e.code:E.find(t=>t.id===e.panel)?.code||``,pe=()=>H(e=>e.panels.push({id:`block_${Math.random().toString(36).slice(2,6)}`,type:`placeholder`,title:`空区块`,grid:NO(e.panels)})),me=(e,t)=>{H(n=>{if(e!==null&&e<n.panels.length){let r=n.panels[e];Object.assign(r,{type:`custom_panel`,panel:t.id,title:r.title===`空区块`?t.name:r.title})}else n.panels.push({id:`plug_${t.id}_${Math.random().toString(36).slice(2,5)}`,type:`custom_panel`,title:t.name,panel:t.id,grid:NO(n.panels)})}),m(!1),g(null),Z.success(`已插入「${t.name}」(草稿,待发布)`)},he=async e=>{let t=B[e];z(e);let n=``;try{let e=t.panel||t.id,r=await ot(`/api/panel-errors?key=${encodeURIComponent(e)}`);n=r.errors?.length?r.errors.map(e=>`[${e.kind}] ${e.message}`).join(` | `):``}catch{}F(`请调试该插件:${n?`最近运行错误:${n}。`:`暂无上报错误,请先 read_panel_plugin 审代码,重点检查结果处理与错误路径。`}请定位根因、修复并说明验证方式。`),Z.info(`已锁定调试目标并带上错误上下文,发送即开始`)},ge=async(e,t)=>{try{let n=await st(`/api/panels/rollback`,{id:e,version:t});Z.success(`已回退到 ${t}(新版本号 ${n.plugin.version},引用即时生效)`),le()}catch(e){Z.error(String(e.message))}},_e=()=>{if(te===null||!B[te])return``;let e=B[te],t=e.grid||{x:1,y:1,w:6,h:1},n=Math.round(t.w/12*100),r=t.w<=3?`窄条(紧凑单列列表/迷你卡)`:t.w>=9?`宽区块(表格/多列仪表)`:`中等宽度(两列卡/紧凑表)`;return`【定制目标】区块「${e.title}」(id=${e.id}):第${t.x}列起、跨${t.w}列(约${n}%宽)、跨${t.h}行(${r})。${e.panel?`当前引用插件 ${e.panel}——先 read_panel_plugin 再决定改造还是重写。`:`空区块,可新建插件。`}`},ve=e=>{z(e),F(``),Z.info(`已锁定定制目标「${B[e].title}」——在右侧描述需求即可`)},ye=async()=>{u(!0);try{let r=await ct(`/api/workbench`,{agent_id:e,dsl:t});n(r.dsl),o(r.versions),c(JSON.stringify(r.dsl,null,2)),i(!1),re(!1),Z.success(`已发布 ${r.dsl.version},工作台即时生效`)}catch(e){Z.error(String(e.message))}finally{u(!1)}},be=async()=>{await lt(`/api/workbench/draft`,{agent_id:e}),Z.success(`已放弃草稿`),le()},xe=async t=>{try{let r=await st(`/api/workbench/rollback`,{agent_id:e,version:t});n(r.dsl),o(r.versions),c(JSON.stringify(r.dsl,null,2)),i(!1),Z.success(`已回滚到 ${t}`)}catch(e){Z.error(String(e.message))}},U=()=>{j.current?.abort()},Se=async()=>{if(I)Z.info(`对话进行中,请先停止再清空`);else if(window.confirm(`清空二开助手的会话历史?服务端上下文将被丢弃并从零开始;已生成的草稿与插件不受影响。`))try{await st(`/api/session/reset`,{scope:`dev`,sessionId:A}),N([]),ee(``),Z.success(`会话已清空`)}catch(e){Z.error(String(e.message))}},Ce=async()=>{let t=P.trim();if(!t||I)return;let n=_e()?`${_e()}\n需求:${t}`:t;F(``),L(!0),re(!1),se.current=!0,N(e=>[...e,{role:`user`,text:t}]);let r=!1,i=!1,a=new AbortController;j.current=a;try{await ut(`/api/dev/chat`,{sessionId:A,agentId:e,message:n},e=>{let t=e.type;t===`status`?ee(String(e.text||``)):t===`text_delta`?(i=!0,ee(``),N(t=>{let n=t[t.length-1];return n?.role===`agent`&&n.streaming?[...t.slice(0,-1),{...n,text:n.text+String(e.delta)}]:[...t,{role:`agent`,text:String(e.delta),streaming:!0}]})):t===`done`?!i&&!r&&N(e=>[...e,{role:`agent`,text:`(模型返回了空回复——请重试;若持续出现请到「系统设置」检查模型配置)`}]):t===`tool_start`?(r=!0,N(t=>[...t,{role:`agent`,text:``,streaming:!1,events:[{tool:String(e.tool),args:e.args||{}}]}])):t===`tool_end`?N(t=>{for(let n=t.length-1;n>=0;n--){let r=t[n];if(r.role===`agent`&&r.events){for(let n=r.events.length-1;n>=0;n--)if(r.events[n].tool===e.tool&&r.events[n].result===void 0)return r.events[n].result=String(e.result||``),r.events[n].ok=e.ok!==!1,[...t]}}return t}):t===`interrupted`?(ee(``),N(e=>[...e,{role:`agent`,text:`(已中断)`}])):t===`meta`?e.hasDraft?(re(!0),le()):r&&le():t===`error`&&Z.error(String(e.message))},a.signal)}catch(e){a.signal.aborted?N(e=>[...e,{role:`agent`,text:`(已中断)`}]):N(t=>[...t,{role:`agent`,text:`❌ ${String(e.message)}`}])}finally{ee(``),L(!1),j.current===a&&(j.current=null)}};return(0,K.jsxs)(`div`,{className:`flex h-full flex-col gap-3 overflow-hidden p-5`,children:[(0,K.jsxs)(`div`,{className:`flex shrink-0 items-end justify-between`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h1`,{className:`text-lg font-bold`,children:`定制工作台`}),(0,K.jsx)(`p`,{className:`mt-0.5 text-xs text-muted-foreground`,children:`区块你规划 · 插件按区块占比定制 · 一切修改走草稿审阅发布`})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(J,{variant:`secondary`,children:r?`草稿(未发布)`:`线上 ${t.version}`}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,onClick:()=>{g(null),m(!0)},children:[(0,K.jsx)(pg,{className:`mr-1 h-3.5 w-3.5`}),`插件库`]}),(0,K.jsxs)(Y,{size:`sm`,variant:`outline`,title:`把当前工作台(含依赖插件/数据集 schema/交互脚本)发布为 ARM UI 资产`,onClick:()=>ae({type:`workbench`,agentId:e,title:t.workbench}),children:[(0,K.jsx)(_h,{className:`mr-1 h-3.5 w-3.5 text-violet-400`}),`导出资产`]}),(0,K.jsxs)(Y,{size:`sm`,disabled:l||!r,onClick:ye,children:[(0,K.jsx)(yg,{className:`mr-1 h-3.5 w-3.5`}),l?`发布中…`:`审阅后发布`]})]})]}),r&&(0,K.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2 rounded-md border border-amber-500/50 bg-amber-500/10 px-3 py-2 text-xs text-amber-300`,children:[(0,K.jsx)(`span`,{children:`⚠`}),`草稿未发布——审阅后发布生效,或`,(0,K.jsx)(`button`,{className:`underline underline-offset-2`,onClick:be,children:`放弃草稿`})]}),(0,K.jsxs)(`div`,{className:`grid min-h-0 flex-1 grid-cols-[1fr_380px] gap-4`,children:[(0,K.jsx)(`div`,{className:`flex min-h-0 flex-col`,children:(0,K.jsxs)(vO,{defaultValue:`canvas`,className:`flex min-h-0 flex-1 flex-col`,children:[(0,K.jsxs)(bO,{className:`shrink-0`,children:[(0,K.jsxs)(xO,{value:`canvas`,className:`text-xs`,children:[(0,K.jsx)(Yh,{className:`mr-1 h-3.5 w-3.5`}),`布局画布`]}),(0,K.jsx)(xO,{value:`json`,className:`text-xs`,children:`JSON`})]}),(0,K.jsxs)(SO,{value:`canvas`,className:`mt-2 flex min-h-0 flex-1 flex-col gap-2`,children:[(0,K.jsxs)(`div`,{className:`flex shrink-0 flex-nowrap items-center gap-1.5 overflow-x-auto rounded-md border bg-card p-2`,children:[(0,K.jsxs)(Y,{size:`sm`,variant:`secondary`,className:`h-7 shrink-0 text-xs`,onClick:pe,children:[(0,K.jsx)(dg,{className:`mr-1 h-3 w-3`}),`添加区块`]}),(0,K.jsx)(_O,{orientation:`vertical`,className:`mx-1 h-5 shrink-0`}),V?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(`span`,{className:`max-w-28 shrink-0 truncate text-[11px] text-muted-foreground`,title:V.title,children:[`「`,V.title,`」`]}),(0,K.jsx)(`span`,{className:`shrink-0 text-[11px]`,children:`列`}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`左移一列`,onClick:()=>ue(_,{x:Math.max(1,(V.grid?.x||1)-1)}),children:(0,K.jsx)(qm,{className:`h-3 w-3`})}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`右移一列`,onClick:()=>ue(_,{x:Math.min(12,(V.grid?.x||1)+1)}),children:(0,K.jsx)(Ym,{className:`h-3 w-3`})}),(0,K.jsx)(`span`,{className:`shrink-0 text-[11px]`,children:`跨列`}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`跨列减一`,onClick:()=>ue(_,{w:Math.max(1,(V.grid?.w||6)-1)}),children:`−`}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`跨列加一`,onClick:()=>ue(_,{w:Math.min(12,(V.grid?.w||6)+1)}),children:`+`}),(0,K.jsx)(`span`,{className:`shrink-0 text-[11px]`,children:`跨行`}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`跨行减一`,onClick:()=>ue(_,{h:Math.max(1,(V.grid?.h||1)-1)}),children:(0,K.jsx)(Zm,{className:`h-3 w-3`})}),(0,K.jsx)(Y,{size:`icon`,variant:`ghost`,className:`h-7 w-7 shrink-0`,title:`跨行加一`,onClick:()=>ue(_,{h:Math.min(8,(V.grid?.h||1)+1)}),children:(0,K.jsx)(Gm,{className:`h-3 w-3`})}),(0,K.jsxs)(Y,{size:`sm`,variant:`ghost`,className:`h-7 shrink-0 text-xs text-primary`,onClick:()=>ve(_),children:[(0,K.jsx)(th,{className:`mr-1 h-3 w-3`}),`AI 定制`]}),(0,K.jsxs)(CO,{children:[(0,K.jsx)(wO,{asChild:!0,children:(0,K.jsxs)(Y,{size:`sm`,variant:`ghost`,className:`h-7 shrink-0 text-xs`,children:[(0,K.jsx)(Th,{className:`h-3 w-3`}),`更多`]})}),(0,K.jsxs)(TO,{align:`end`,children:[(V.type===`custom`||V.type===`custom_panel`)&&(0,K.jsxs)(EO,{className:`text-amber-400 focus:text-amber-300`,onClick:()=>he(_),children:[(0,K.jsx)(t_,{}),`AI 调试`]}),(0,K.jsxs)(EO,{onClick:()=>ue(_,{x:1,w:12}),children:[(0,K.jsx)(Ug,{className:`text-muted-foreground`}),`占满宽度`]}),(0,K.jsxs)(EO,{onClick:()=>{let e=B.reduce((e,t)=>Math.max(e,(t.grid?.y||1)+(t.grid?.h||1)-1),1);ue(_,{h:Math.max(1,e-(V.grid?.y||1)+1)})},children:[(0,K.jsx)(Gg,{className:`text-muted-foreground`}),`延到底部`]}),(0,K.jsxs)(EO,{onClick:()=>ue(_,{x:1}),children:[(0,K.jsx)(Um,{className:`text-muted-foreground`}),`贴左`]}),(0,K.jsxs)(EO,{onClick:()=>ue(_,{x:12-(V.grid?.w||6)+1}),children:[(0,K.jsx)(Vm,{className:`text-muted-foreground`}),`贴右`]}),(0,K.jsx)(DO,{}),(0,K.jsxs)(EO,{onClick:()=>{g(_),m(!0)},children:[(0,K.jsx)(pg,{className:`text-muted-foreground`}),`换插件`]}),(0,K.jsxs)(EO,{onClick:()=>{C(_),x(!0)},children:[(0,K.jsx)(Dg,{className:`text-muted-foreground`}),`面板设置`]}),(0,K.jsxs)(EO,{className:`text-red-400 focus:text-red-300`,onClick:()=>{H(e=>e.panels.splice(_,1)),y(null)},children:[(0,K.jsx)(qg,{}),`删除区块`]})]})]})]}):(0,K.jsx)(`span`,{className:`shrink-0 text-[11px] text-muted-foreground`,children:`点击画布中的区块进行编辑`})]}),(0,K.jsx)(`div`,{className:`shrink-0`,children:(0,K.jsx)(mO,{})}),(0,K.jsx)(`div`,{className:`relative min-h-0 flex-1 overflow-hidden rounded-lg border bg-muted/20 p-2`,children:(0,K.jsx)(pO,{className:`absolute inset-0 overflow-auto`,dsl:t,edit:{sel:_,onSelect:y,onGrid:(e,t)=>ue(e,t)},renderPanel:t=>{let n=fe(t);return n?(0,K.jsx)(dO,{code:n,data:de(t),meta:{agentId:e,panelId:t.id,pluginId:t.panel}}):(0,K.jsx)(`div`,{className:`p-3 text-[11px] text-muted-foreground`,children:`(插件代码加载中…)`})},renderDialog:()=>(0,K.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-1 text-[11px] text-muted-foreground`,children:[(0,K.jsx)(th,{className:`h-5 w-5 text-primary`}),`诊断对话(内核)`,(0,K.jsx)(`span`,{className:`text-[10px]`,children:`发布后在工作台可交互`})]}),renderPlaceholder:()=>(0,K.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-1 text-[11px] text-muted-foreground`,children:[(0,K.jsx)(dg,{className:`h-4 w-4`}),`空区块`,(0,K.jsx)(`span`,{className:`text-[10px]`,children:`选中后「换插件」或「AI 定制」`})]})})}),(0,K.jsx)(`p`,{className:`shrink-0 text-[10px] text-muted-foreground`,children:`所见即所得(比例一致):画布 = 缩小的可视区,行高为可视区等分——跨 n 行即占 n/总行数,与实际浏览时任何屏幕尺寸下的比例完全一致;内容超高时面板内部滚动。拖拽移动(吸附网格)· 手柄调跨列跨行 · 右上角显示占比。`})]}),(0,K.jsxs)(SO,{value:`json`,className:`mt-2 flex min-h-0 flex-1 flex-col gap-2`,children:[(0,K.jsx)(`textarea`,{value:s,onChange:e=>c(e.target.value),spellCheck:!1,className:`min-h-0 w-full flex-1 resize-none rounded-md border bg-muted p-3 font-mono text-[11px] leading-relaxed`}),(0,K.jsxs)(`div`,{className:`flex shrink-0 gap-2`,children:[(0,K.jsx)(Y,{size:`sm`,onClick:()=>{try{let e=JSON.parse(s);if(!e.panels)throw Error(`缺少 panels`);n(e),i(!0),Z.success(`JSON 已应用(未发布)`)}catch(e){Z.error(`JSON 解析失败: ${e.message}`)}},children:`应用 JSON`}),(0,K.jsx)(Y,{size:`sm`,variant:`outline`,onClick:()=>c(JSON.stringify(t,null,2)),children:`从画布刷新`})]})]})]})}),(0,K.jsxs)(`div`,{className:`flex min-h-0 flex-col gap-4`,children:[(0,K.jsx)(bm,{className:`flex min-h-0 flex-1 flex-col py-0`,children:(0,K.jsxs)(Cm,{className:`flex min-h-0 flex-1 flex-col p-0`,children:[(0,K.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1.5 border-b px-3 py-2 text-xs font-semibold`,children:[(0,K.jsx)(Lg,{className:`h-3.5 w-3.5 text-primary`}),`二开助手`,(0,K.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:`· 描述需求,直接定制区块`}),(0,K.jsx)(`button`,{className:`ml-auto shrink-0 rounded p-0.5 text-muted-foreground hover:text-foreground disabled:opacity-40`,title:`清空会话(丢弃服务端上下文,从零开始)`,disabled:I,onClick:Se,children:(0,K.jsx)(qg,{className:`h-3.5 w-3.5`})})]}),te!==null&&B[te]&&(()=>{let e=B[te],t=e.grid||{x:1,y:1,w:6,h:1},n=Math.round(t.w/12*100);return(0,K.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1.5 border-b bg-primary/5 px-3 py-1.5 text-[11px]`,children:[(0,K.jsx)(yh,{className:`h-3.5 w-3.5 shrink-0 text-primary`}),(0,K.jsxs)(`span`,{className:`min-w-0 truncate`,children:[`定制目标:`,(0,K.jsx)(`b`,{children:e.title}),` · `,n,`% 宽 · `,t.h,` 行`,e.panel?(0,K.jsxs)(K.Fragment,{children:[` · `,(0,K.jsx)(`span`,{className:`font-mono`,children:e.panel})]}):` · 空区块`]}),(0,K.jsx)(`button`,{className:`ml-auto shrink-0 rounded p-0.5 text-muted-foreground hover:text-foreground`,title:`取消目标,改为自由描述`,onClick:()=>z(null),children:`×`})]})})(),ne&&r&&(0,K.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1.5 border-b bg-emerald-500/10 px-3 py-1.5 text-[11px] text-emerald-400`,children:[(0,K.jsx)(ph,{className:`h-3.5 w-3.5 shrink-0`}),`草稿已生成——到顶部「审阅后发布」生效`]}),(0,K.jsx)(eO,{className:`min-h-0 flex-1`,children:(0,K.jsxs)(`div`,{className:`space-y-2.5 p-3`,ref:oe,children:[M.length===0&&(0,K.jsx)(`div`,{className:`space-y-2`,children:(0,K.jsxs)(`div`,{className:`rounded-md border border-dashed border-primary/30 bg-primary/5 p-3 text-[11px] leading-relaxed`,children:[(0,K.jsx)(`div`,{className:`mb-1 text-xs font-semibold text-primary`,children:`✨ 两种玩法`}),(0,K.jsxs)(`div`,{children:[`① 画布选中区块 → 工具条「`,(0,K.jsx)(`b`,{children:`AI 定制`}),`」→ 目标钉在上方,只管补需求`]}),(0,K.jsx)(`div`,{children:`② 直接描述需求,助手自动建区块进草稿`}),(0,K.jsx)(`div`,{className:`mt-1.5 flex flex-wrap gap-1.5`,children:[[`窄条:最近告警`,`新建一个窄条区块(跨3列):最近活动告警列表,高级别标红,点击可选中设备`],[`横条:KPI 摘要`,`新建一个单行横条区块:关键指标摘要读数(props.kpi),异常着色`],[`宽表:设备台账`,`新建一个宽区块(跨9列以上):设备台账表格,显示全部字段,支持点击选中`]].map(([e,t])=>(0,K.jsx)(`button`,{onClick:()=>F(t),className:`rounded-full border px-2.5 py-1 text-[11px] text-muted-foreground transition-colors hover:border-primary/60 hover:text-primary`,children:e},e))})]})}),M.map((e,t)=>(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`div`,{className:e.role===`user`?`ml-auto max-w-[90%] rounded-lg bg-primary/20 px-2.5 py-1.5 text-xs break-words whitespace-pre-wrap`:`max-w-full rounded-lg bg-card px-2.5 py-1.5 text-xs leading-relaxed break-words whitespace-pre-wrap`,children:e.text}),(e.events||[]).map((e,t)=>(0,K.jsxs)(`div`,{className:`mt-1 min-w-0 rounded-md border border-dashed px-2 py-1 text-[10px]`,children:[(0,K.jsx)(`span`,{children:e.ok===!1?`❌`:`🛠`}),` `,(0,K.jsx)(`span`,{className:`font-mono font-semibold`,children:e.tool}),(0,K.jsx)(`pre`,{className:`mt-0.5 max-h-32 overflow-auto whitespace-pre-wrap break-all text-muted-foreground`,children:String(e.result||``).slice(0,260)})]},t))]},t)),(I||R)&&(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 px-1 text-[11px] text-muted-foreground`,children:[(0,K.jsx)(`span`,{className:`h-1.5 w-1.5 animate-pulse rounded-full bg-primary`}),R||`开发中…`]})]})}),(0,K.jsxs)(`div`,{className:`shrink-0 space-y-1 border-t p-2`,children:[(0,K.jsx)(`textarea`,{value:P,onChange:e=>F(e.target.value),rows:2,onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&!e.nativeEvent.isComposing&&(e.preventDefault(),Ce())},placeholder:te===null?`描述需求,如「左上窄条做一个最近工单列表」(Enter 发送)…`:`描述对「${B[te]?.title}」的需求(Enter 发送,Shift+Enter 换行)…`,className:`min-h-[56px] w-full resize-none rounded-md border bg-background px-2 py-1.5 text-xs`}),(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:te===null?`未锁定目标——助手会自动规划区块位置`:`目标上下文(位置/几何/插件)发送时自动携带`}),I?(0,K.jsxs)(Y,{size:`sm`,variant:`destructive`,className:`h-7 gap-1 text-xs`,onClick:U,children:[(0,K.jsx)(Vg,{className:`h-3 w-3`}),`停止`]}):(0,K.jsxs)(Y,{size:`sm`,className:`h-7 gap-1 text-xs`,disabled:!P.trim(),onClick:Ce,children:[(0,K.jsx)(Cg,{className:`h-3 w-3`}),`发送`]})]})]})]})}),(0,K.jsx)(bm,{className:`shrink-0 py-0`,children:(0,K.jsxs)(Cm,{className:`p-0`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 border-b px-3 py-2 text-xs font-semibold`,children:[(0,K.jsx)(_g,{className:`h-3.5 w-3.5`}),`版本历史`]}),(0,K.jsx)(`div`,{className:`max-h-40 overflow-y-auto`,children:(0,K.jsxs)(`div`,{className:`divide-y`,children:[a.length===0&&(0,K.jsx)(`div`,{className:`p-3 text-center text-xs text-muted-foreground`,children:`暂无历史`}),[...a].reverse().map((e,t)=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-1.5 text-xs`,children:[(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsx)(`span`,{className:`font-mono font-semibold`,children:e.version}),t===0&&!r&&(0,K.jsx)(J,{className:`ml-1 h-4 px-1 text-[9px]`,children:`线上`}),(0,K.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,children:gt(e.at,`dts`)})]}),t!==0&&(0,K.jsx)(Y,{size:`sm`,variant:`ghost`,className:`h-6 text-[10px]`,onClick:()=>xe(e.version),children:`回滚`})]},`${e.version}-${e.at}`))]})})]})})]})]}),(0,K.jsx)(a_,{open:b,onOpenChange:x,children:(0,K.jsxs)(c_,{className:`max-w-md`,children:[(0,K.jsx)(l_,{children:(0,K.jsxs)(d_,{children:[`区块设置 · `,B[S]?.title]})}),(0,K.jsxs)(`div`,{className:`space-y-2`,children:[(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`标题`}),(0,K.jsx)(p_,{defaultValue:B[S]?.title||``,className:`text-xs`,onBlur:e=>H(t=>{t.panels[S].title=e.target.value})})]}),B[S]?.type===`custom`&&(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`内联代码(契约:function Panel(props))`}),(0,K.jsx)(`textarea`,{defaultValue:B[S]?.code||``,spellCheck:!1,onBlur:e=>H(t=>{t.panels[S].code=e.target.value}),className:`h-40 w-full rounded-md border bg-muted p-2 font-mono text-[10px]`})]}),B[S]?.type===`custom_panel`&&(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`插件版本(可回退,回退即时生效)`}),(0,K.jsx)(MO,{pluginId:String(B[S]?.panel||``),onRollback:ge})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsx)(m_,{className:`text-xs`,children:`params(插件经 props.params 读取)`}),(0,K.jsx)(`textarea`,{defaultValue:JSON.stringify(B[S]?.params||{},null,1),spellCheck:!1,onBlur:e=>{try{H(t=>{t.panels[S].params=JSON.parse(e.target.value||`{}`)})}catch{Z.error(`params JSON 无效`)}},className:`h-20 w-full rounded-md border bg-muted p-2 font-mono text-[10px]`})]})]}),(0,K.jsx)(u_,{children:(0,K.jsx)(Y,{onClick:()=>x(!1),children:`完成`})})]})}),(0,K.jsx)(a_,{open:p,onOpenChange:e=>{m(e),e||g(null)},children:(0,K.jsxs)(c_,{children:[(0,K.jsx)(l_,{children:(0,K.jsxs)(d_,{className:`flex items-center gap-1.5`,children:[(0,K.jsx)(pg,{className:`h-4 w-4`}),`插件库`,h===null?``:` · 插入到选中区块`]})}),(0,K.jsx)(`div`,{className:`max-h-72 overflow-y-auto`,children:(0,K.jsx)(`div`,{className:`space-y-1.5`,children:d.filter(e=>e.status!==`deprecated`).map(e=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border p-2.5`,children:[(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5 text-xs font-medium`,children:[(0,K.jsx)(`span`,{className:`min-w-0 truncate`,title:e.name,children:e.name}),(0,K.jsx)(J,{variant:`secondary`,className:`h-4 shrink-0 px-1 text-[9px]`,children:e.version}),(0,K.jsx)(J,{variant:`outline`,className:`h-4 shrink-0 px-1 text-[9px]`,children:e.author===`system`?`范本`:e.author===`ai`?`AI`:`人工`})]}),(0,K.jsx)(`div`,{className:`truncate text-[10px] text-muted-foreground`,children:e.description||e.id})]}),(0,K.jsx)(Y,{size:`sm`,variant:`secondary`,className:`h-7 shrink-0 text-[11px]`,onClick:()=>me(h,e),children:`插入`})]},e.id))})}),(0,K.jsxs)(u_,{children:[(0,K.jsx)(Y,{variant:`outline`,size:`sm`,onClick:pe,children:`先加空区块`}),(0,K.jsx)(Y,{variant:`outline`,onClick:()=>m(!1),children:`关闭`})]})]})}),(0,K.jsx)(kO,{target:ie,onClose:()=>ae(null),agents:[{agent_id:e,name:t.workbench||`当前助手`}]}),(0,K.jsx)(`p`,{className:`shrink-0 text-center text-[11px] text-muted-foreground`,children:`区块几何 = 插件设计输入:宽≤3 列紧凑列表、≥9 列表格/仪表 · AI 定制锁定目标、上下文自动携带 · 草稿审阅发布。`})]})}var FO=[{key:`tool_calls`,label:`工具调用`,icon:(0,K.jsx)(t_,{className:`h-3.5 w-3.5`}),tone:`text-sky-400`},{key:`guardrail_blocks`,label:`守护栏拦截`,icon:(0,K.jsx)(jg,{className:`h-3.5 w-3.5`}),tone:`text-red-400`},{key:`human_confirms`,label:`人工确认执行`,icon:(0,K.jsx)(zm,{className:`h-3.5 w-3.5`}),tone:`text-amber-400`},{key:`orchestrations`,label:`编排执行`,icon:(0,K.jsx)(Lg,{className:`h-3.5 w-3.5`}),tone:`text-violet-400`},{key:`experiences`,label:`经验回流`,icon:(0,K.jsx)($m,{className:`h-3.5 w-3.5`}),tone:`text-emerald-400`},{key:`kb_searches`,label:`知识检索`,icon:(0,K.jsx)(xg,{className:`h-3.5 w-3.5`}),tone:`text-cyan-400`},{key:`ai_drafts`,label:`AI 起草`,icon:(0,K.jsx)(Yg,{className:`h-3.5 w-3.5`}),tone:`text-pink-400`}];function IO(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(``),[i,a]=(0,v.useState)(null),[o,s]=(0,v.useState)(!1),c=()=>ot(`/api/evolution`).then(t);(0,v.useEffect)(()=>{c();let e=setInterval(c,1e4);return()=>clearInterval(e)},[]);let l=async()=>{if(n.trim()){s(!0);try{let e=await ot(`/api/kb/search?q=${encodeURIComponent(n)}`);a(e.items),c()}finally{s(!1)}}};return e?(0,K.jsxs)(`div`,{className:`h-full overflow-auto p-5`,children:[(0,K.jsxs)(`div`,{className:`mb-4`,children:[(0,K.jsxs)(`h1`,{className:`flex items-center gap-2 text-lg font-bold`,children:[(0,K.jsx)(Yg,{className:`h-5 w-5 text-primary`}),`自进化看板`]}),(0,K.jsxs)(`p`,{className:`mt-0.5 text-xs text-muted-foreground`,children:[e.flywheel_note,` · 数据来自审计日志与指标流的实时聚合`]})]}),(0,K.jsx)(`div`,{className:`grid grid-cols-4 gap-3 xl:grid-cols-7`,children:FO.map(t=>(0,K.jsx)(bm,{className:`py-3`,children:(0,K.jsxs)(Cm,{className:`px-3`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[11px] text-muted-foreground`,children:[t.icon,t.label]}),(0,K.jsx)(`div`,{className:`mt-1 text-xl font-bold ${t.tone}`,children:e.totals[t.key]??0})]})},t.key))}),(0,K.jsxs)(`div`,{className:`mt-4 grid grid-cols-2 gap-4`,children:[(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsx)(Sm,{className:`text-xs text-muted-foreground`,children:`飞轮证据 · 检索相似度趋势(回流前后对比)`})}),(0,K.jsx)(Cm,{className:`p-0`,children:(0,K.jsx)(eO,{className:`h-64`,children:(0,K.jsxs)(`div`,{className:`space-y-1.5 p-3`,children:[e.similarity_trend.length===0&&(0,K.jsx)(`div`,{className:`py-8 text-center text-xs text-muted-foreground`,children:`尚无检索记录`}),e.similarity_trend.map((e,t)=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 text-xs`,children:[(0,K.jsx)(`span`,{className:`w-40 shrink-0 truncate text-muted-foreground`,title:e.query,children:e.query}),(0,K.jsx)(`div`,{className:`h-2 flex-1 overflow-hidden rounded bg-muted`,children:(0,K.jsx)(`div`,{className:`h-full rounded ${e.similarity>=75?`bg-emerald-500`:e.similarity>=55?`bg-amber-500`:`bg-slate-500`}`,style:{width:`${e.similarity}%`}})}),(0,K.jsxs)(`span`,{className:`w-9 text-right font-mono ${e.similarity>=75?`text-emerald-400`:`text-muted-foreground`}`,children:[e.similarity,`%`]})]},t))]})})})]}),(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsxs)(Sm,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,K.jsx)($m,{className:`h-3.5 w-3.5`}),`经验沉淀(写入 ARM 知识库)`]})}),(0,K.jsx)(Cm,{className:`p-0`,children:(0,K.jsx)(eO,{className:`h-64`,children:(0,K.jsxs)(`div`,{className:`divide-y`,children:[e.experiences.length===0&&(0,K.jsx)(`div`,{className:`p-8 text-center text-xs text-muted-foreground`,children:`尚无回流记录`}),e.experiences.map((e,t)=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-2 text-xs`,children:[(0,K.jsx)(kh,{className:`h-3 w-3 shrink-0 text-emerald-400`}),(0,K.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,title:e.title,children:e.title}),(0,K.jsx)(`span`,{className:`shrink-0 font-mono text-[10px] text-muted-foreground`,children:e.knowledge_id?e.knowledge_id.slice(0,8):`—`}),(0,K.jsx)(`span`,{className:`shrink-0 text-[10px] text-muted-foreground`,children:gt(e.ts)})]},t))]})})})]})]}),(0,K.jsxs)(`div`,{className:`mt-4 grid grid-cols-3 gap-4`,children:[(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsx)(Sm,{className:`text-xs text-muted-foreground`,children:`工具调用分布`})}),(0,K.jsxs)(Cm,{className:`p-3`,children:[Object.keys(e.by_tool).length===0&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:`暂无数据`}),Object.entries(e.by_tool).sort((e,t)=>t[1]-e[1]).map(([t,n])=>{let r=Math.max(...Object.values(e.by_tool));return(0,K.jsxs)(`div`,{className:`mb-1.5 flex items-center gap-2 text-xs`,children:[(0,K.jsx)(`span`,{className:`w-36 shrink-0 truncate font-mono`,children:t}),(0,K.jsx)(`div`,{className:`h-2 flex-1 overflow-hidden rounded bg-muted`,children:(0,K.jsx)(`div`,{className:`h-full rounded bg-sky-500`,style:{width:`${n/r*100}%`}})}),(0,K.jsx)(`span`,{className:`w-6 text-right font-mono`,children:n})]},t)})]})]}),(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsxs)(Sm,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,K.jsx)(xh,{className:`h-3.5 w-3.5`}),`ARM 知识库实检(真实 RAG)`]})}),(0,K.jsxs)(Cm,{className:`p-3`,children:[(0,K.jsxs)(`div`,{className:`flex gap-2`,children:[(0,K.jsx)(p_,{value:n,onChange:e=>r(e.target.value),onKeyDown:e=>e.key===`Enter`&&l(),placeholder:`如:堆垛机 货叉定位偏移`,className:`text-xs`}),(0,K.jsx)(Y,{size:`sm`,disabled:o,onClick:l,children:o?`检索中`:`检索`})]}),(0,K.jsx)(eO,{className:`mt-2 h-44`,children:(0,K.jsxs)(`div`,{className:`space-y-1.5`,children:[!i&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:`输入问题检索企业经验库(与助手使用同一数据源)`}),i?.length===0&&(0,K.jsx)(`div`,{className:`py-6 text-center text-xs text-muted-foreground`,children:`无命中`}),i?.map((e,t)=>(0,K.jsxs)(`div`,{className:`rounded-md bg-card px-2.5 py-1.5`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs`,children:[e.similarity!=null&&(0,K.jsxs)(J,{variant:`secondary`,className:`h-4 text-[9px] ${e.similarity>=75?`text-emerald-400`:``}`,children:[e.similarity,`%`]}),(0,K.jsx)(`span`,{className:`truncate font-medium`,children:e.title})]}),(0,K.jsx)(`p`,{className:`mt-0.5 line-clamp-2 text-[10px] leading-relaxed text-muted-foreground`,children:e.snippet})]},t))]})})]})]}),(0,K.jsxs)(bm,{className:`py-0`,children:[(0,K.jsx)(xm,{className:`border-b py-2.5`,children:(0,K.jsx)(Sm,{className:`text-xs text-muted-foreground`,children:`审计流(实时)`})}),(0,K.jsx)(Cm,{className:`p-0`,children:(0,K.jsx)(eO,{className:`h-52`,children:(0,K.jsx)(`div`,{className:`divide-y font-mono text-[10px]`,children:e.recent_audit.map((e,t)=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-1.5`,children:[(0,K.jsx)(`span`,{className:`text-muted-foreground`,children:gt(e.ts,`t`)}),(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.actor}),(0,K.jsx)(`span`,{className:`truncate`,children:e.tool||e.logic||e.action||e.name||e.verdict||``})]},t))})})})]})]})]}):(0,K.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:`进化数据加载中…`})}function LO({className:e,size:t=`default`,...n}){return(0,K.jsx)(qp,{"data-slot":`switch`,"data-size":t,className:mn(`peer group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80`,e),...n,children:(0,K.jsx)(Yp,{"data-slot":`switch-thumb`,className:mn(`pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0 dark:data-[state=checked]:bg-primary-foreground dark:data-[state=unchecked]:bg-foreground`)})})}function RO(){let[e,t]=(0,v.useState)(null),[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(``),[o,s]=(0,v.useState)(``),[c,l]=(0,v.useState)(!1),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(``),[m,h]=(0,v.useState)(``),[g,_]=(0,v.useState)(``),[y,b]=(0,v.useState)(``),[x,S]=(0,v.useState)(!1),[C,w]=(0,v.useState)(null),[T,E]=(0,v.useState)(``),[D,O]=(0,v.useState)(!1),[k,A]=(0,v.useState)(``),[j,M]=(0,v.useState)(!1),[N,P]=(0,v.useState)([]),[F,I]=(0,v.useState)([]),[L,R]=(0,v.useState)(!1),[ee,te]=(0,v.useState)(``),[z,ne]=(0,v.useState)(``),[re,ie]=(0,v.useState)(!1),[ae,oe]=(0,v.useState)(null),se=()=>{ot(`/api/settings`).then(e=>{t(e),a(e.arm.api_base),p(e.llm.model),h(e.llm.base_url_runtime?e.llm.base_url:``),b(e.llm.context_tokens_runtime?String(e.llm.context_tokens):``),E(e.scene.profile),P(e.guard.deny),I(e.guard.ro),R(e.guard.sudo_u_l2)}),ot(`/api/arm/status`).then(r).catch(()=>r(null))};(0,v.useEffect)(()=>{se()},[]);let ce=async()=>{l(!0),d(null);try{let e=await ct(`/api/settings`,{arm_api_base:i.trim(),...o.trim()?{arm_token:o.trim()}:{}});d(e.probe||null),s(``),e.probe?.online?Z.success(`已保存并连通(${e.probe.latency_ms}ms),源切换即时生效`):Z.warning(`已保存,但当前源不可达`,{description:e.note}),se()}catch(e){Z.error(String(e.message))}finally{l(!1)}},le=async()=>{S(!0),w(null);try{let e=await ct(`/api/settings`,{llm_model:f.trim(),llm_base_url:m.trim(),llm_context_tokens:y.trim(),...g.trim()?{llm_api_key:g.trim()}:{}});_(``),w(e.llm_probe||null),e.llm_probe?.online?Z.success(`模型已切换(探针 ${e.llm_probe.latency_ms}ms:${e.llm_probe.reply||`ok`})`):e.note&&Z.warning(`已保存,但探针未通过`,{description:e.note}),se()}catch(e){Z.error(String(e.message))}finally{S(!1)}},B=async()=>{M(!0);try{if(await ct(`/api/settings`,{access_token:k}),k.trim()){if(!(await fetch(`/api/auth/login`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({token:k.trim()})})).ok)throw Error(`已保存但自动登录失败,刷新后输入令牌进入`);Z.success(`访问令牌已启用(当前浏览器已自动登录)`)}else Z.success(`访问令牌已关闭(恢复开放访问)`);A(``),se()}catch(e){Z.error(String(e.message))}finally{M(!1)}},V=async()=>{O(!0);try{await ct(`/api/settings`,{scene_profile:T}),Z.success(T.trim()?`场景画像已保存,对全部助手即时生效(新对话起)`:`场景画像已清空(不再注入)`),se()}catch(e){Z.error(String(e.message))}finally{O(!1)}},H=async()=>{ie(!0);try{await ct(`/api/settings`,{guard:{deny:N,ro:F,sudo_u_l2:L}}),Z.success(`守护栏已更新(危险规则 ${N.length} 条 · 白名单 ${F.length} 命令),即时生效`),oe(null),se()}catch(e){Z.error(String(e.message))}finally{ie(!1)}};return(0,K.jsxs)(`div`,{className:`h-full overflow-auto p-5`,children:[(0,K.jsxs)(`div`,{className:`mb-4`,children:[(0,K.jsxs)(`h1`,{className:`flex items-center gap-2 text-lg font-bold`,children:[(0,K.jsx)(kg,{className:`h-5 w-5 text-primary`}),`系统设置`]}),(0,K.jsx)(`p`,{className:`mt-0.5 text-xs text-muted-foreground`,children:`平台全局配置 · 修改保存后即时生效(无需重启)· 运行时配置优先于 .env`})]}),(0,K.jsxs)(vO,{defaultValue:`arm`,className:`max-w-2xl`,children:[(0,K.jsxs)(bO,{children:[(0,K.jsxs)(xO,{value:`arm`,className:`text-xs`,children:[(0,K.jsx)(Tg,{className:`mr-1 h-3.5 w-3.5`}),`ARM 源`,n&&(0,K.jsx)(`span`,{className:`ml-1 h-1.5 w-1.5 rounded-full ${n.online?`bg-emerald-500`:`bg-amber-500`}`})]}),(0,K.jsxs)(xO,{value:`llm`,className:`text-xs`,children:[(0,K.jsx)(th,{className:`mr-1 h-3.5 w-3.5`}),`LLM 模型服务`]}),(0,K.jsxs)(xO,{value:`scene`,className:`text-xs`,children:[(0,K.jsx)(Lh,{className:`mr-1 h-3.5 w-3.5`}),`场景画像`,e&&e.scene.length>0&&(0,K.jsx)(`span`,{className:`ml-1 h-1.5 w-1.5 rounded-full bg-emerald-500`})]}),(0,K.jsxs)(xO,{value:`auth`,className:`text-xs`,children:[(0,K.jsx)(tg,{className:`mr-1 h-3.5 w-3.5`}),`访问安全`,e?.auth.enabled&&(0,K.jsx)(`span`,{className:`ml-1 h-1.5 w-1.5 rounded-full bg-emerald-500`})]}),(0,K.jsxs)(xO,{value:`guard`,className:`text-xs`,children:[(0,K.jsx)(Fg,{className:`mr-1 h-3.5 w-3.5`}),`守护栏`,(0,K.jsxs)(`span`,{className:`ml-1 text-[9px] text-muted-foreground`,children:[N.length,`规`]})]})]}),(0,K.jsx)(SO,{value:`arm`,className:`mt-3`,children:(0,K.jsxs)(bm,{className:`mb-3 max-w-2xl`,children:[(0,K.jsxs)(xm,{className:`pb-2`,children:[(0,K.jsxs)(Sm,{className:`flex items-center gap-2 text-sm`,children:[(0,K.jsx)(Tg,{className:`h-4 w-4 text-primary`}),`ARM 源`,n&&(0,K.jsx)(J,{variant:`outline`,className:`text-[10px] ${n.online?`text-emerald-400`:`text-amber-400`}`,children:n.online?`在线 · ${n.latency_ms}ms`:`不可达(回落本地库)`})]}),(0,K.jsx)(`p`,{className:`text-[11px] leading-relaxed text-muted-foreground`,children:`ARM 是可私有化部署的资源管理系统(助手档案 + 知识库):在此切换源(如 本地开发版 → 客户私有站点), 检索/下载/同步全部即时跟随;助手已下载的本地档案不受影响。`})]}),(0,K.jsxs)(Cm,{className:`space-y-3`,children:[e&&!e.arm.token_set&&e.arm.token_source===`none`&&(0,K.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 p-2.5 text-[11px] leading-relaxed text-amber-300`,children:[(0,K.jsx)(`span`,{className:`shrink-0`,children:`🔑`}),(0,K.jsxs)(`div`,{className:`flex-1`,children:[`尚未配置访问令牌——匿名仅能浏览目录,`,(0,K.jsx)(`b`,{children:`下载 / 上岗 / 新建 / 经验回流`}),`等操作会被 ARM 拒绝(401/403)。 请登录 ARM 站点生成访问令牌(arm_pat_… 开头),粘贴到下方「访问令牌」并保存。`,(0,K.jsx)(`a`,{href:e.arm.api_base,target:`_blank`,rel:`noreferrer`,className:`ml-1 underline underline-offset-2 hover:text-amber-200`,children:`打开 ARM 生成令牌 →`})]})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`flex items-center gap-2 text-xs`,children:[`站点地址(REST API 根地址)`,e&&(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.arm.api_base_runtime?`运行时配置`:`默认(${(e.arm.default_base||``).replace(/^https?:\/\//,``)})`})]}),(0,K.jsx)(p_,{value:i,onChange:e=>a(e.target.value),placeholder:`如 http://localhost:3001 或 https://arm.customer.com`,className:`font-mono text-xs`})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`flex items-center gap-2 text-xs`,children:[`访问令牌(Token)`,e&&(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.arm.token_set?`${e.arm.token_masked} · ${e.arm.token_source}`:`未配置(${e.arm.token_source===`pat`?`回落 ~/.arm PAT`:`匿名/只读`})`})]}),(0,K.jsx)(p_,{type:`password`,value:o,onChange:e=>s(e.target.value),placeholder:e?.arm.token_set?`已配置(留空保持不变)`:`arm_pat_…`,className:`font-mono text-xs`})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(Y,{size:`sm`,className:`text-xs`,disabled:c,onClick:ce,children:c?`保存中…`:`保存并测试连接`}),u&&(0,K.jsx)(`span`,{className:`flex items-center gap-1 text-[11px] ${u.online?`text-emerald-400`:`text-amber-400`}`,children:u.online?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(ph,{className:`h-3.5 w-3.5`}),`连通 `,u.latency_ms,`ms,源已切换`]}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(hh,{className:`h-3.5 w-3.5`}),`不可达:`,u.error]})})]})]})]})}),(0,K.jsx)(SO,{value:`llm`,className:`mt-3`,children:(0,K.jsxs)(bm,{className:`mb-3 max-w-2xl`,children:[(0,K.jsxs)(xm,{className:`pb-2`,children:[(0,K.jsxs)(Sm,{className:`flex items-center gap-2 text-sm`,children:[(0,K.jsx)(th,{className:`h-4 w-4 text-primary`}),`LLM 模型服务`,e&&(0,K.jsx)(J,{variant:`outline`,className:`text-[10px]`,children:e.llm.model})]}),(0,K.jsx)(`p`,{className:`text-[11px] leading-relaxed text-muted-foreground`,children:`OpenAI 兼容端点:缺省公司内网 bifrost 网关(内网开箱可用),可切换模型 / 自建网关 / 公有云端点。保存后新对话即时使用新模型,应用失败自动回滚。`})]}),(0,K.jsxs)(Cm,{className:`space-y-3`,children:[(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`flex items-center gap-2 text-xs`,children:[`模型`,e&&(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.llm.model_runtime?`运行时配置`:`默认(.env)`})]}),(0,K.jsx)(p_,{value:f,onChange:e=>p(e.target.value),list:`llm-catalog`,placeholder:`如 def / glm-5.3 / 自定义名称`,className:`font-mono text-xs`}),(0,K.jsx)(`datalist`,{id:`llm-catalog`,children:(e?.llm.catalog||[]).map(e=>(0,K.jsx)(`option`,{value:e},e))})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`text-xs`,children:[`端点地址(留空 = `,e?.llm.default_base||`默认内网 bifrost`,`)`]}),(0,K.jsx)(p_,{value:m,onChange:e=>h(e.target.value),placeholder:`https://your-gateway/v1(OpenAI 兼容)`,className:`font-mono text-xs`})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`flex items-center gap-2 text-xs`,children:[`API Key`,e&&(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.llm.key_set?`${e.llm.key_masked} · ${e.llm.key_source}`:`未配置`})]}),(0,K.jsx)(p_,{type:`password`,value:g,onChange:e=>_(e.target.value),placeholder:e?.llm.key_set?`已配置(留空保持不变)`:`sk-… / api key`,className:`font-mono text-xs`})]}),(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(m_,{className:`flex items-center gap-2 text-xs`,children:[`上下文窗口(token)`,e&&(0,K.jsx)(J,{variant:`outline`,className:`h-4 px-1 text-[9px]`,children:e.llm.context_tokens_runtime?`运行时配置 ${e.llm.context_tokens}`:`默认 ${e.llm.default_context_tokens}`})]}),(0,K.jsx)(p_,{type:`number`,inputMode:`numeric`,min:4e3,max:2e6,step:1e3,value:y,onChange:e=>b(e.target.value),placeholder:`${e?.llm.default_context_tokens||128e3}(留空 = 默认)`,className:`font-mono text-xs`}),(0,K.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:`按所选模型的真实窗口填写。会话历史超出窗口时自动丢弃最早轮次(保留当前轮),避免长期使用后请求被模型拒绝。`})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(Y,{size:`sm`,className:`text-xs`,disabled:x,onClick:le,children:x?`切换中…`:`保存并测试模型`}),C&&(0,K.jsx)(`span`,{className:`flex items-center gap-1 text-[11px] ${C.online?`text-emerald-400`:`text-amber-400`}`,children:C.online?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(ph,{className:`h-3.5 w-3.5`}),`探针通过 `,C.latency_ms,`ms:`,C.reply]}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(hh,{className:`h-3.5 w-3.5`}),`未通过:`,C.error]})})]})]})]})}),(0,K.jsx)(SO,{value:`scene`,className:`mt-3`,children:(0,K.jsxs)(bm,{className:`mb-3 max-w-2xl`,children:[(0,K.jsxs)(xm,{className:`pb-2`,children:[(0,K.jsxs)(Sm,{className:`flex items-center gap-2 text-sm`,children:[(0,K.jsx)(Lh,{className:`h-4 w-4 text-primary`}),`场景画像`,e&&(0,K.jsx)(J,{variant:`outline`,className:`text-[10px] ${e.scene.length?`text-emerald-400`:``}`,children:e.scene.length?`已启用 · ${e.scene.length} 字`:`未配置(不注入)`})]}),(0,K.jsxs)(`p`,{className:`text-[11px] leading-relaxed text-muted-foreground`,children:[`平台级、全局一份的使用方场景描述(团队环境 / 系统清单 / 规范 / 联系人),作为常驻事实注入`,(0,K.jsx)(`b`,{children:`所有助手`}),`的上下文—— 助手不必每次重新探索环境。与知识检索互补(常驻事实 vs 按需检索)。⚠ 不放凭据:写"凭据在哪、找谁要"即可。`]})]}),(0,K.jsxs)(Cm,{className:`space-y-2`,children:[(0,K.jsx)(`textarea`,{value:T,onChange:e=>E(e.target.value),spellCheck:!1,rows:8,placeholder:`例如:
101
101
  · 团队负责公司内部系统的运维与研发提效
102
102
  · 系统:ARM(助手管理)、Nexus(nexus.aimstek.cn)、Jenkins、玄武环境、WMS
103
103
  · 服务器多为 root/统一密码策略,凭据找张三
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>AIMS 工业智能体平台</title>
8
- <script type="module" crossorigin src="/assets/index-_EVO7WmA.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-CUF2TY1u.css">
8
+ <script type="module" crossorigin src="/assets/index-yKpm2RG4.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-CNak0man.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>