@lob-ox/core-win-x64 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core.cjs CHANGED
@@ -1243,7 +1243,7 @@ var require_version = __commonJS({
1243
1243
  var fs2 = require("node:fs");
1244
1244
  var path2 = require("node:path");
1245
1245
  function guardVersion() {
1246
- if (true) return String("0.0.2");
1246
+ if (true) return String("0.0.3");
1247
1247
  try {
1248
1248
  return JSON.parse(fs2.readFileSync(path2.join(__dirname, "..", "..", "package.json"), "utf8")).version || "unknown";
1249
1249
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lob-ox/core-win-x64",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "DSH lifecycle guard core (Node launcher) for win-x64 — requires Node >=18.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -1,3 +1,3 @@
1
- import{F as e,I as t,L as n,N as r,O as i,R as a,S as o,U as s,V as c,_ as l,a as u,b as d,c as f,g as p,k as m,n as h,o as g,t as _,v,x as y,y as b}from"./supervisor-Dfq_YAmt.js";import{n as x,o as S}from"./openExternal-Ds20EFp9.js";import{n as C,t as w}from"./rocket-Dit4Xpeq.js";import{t as ee}from"./shield-check-D2xvjEfM.js";import{c as T,f as E,o as D,s as te}from"./supervisor-BZTzTZDT.js";import{t as O}from"./useSupervisorAction-DZSdzPif.js";import{c as k,i as A,o as j,r as M,t as N}from"./widgets-M2h3F-43.js";var ne=r(`box`,[[`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`,key:`hh9hay`}],[`path`,{d:`m3.3 7 8.7 5 8.7-5`,key:`g66t2b`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}]]),P=r(`rotate-cw`,[[`path`,{d:`M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8`,key:`1p45f6`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}]]),F=r(`square`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}]]),I=s(c(),1),L=a();function R({onRegisterActions:r}){let{snap:a}=_(),{busy:s,run:c}=O(),R=e(),[z,B]=(0,I.useState)(!1),[V,H]=(0,I.useState)(``),[U,W]=(0,I.useState)(``),[G,K]=(0,I.useState)(``),q=a.instances?.instances??[],[J,Y]=(0,I.useState)(null);(0,I.useEffect)(()=>{let e=!0;return u.envStatus().then(t=>{e&&Y(t.capabilities??null)}).catch(()=>void 0),()=>{e=!1}},[]);let X=J!==null&&J.sandboxLaunch===!1,Z=J?.sandboxEnforcement===`supervise`,Q=J==null?null:J.sandboxEnforcement===`cgroup`?`cgroup 内核硬限`:Z?`采样式软限(超限由守卫按拍数收割重启,非内核级强制)`:`无内核级限额`;(0,I.useEffect)(()=>(r?.({onAdd:()=>B(!0)}),()=>r?.(null)),[r]);let $=(e,t)=>c(e,t),re=e=>c(e,()=>x(()=>u.instanceOpenWeb(e)).then(()=>void 0));async function ie(){if(X){i.error(`当前平台不支持沙箱实例(见 /env/status 能力矩阵)`);return}let e=parseInt(U,10);if(!Number.isFinite(e)||e<=0){i.error(`请填写有效端口`);return}let t=G?G.split(/\n/).map(e=>e.trim()).filter(Boolean):[];try{let n=await u.instanceAdd({name:V.trim()||`沙箱 `+e,port:e,command:t});if(n&&n.ok===!1){i.error(n.error||`添加失败`);return}i.success(`已添加实例`),B(!1),H(``),W(``),K(``),h.refresh()}catch(e){i.error(String(e))}}async function ae(e){await c(e.id,async()=>{let t=await u.instanceCheckUpdate(e.id);t.updateAvailable?(i.success(`发现新版 `+t.latest+`,可点「更新」升级`),se(t=>new Map(t).set(e.id,!0))):t.latest?i.info(`已是最新 `+t.latest):i.error(t.error||`版本检测失败`)})}let[oe,se]=(0,I.useState)(new Map);async function ce(e){await R({title:`升级该沙箱实例的 DSH 到最新版?`,description:`实例会短暂重启,进行中的请求中断。`,confirmText:`升级`})&&await c(e.id,()=>u.instanceUpgrade(e.id),{success:`升级已开始…`})}async function le(e){await R({title:`删除实例「`+e.name+`」?`,description:`将彻底删除该沙箱实例(含配置与运行时数据)。此操作不可恢复。`,confirmText:`删除实例`,tone:`destructive`})&&await c(e.id,async()=>{let t=await u.instanceRemove(e.id);t&&t.ok!==!1&&t.dataPreserved===!0?i.warning(`实例已移除,但因其单元仍在运行,数据目录已保留(未删除)——请先停止实例再删数据`):t&&t.ok===!1&&i.error(t.error||`删除失败`),h.refresh()})}let ue=({it:e})=>{let r=e.state?.running??!1,i=e.state?.lifecyclePhase,a=te(i,r),o=e.updateJob,c=o?.state===`running`,l=e.state?.allocation?.memoryMax||`—`,d=e.state?.allocation?.cpuQuota||`—`,p=e.state?.usage,h=p&&typeof p.memMb==`number`?p.memMb:null,g=p&&typeof p.cpuPct==`number`?p.cpuPct:null,_=s===e.id;return(0,L.jsxs)(N,{className:`overflow-visible`,children:[(0,L.jsxs)(`div`,{className:`grid grid-cols-1 @min-[720px]:grid-cols-[minmax(0,5fr)_minmax(0,6fr)]`,children:[(0,L.jsxs)(`div`,{className:`flex flex-col gap-4 border-b border-border px-6 py-5 md:border-b-0 md:border-r`,children:[(0,L.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,L.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,L.jsx)(`strong`,{className:`truncate text-lg font-semibold tracking-[-0.01em] text-foreground`,children:e.name}),e.version?(0,L.jsxs)(`span`,{className:`font-mono text-sm text-muted-foreground`,children:[`v`,e.version]}):null]}),oe.get(e.id)?(0,L.jsxs)(t,{className:`text-primary-foreground`,onClick:()=>void ce(e),size:`chip`,children:[(0,L.jsx)(P,{className:`size-3`}),`更新`]}):(0,L.jsxs)(t,{className:`bg-primary/10 text-primary hover:bg-primary/15`,disabled:_||c,onClick:()=>void ae(e),size:`chip`,variant:`ghost`,children:[(0,L.jsx)(P,{className:n(`size-3`,_&&`animate-spin`)}),`检测更新`]})]}),(0,L.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,L.jsx)(k,{tone:a.tone,ping:a.tone===`ok`}),(0,L.jsx)(`span`,{className:`text-base font-semibold leading-none text-foreground`,children:a.label})]}),c?(0,L.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,L.jsx)(f,{className:`size-3`}),`正在升级 DeepSeek Harness(`,o?.step||``,`)…`]}):null,e.state?.installing?(0,L.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,L.jsx)(f,{className:`size-3`}),`正在安装…`]}):null,i===`FAILED`?(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-destructive`,children:[(0,L.jsx)(m,{className:`size-3.5`}),(0,L.jsx)(`span`,{className:`truncate`,children:e.state?.lastError||e.state?.installError||`启动反复失败,已停止自动重启,可手动重试`})]}):null]}),(0,L.jsx)(`div`,{className:`flex items-center bg-[image:var(--panel-accent-gradient)] px-6 py-5`,children:(0,L.jsxs)(`div`,{className:`grid w-full grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-4`,children:[(0,L.jsx)(A,{icon:(0,L.jsx)(E,{className:`size-4`}),label:`端口`,value:String(e.port),mono:!0}),(0,L.jsx)(A,{icon:(0,L.jsx)(F,{className:`size-4`}),label:`PID`,value:e.state?.pid?String(e.state.pid):`—`,mono:!0}),(0,L.jsx)(A,{icon:(0,L.jsx)(P,{className:`size-4`}),label:`重启次数`,value:String(e.state?.restartCount??0),mono:!0}),(0,L.jsx)(A,{icon:(0,L.jsx)(m,{className:`size-4`}),label:`最近故障`,value:e.state?.lastFailure?D(e.state.lastFailure):`无`,warn:!!e.state?.lastFailure})]})})]}),(0,L.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 border-t border-border/60 px-6 py-3`,children:[(0,L.jsxs)(`span`,{className:`hidden min-w-0 items-center lg:inline-flex gap-2 text-xs text-muted-foreground`,children:[(0,L.jsx)(M,{domain:`sandbox`}),(0,L.jsx)(j,{tone:e.remoteMode&&e.remoteMode!==`off`?`boot`:`off`,children:e.remoteMode===`wan`?`远程·公网`:e.remoteMode===`lan`?`远程·局域网`:`远程关闭`}),(0,L.jsxs)(`span`,{className:`whitespace-nowrap`,title:`配额由守卫按机器预算与活跃实例数动态推导`+(Q?`;执行档位:`+Q:``),children:[`配额 内存 `,l,` · CPU `,d,Z?`(软限)`:``]}),h===null&&g===null?null:(0,L.jsxs)(`span`,{className:`whitespace-nowrap`,title:`监督拍实测值(最近一次采样;停止或未采到不显示)`,children:[`占用 `,h===null?`—`:`${h}MB`,g===null?``:` · CPU ${Math.round(g)}%`]})]}),(0,L.jsxs)(`div`,{className:`ml-auto flex flex-wrap items-center gap-2`,children:[(0,L.jsxs)(t,{disabled:!r,onClick:()=>void re(e.id),size:`sm`,title:`打开 DSH Web(自动带认证连接)`,variant:`outline`,className:`hidden md:inline-flex`,children:[(0,L.jsx)(S,{className:`size-4`}),`DSH Web`]}),(0,L.jsx)(t,{disabled:c,onClick:()=>void $(e.id,()=>r?u.instanceStop(e.id):u.instanceStart(e.id)),size:`sm`,variant:`outline`,children:r?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(C,{className:`size-4 text-status-error`}),`停止实例`]}):(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(w,{className:`size-4 text-primary`}),`启动实例`]})}),(0,L.jsx)(`span`,{"aria-hidden":`true`,className:`mx-1 h-5 w-px bg-border`}),(0,L.jsxs)(t,{disabled:_,onClick:()=>void $(e.id,()=>u.instanceUpdate(e.id,{guardian:!e.guardian})),size:`sm`,variant:`outline`,children:[(0,L.jsx)(ee,{className:n(`size-4`,e.guardian?`text-status-ok`:`text-muted-foreground`)}),e.guardian?`停止守护`:`启动守护`]}),(0,L.jsxs)(t,{className:`hidden h-[30px] md:inline-flex`,disabled:_,onClick:()=>void le(e),size:`sm`,variant:`destructive`,children:[(0,L.jsx)(T,{className:`size-4`}),`删除`]})]})]})]})};return(0,L.jsxs)(`div`,{className:`grid content-start gap-4`,children:[X?(0,L.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-amber-500/30 bg-amber-500/5 px-3 py-2.5 text-xs text-muted-foreground`,children:[(0,L.jsx)(m,{className:`mt-0.5 size-3.5 shrink-0 text-amber-500`}),(0,L.jsxs)(`span`,{children:[`当前平台(`,J?.platform||`未知`,`)不支持沙箱实例(能力矩阵见 /env/status 的 capabilities.sandboxLaunch;限额执行档位见 capabilities.sandboxEnforcement)。 原生 DSH 主实例不受影响。`]})]}):null,q.length?(0,L.jsx)(`div`,{className:`grid gap-3`,children:q.map(e=>(0,L.jsx)(ue,{it:e},e.id))}):(0,L.jsx)(`div`,{className:`grid min-h-[220px] place-items-center rounded-lg border border-dashed border-border text-center`,children:(0,L.jsxs)(`div`,{children:[(0,L.jsx)(ne,{className:`mx-auto mb-3 size-8 text-muted-foreground`}),(0,L.jsx)(`p`,{className:`text-sm font-medium text-foreground`,children:`尚未添加沙箱实例`}),(0,L.jsx)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:X?`当前平台不支持沙箱实例(见上方说明)`:`点击顶部「添加实例」创建沙箱`})]})}),(0,L.jsx)(v,{open:z,onOpenChange:B,children:(0,L.jsxs)(b,{className:`max-w-[440px]`,children:[(0,L.jsx)(y,{children:(0,L.jsx)(o,{children:`添加 DSH 实例`})}),(0,L.jsxs)(`div`,{className:`grid gap-3`,children:[(0,L.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,L.jsx)(p,{children:`实例名称`}),(0,L.jsx)(l,{placeholder:`如 沙箱二开`,value:V,onChange:e=>H(e.target.value)})]}),(0,L.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,L.jsx)(p,{children:`监听端口`}),(0,L.jsx)(l,{inputMode:`numeric`,placeholder:`如 3082`,value:U,onChange:e=>W(e.target.value)})]}),(0,L.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,L.jsx)(p,{children:`启动命令(每项一参数,可留空用默认)`}),(0,L.jsx)(g,{className:`min-h-[72px] font-mono text-sm`,placeholder:`node
1
+ import{F as e,I as t,L as n,N as r,O as i,R as a,S as o,U as s,V as c,_ as l,a as u,b as d,c as f,g as p,k as m,n as h,o as g,t as _,v,x as y,y as b}from"./supervisor-Dfq_YAmt.js";import{n as x,o as S}from"./openExternal-Ds20EFp9.js";import{n as C,t as w}from"./rocket-Dit4Xpeq.js";import{t as ee}from"./shield-check-D2xvjEfM.js";import{c as T,f as E,o as D,s as te}from"./supervisor-BilTj6si.js";import{t as O}from"./useSupervisorAction-DZSdzPif.js";import{c as k,i as A,o as j,r as M,t as N}from"./widgets-M2h3F-43.js";var ne=r(`box`,[[`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`,key:`hh9hay`}],[`path`,{d:`m3.3 7 8.7 5 8.7-5`,key:`g66t2b`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}]]),P=r(`rotate-cw`,[[`path`,{d:`M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8`,key:`1p45f6`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}]]),F=r(`square`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}]]),I=s(c(),1),L=a();function R({onRegisterActions:r}){let{snap:a}=_(),{busy:s,run:c}=O(),R=e(),[z,B]=(0,I.useState)(!1),[V,H]=(0,I.useState)(``),[U,W]=(0,I.useState)(``),[G,K]=(0,I.useState)(``),q=a.instances?.instances??[],[J,Y]=(0,I.useState)(null);(0,I.useEffect)(()=>{let e=!0;return u.envStatus().then(t=>{e&&Y(t.capabilities??null)}).catch(()=>void 0),()=>{e=!1}},[]);let X=J!==null&&J.sandboxLaunch===!1,Z=J?.sandboxEnforcement===`supervise`,Q=J==null?null:J.sandboxEnforcement===`cgroup`?`cgroup 内核硬限`:Z?`采样式软限(超限由守卫按拍数收割重启,非内核级强制)`:`无内核级限额`;(0,I.useEffect)(()=>(r?.({onAdd:()=>B(!0)}),()=>r?.(null)),[r]);let $=(e,t)=>c(e,t),re=e=>c(e,()=>x(()=>u.instanceOpenWeb(e)).then(()=>void 0));async function ie(){if(X){i.error(`当前平台不支持沙箱实例(见 /env/status 能力矩阵)`);return}let e=parseInt(U,10);if(!Number.isFinite(e)||e<=0){i.error(`请填写有效端口`);return}let t=G?G.split(/\n/).map(e=>e.trim()).filter(Boolean):[];try{let n=await u.instanceAdd({name:V.trim()||`沙箱 `+e,port:e,command:t});if(n&&n.ok===!1){i.error(n.error||`添加失败`);return}i.success(`已添加实例`),B(!1),H(``),W(``),K(``),h.refresh()}catch(e){i.error(String(e))}}async function ae(e){await c(e.id,async()=>{let t=await u.instanceCheckUpdate(e.id);t.updateAvailable?(i.success(`发现新版 `+t.latest+`,可点「更新」升级`),se(t=>new Map(t).set(e.id,!0))):t.latest?i.info(`已是最新 `+t.latest):i.error(t.error||`版本检测失败`)})}let[oe,se]=(0,I.useState)(new Map);async function ce(e){await R({title:`升级该沙箱实例的 DSH 到最新版?`,description:`实例会短暂重启,进行中的请求中断。`,confirmText:`升级`})&&await c(e.id,()=>u.instanceUpgrade(e.id),{success:`升级已开始…`})}async function le(e){await R({title:`删除实例「`+e.name+`」?`,description:`将彻底删除该沙箱实例(含配置与运行时数据)。此操作不可恢复。`,confirmText:`删除实例`,tone:`destructive`})&&await c(e.id,async()=>{let t=await u.instanceRemove(e.id);t&&t.ok!==!1&&t.dataPreserved===!0?i.warning(`实例已移除,但因其单元仍在运行,数据目录已保留(未删除)——请先停止实例再删数据`):t&&t.ok===!1&&i.error(t.error||`删除失败`),h.refresh()})}let ue=({it:e})=>{let r=e.state?.running??!1,i=e.state?.lifecyclePhase,a=te(i,r),o=e.updateJob,c=o?.state===`running`,l=e.state?.allocation?.memoryMax||`—`,d=e.state?.allocation?.cpuQuota||`—`,p=e.state?.usage,h=p&&typeof p.memMb==`number`?p.memMb:null,g=p&&typeof p.cpuPct==`number`?p.cpuPct:null,_=s===e.id;return(0,L.jsxs)(N,{className:`overflow-visible`,children:[(0,L.jsxs)(`div`,{className:`grid grid-cols-1 @min-[720px]:grid-cols-[minmax(0,5fr)_minmax(0,6fr)]`,children:[(0,L.jsxs)(`div`,{className:`flex flex-col gap-4 border-b border-border px-6 py-5 md:border-b-0 md:border-r`,children:[(0,L.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,L.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,L.jsx)(`strong`,{className:`truncate text-lg font-semibold tracking-[-0.01em] text-foreground`,children:e.name}),e.version?(0,L.jsxs)(`span`,{className:`font-mono text-sm text-muted-foreground`,children:[`v`,e.version]}):null]}),oe.get(e.id)?(0,L.jsxs)(t,{className:`text-primary-foreground`,onClick:()=>void ce(e),size:`chip`,children:[(0,L.jsx)(P,{className:`size-3`}),`更新`]}):(0,L.jsxs)(t,{className:`bg-primary/10 text-primary hover:bg-primary/15`,disabled:_||c,onClick:()=>void ae(e),size:`chip`,variant:`ghost`,children:[(0,L.jsx)(P,{className:n(`size-3`,_&&`animate-spin`)}),`检测更新`]})]}),(0,L.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,L.jsx)(k,{tone:a.tone,ping:a.tone===`ok`}),(0,L.jsx)(`span`,{className:`text-base font-semibold leading-none text-foreground`,children:a.label})]}),c?(0,L.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,L.jsx)(f,{className:`size-3`}),`正在升级 DeepSeek Harness(`,o?.step||``,`)…`]}):null,e.state?.installing?(0,L.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,L.jsx)(f,{className:`size-3`}),`正在安装…`]}):null,i===`FAILED`?(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-destructive`,children:[(0,L.jsx)(m,{className:`size-3.5`}),(0,L.jsx)(`span`,{className:`truncate`,children:e.state?.lastError||e.state?.installError||`启动反复失败,已停止自动重启,可手动重试`})]}):null]}),(0,L.jsx)(`div`,{className:`flex items-center bg-[image:var(--panel-accent-gradient)] px-6 py-5`,children:(0,L.jsxs)(`div`,{className:`grid w-full grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-4`,children:[(0,L.jsx)(A,{icon:(0,L.jsx)(E,{className:`size-4`}),label:`端口`,value:String(e.port),mono:!0}),(0,L.jsx)(A,{icon:(0,L.jsx)(F,{className:`size-4`}),label:`PID`,value:e.state?.pid?String(e.state.pid):`—`,mono:!0}),(0,L.jsx)(A,{icon:(0,L.jsx)(P,{className:`size-4`}),label:`重启次数`,value:String(e.state?.restartCount??0),mono:!0}),(0,L.jsx)(A,{icon:(0,L.jsx)(m,{className:`size-4`}),label:`最近故障`,value:e.state?.lastFailure?D(e.state.lastFailure):`无`,warn:!!e.state?.lastFailure})]})})]}),(0,L.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 border-t border-border/60 px-6 py-3`,children:[(0,L.jsxs)(`span`,{className:`hidden min-w-0 items-center lg:inline-flex gap-2 text-xs text-muted-foreground`,children:[(0,L.jsx)(M,{domain:`sandbox`}),(0,L.jsx)(j,{tone:e.remoteMode&&e.remoteMode!==`off`?`boot`:`off`,children:e.remoteMode===`wan`?`远程·公网`:e.remoteMode===`lan`?`远程·局域网`:`远程关闭`}),(0,L.jsxs)(`span`,{className:`whitespace-nowrap`,title:`配额由守卫按机器预算与活跃实例数动态推导`+(Q?`;执行档位:`+Q:``),children:[`配额 内存 `,l,` · CPU `,d,Z?`(软限)`:``]}),h===null&&g===null?null:(0,L.jsxs)(`span`,{className:`whitespace-nowrap`,title:`监督拍实测值(最近一次采样;停止或未采到不显示)`,children:[`占用 `,h===null?`—`:`${h}MB`,g===null?``:` · CPU ${Math.round(g)}%`]})]}),(0,L.jsxs)(`div`,{className:`ml-auto flex flex-wrap items-center gap-2`,children:[(0,L.jsxs)(t,{disabled:!r,onClick:()=>void re(e.id),size:`sm`,title:`打开 DSH Web(自动带认证连接)`,variant:`outline`,className:`hidden md:inline-flex`,children:[(0,L.jsx)(S,{className:`size-4`}),`DSH Web`]}),(0,L.jsx)(t,{disabled:c,onClick:()=>void $(e.id,()=>r?u.instanceStop(e.id):u.instanceStart(e.id)),size:`sm`,variant:`outline`,children:r?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(C,{className:`size-4 text-status-error`}),`停止实例`]}):(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(w,{className:`size-4 text-primary`}),`启动实例`]})}),(0,L.jsx)(`span`,{"aria-hidden":`true`,className:`mx-1 h-5 w-px bg-border`}),(0,L.jsxs)(t,{disabled:_,onClick:()=>void $(e.id,()=>u.instanceUpdate(e.id,{guardian:!e.guardian})),size:`sm`,variant:`outline`,children:[(0,L.jsx)(ee,{className:n(`size-4`,e.guardian?`text-status-ok`:`text-muted-foreground`)}),e.guardian?`停止守护`:`启动守护`]}),(0,L.jsxs)(t,{className:`hidden h-[30px] md:inline-flex`,disabled:_,onClick:()=>void le(e),size:`sm`,variant:`destructive`,children:[(0,L.jsx)(T,{className:`size-4`}),`删除`]})]})]})]})};return(0,L.jsxs)(`div`,{className:`grid content-start gap-4`,children:[X?(0,L.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-amber-500/30 bg-amber-500/5 px-3 py-2.5 text-xs text-muted-foreground`,children:[(0,L.jsx)(m,{className:`mt-0.5 size-3.5 shrink-0 text-amber-500`}),(0,L.jsxs)(`span`,{children:[`当前平台(`,J?.platform||`未知`,`)不支持沙箱实例(能力矩阵见 /env/status 的 capabilities.sandboxLaunch;限额执行档位见 capabilities.sandboxEnforcement)。 原生 DSH 主实例不受影响。`]})]}):null,q.length?(0,L.jsx)(`div`,{className:`grid gap-3`,children:q.map(e=>(0,L.jsx)(ue,{it:e},e.id))}):(0,L.jsx)(`div`,{className:`grid min-h-[220px] place-items-center rounded-lg border border-dashed border-border text-center`,children:(0,L.jsxs)(`div`,{children:[(0,L.jsx)(ne,{className:`mx-auto mb-3 size-8 text-muted-foreground`}),(0,L.jsx)(`p`,{className:`text-sm font-medium text-foreground`,children:`尚未添加沙箱实例`}),(0,L.jsx)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:X?`当前平台不支持沙箱实例(见上方说明)`:`点击顶部「添加实例」创建沙箱`})]})}),(0,L.jsx)(v,{open:z,onOpenChange:B,children:(0,L.jsxs)(b,{className:`max-w-[440px]`,children:[(0,L.jsx)(y,{children:(0,L.jsx)(o,{children:`添加 DSH 实例`})}),(0,L.jsxs)(`div`,{className:`grid gap-3`,children:[(0,L.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,L.jsx)(p,{children:`实例名称`}),(0,L.jsx)(l,{placeholder:`如 沙箱二开`,value:V,onChange:e=>H(e.target.value)})]}),(0,L.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,L.jsx)(p,{children:`监听端口`}),(0,L.jsx)(l,{inputMode:`numeric`,placeholder:`如 3082`,value:U,onChange:e=>W(e.target.value)})]}),(0,L.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,L.jsx)(p,{children:`启动命令(每项一参数,可留空用默认)`}),(0,L.jsx)(g,{className:`min-h-[72px] font-mono text-sm`,placeholder:`node
2
2
  /usr/local/bin/dsh
3
3
  web`,value:G,onChange:e=>K(e.target.value)})]}),(0,L.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`内存/CPU 配额无需填写:启动时由守卫按机器预算与活跃实例数自动推导,实例增减后动态重分配。`,Q?` 执行档位:${Q}。`:``]})]}),(0,L.jsxs)(d,{children:[(0,L.jsx)(t,{onClick:()=>B(!1),variant:`outline`,children:`取消`}),(0,L.jsx)(t,{onClick:()=>void ie(),children:`添加`})]})]})})]})}export{R as InstancesPage};
@@ -1,2 +1,2 @@
1
- import{F as e,I as t,L as n,N as r,O as i,R as a,S as o,U as s,V as c,a as l,b as ee,h as u,k as d,m as f,t as p,v as m,x as h,y as g}from"./supervisor-Dfq_YAmt.js";import{n as _,o as v}from"./openExternal-Ds20EFp9.js";import{n as y,t as b}from"./rocket-Dit4Xpeq.js";import{t as x}from"./refresh-cw-CFZGPyP6.js";import{t as S}from"./shield-check-D2xvjEfM.js";import{c as C,f as te,n as w,o as T,t as E}from"./supervisor-BZTzTZDT.js";import{t as D}from"./useSupervisorAction-DZSdzPif.js";import{c as O,i as k,n as A,o as j,t as M}from"./widgets-M2h3F-43.js";import{t as N}from"./format-QeaTKFhQ.js";var P=r(`arrow-up-right`,[[`path`,{d:`M7 7h10v10`,key:`1tivn9`}],[`path`,{d:`M7 17 17 7`,key:`1vkiza`}]]),F=r(`circle-dot`,[[`circle`,{cx:`12`,cy:`12`,r:`1`,key:`41hilf`}],[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]]),I=r(`square-terminal`,[[`path`,{d:`m7 11 2-2-2-2`,key:`1lz0vl`}],[`path`,{d:`M11 13h4`,key:`1p7l4v`}],[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,ry:`2`,key:`1m3agn`}]]),L=s(c(),1),R=a();function z(e,t){return e===`dsh-main`||e===`supervisor-api`?`boot`:(t||``).startsWith(`inst:`)?`ok`:e===`relay`?`warn`:e.startsWith(`managed:`)?`boot`:`off`}function B(e){let t={"dsh-main":`DSH 主实例`,"supervisor-api":`管家 API`,user:`沙箱实例`,relay:`局域网隧道`,oauthCallback:`登录回调`,proxyInstance:`反代实例`,providerApi:`供应商 API`,"managed:router-daemon":`智能路由`,"managed:lan-daemon":`远程控制`,dynamic:`动态端口`},n=/^managed:(.+)$/.exec(e.role);return n?t[e.role]??n[1]:t[e.role]??e.role}function V(e,t){let n=e.owner||``;if(e.role===`proxyInstance`){let e=(n.split(`:`).pop()||``).slice(-4),r=(t??[]).find(t=>(t.accounts??[]).some(t=>(t.maskedKey||``).endsWith(e)));return r?r.name:`反代`}return n.startsWith(`inst:`)?`沙箱实例`:n.startsWith(`system:`)?`系统`:n.startsWith(`relay:`)?`局域网隧道`:n.startsWith(`dynamic:`)?`动态`:n.startsWith(`providerApi:`)?`供应商`:n.startsWith(`oauth:`)?`登录回调`:n===`router-daemon`||e.role===`managed:router-daemon`?`智能路由`:n===`lan-daemon`||e.role===`managed:lan-daemon`?`远程控制`:e.role===`oauthCallback`?`登录回调`:e.role}function H({providers:e=[]}){let{snap:t}=p(),r=t.ports?.records??null,i=(0,L.useMemo)(()=>r?[...r.filter(e=>e.role!==`supervisor-api`||e.port!==3100&&e.port!==3101)].sort((e,t)=>!!e.active==!!t.active?e.port-t.port:e.active?-1:1):null,[r]);return(0,R.jsxs)(M,{className:`flex min-h-0 flex-col overflow-hidden`,children:[(0,R.jsx)(A,{title:`运行状态`,subtitle:`核心服务与端口实时状态`,actions:i?(0,R.jsxs)(`span`,{className:`font-mono text-xs text-muted-foreground`,children:[i.length,` 端口`]}):null}),i?(0,R.jsxs)(`div`,{className:`min-h-0 overflow-x-auto`,children:[(0,R.jsxs)(`div`,{className:`grid min-w-[400px] grid-cols-[56px_minmax(0,1fr)_auto_66px] items-center gap-2 border-b border-border/60 bg-muted/60 px-4 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground`,children:[(0,R.jsx)(`span`,{children:`端口`}),(0,R.jsx)(`span`,{children:`服务`}),(0,R.jsx)(`span`,{className:`text-right`,children:`归属`}),(0,R.jsx)(`span`,{className:`text-right`,children:`状态`})]}),(0,R.jsx)(`div`,{className:`max-h-[340px] overflow-y-auto overscroll-contain`,children:i.map((t,r)=>(0,R.jsxs)(`div`,{className:n(`grid grid-cols-[56px_minmax(0,1fr)_auto_66px] items-center gap-2 px-4 py-2 hover:bg-muted/40`,r>0&&`border-t border-border/50`),children:[(0,R.jsx)(`code`,{className:`font-mono text-sm tabular-nums text-foreground`,children:t.port}),(0,R.jsx)(`div`,{className:`flex min-w-0 items-center gap-1.5`,children:(0,R.jsx)(`span`,{className:`truncate text-xs text-foreground`,children:B(t)})}),(0,R.jsx)(`div`,{className:`flex justify-end`,children:(0,R.jsx)(j,{tone:z(t.role,t.owner),children:V(t,e)})}),(0,R.jsx)(`div`,{className:`flex justify-end`,children:t.active===!0?(0,R.jsxs)(`span`,{className:`inline-flex items-center gap-1 whitespace-nowrap text-[11px] text-status-ok`,children:[(0,R.jsx)(F,{className:`size-3`}),`运行中`]}):t.active===!1?(0,R.jsxs)(`span`,{className:`inline-flex items-center gap-1 whitespace-nowrap text-[11px] text-muted-foreground`,children:[(0,R.jsx)(F,{className:`size-3 opacity-50`}),`未运行`]}):(0,R.jsxs)(`span`,{className:`inline-flex items-center gap-1 whitespace-nowrap text-[11px] text-muted-foreground`,children:[(0,R.jsx)(F,{className:`size-3 opacity-40`}),`状态未知`]})})]},t.port+`-`+t.owner))})]}):(0,R.jsx)(`div`,{className:`px-5 py-6 text-center text-xs text-muted-foreground`,children:`运行状态加载中…`})]})}function U(e){if(!e)return`未读出`;let t=String(e.state||`?`),n=e.detail?`(`+String(e.detail)+`)`:``;return(String(e.label||``)||`条目`)+` `+t+n}function W(e){return!e||e.state===`pending`?`未探测(点「重新探测」补齐)`:e.state===`error`?`探测失败:`+(e.error||`未给出原因`):e.state===`empty`?`已探测,无内容`:`已探测`+(e.at?` `+new Date(e.at).toLocaleTimeString():``)}function G(e){let t=e||{};return t.state===`on`?`在用(`+(t.server||t.pac||`地址未读出`)+`)`:t.state===`off`?`系统里明确未启用`:t.state===`unknown`?`取不到`+(t.source?`(`+t.source+`)`:``)+`,按判不出处理`:`未探测`}function K(e){return e===!0?`可达`:e===!1?`不通`:`判不出`}function q(e){return(e.section?e.section+`:`:``)+e.source+`:`+String(e.detail??``)}function J(e){return typeof e!=`number`||!Number.isFinite(e)||e<0?`时间未读出`:e<6e4?`刚刚`:e<36e5?Math.floor(e/6e4)+` 分钟前`:e<864e5?Math.floor(e/36e5)+` 小时前`:Math.floor(e/864e5)+` 天前`}function Y(e){return e===!0?`是`:e===!1?`否`:`未读出`}function X(e,t,n){let r=t||``,i=n||``,a=r&&i&&r!==i?`(两份不一致:装内核用的是壳那套,本进程解析到的是内核这套)`:``;return e+` 内核 `+(r||`未读出`)+` / 壳 `+(i||`未报`)+a}function Z(e){let t=e.ok===!0?`通`:e.ok===!1?`不通`:`判不出`;return(e.probe||`明细`)+` `+t+(e.target?`(`+e.target+`)`:``)+(typeof e.ms==`number`?` `+e.ms+` 毫秒`:``)}function ne(e,t){return e?t?`没落盘(这一拍读的是内核缓存拍)`:e.written===!0?`已写入`:e.error?`失败:`+e.error:`没落盘(也没报错误)`:`未给出(这一拍没装配)`}function re(e,t){if(t)return`读不回:`+t;if(!e)return`未读`;if(e.available===!0){let t=typeof e.at==`number`?new Date(e.at).toLocaleString():`时间未读出`,n=e.data&&e.data.browsers?e.data.browsers.length:null;return t+`(`+J(e.ageMs)+`)`+(n===null?``:`,候选 `+n+` 个`)}return e.reason===`never-written`?`这台机器还没落过盘`:`快照文件读不出或版本不符(不是没写过,得查文件)`}function ie(e){let t=e||{},n=Object.keys(t).filter(e=>t[e]!==`ok`);return n.length?`未补齐:`+n.join(`、`):`全部维度补齐`}function ae(e){let t=e&&e.name?e.name:`未定出`;return!e||!e.how?`现在会用:`+t:e.how===`user-preference`?`现在会用:`+t+`(你选的)`:e.how===`candidate-rank`?`现在会用:`+t+`(系统未报默认项,按候选次序取首个,可在此改)`:e.how===`only-installed`?`现在会用:`+t+`(本机唯一候选)`:e.how===`none-found`?`本机未探到可用浏览器,请安装或启用一个后重新探测`:`现在会用:`+t+`(系统默认项)`}var Q=`__system__`;function oe(){let[e,r]=(0,L.useState)(!1),[i,a]=(0,L.useState)(null),[s,c]=(0,L.useState)(null),[p,_]=(0,L.useState)(null),[y,b]=(0,L.useState)(!1),[S,C]=(0,L.useState)(!1),[te,w]=(0,L.useState)(null),[T,E]=(0,L.useState)(null),D=(0,L.useCallback)(async e=>{e&&b(!0);try{let t=await l.environment(e);a(t),_(null),c(null)}catch(e){c(String(e.message||e))}b(!1),l.environmentLast().then(e=>{w(e),E(null)}).catch(e=>{w(null),E(String(e.message||e))})},[]);(0,L.useEffect)(()=>{e&&D(!1)},[e,D]);let O=async e=>{C(!0);let t={ok:!1,error:`偏好写入未返回结果`};try{t=await l.setExternalBrowser(e)}catch(e){t={ok:!1,error:String(e.message||e)}}if(C(!1),!t||t.ok!==!0){c(t&&t.error||`偏好写入失败`);return}c(null),await D(!0)},k=i?.browsers??[],A=i?.sections,j=i?.pick?.stale===!0,M=i?.preference?.id||Q,N=p===null?M:p,P=A?.startup?.data,F=A?.shell?.data,I=F?.registry,z=I?.probes||[],B=F?.records||[],V=I?.latencyMs,H=I?.probesTotal??0,oe=A?.runtime?.data?.node?.version||null,$=A?.runtime?.data?.npm?.detail||null;return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 whitespace-nowrap`,children:[(0,R.jsxs)(t,{size:`sm`,variant:`ghost`,className:`h-6 gap-1 px-1.5 text-xs text-muted-foreground`,onClick:()=>r(!0),children:[(0,R.jsx)(v,{className:`size-3`}),`环境表单`]}),i?.pick?.name?(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground/70`,children:i.pick.name}):null]}),(0,R.jsx)(m,{open:e,onOpenChange:r,children:(0,R.jsxs)(g,{className:`max-w-[560px]`,children:[(0,R.jsx)(h,{children:(0,R.jsx)(o,{children:`本机环境表单`})}),(0,R.jsxs)(`div`,{className:`grid max-h-[60vh] gap-3 overflow-y-auto text-sm`,children:[(0,R.jsx)(`p`,{className:n(`text-xs`,j||!k.length?`font-semibold text-warning`:`text-muted-foreground`),children:ae(i?.pick)}),j?(0,R.jsxs)(`p`,{className:`inline-flex items-start gap-1.5 rounded-md bg-warning-background px-2 py-1.5 text-xs font-semibold text-warning`,children:[(0,R.jsx)(d,{className:`mt-0.5 size-3.5 shrink-0`}),`你先前选的浏览器已不在本机候选清单(可能已卸载或路径变更),下方选择已回落到系统判定,请重选或清除。`]}):null,s?(0,R.jsx)(`p`,{className:`text-xs text-status-error`,children:s}):null,(0,R.jsxs)(`div`,{className:`grid gap-2 rounded-md border border-border/60 px-3 py-2.5`,children:[(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:`打开地址用哪个浏览器`}),(0,R.jsxs)(f,{value:N,onValueChange:_,className:`grid gap-1.5`,children:[(0,R.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-2 text-xs`,children:[(0,R.jsx)(u,{value:Q,id:`env-pref-system`}),(0,R.jsx)(`span`,{children:`跟随系统默认(本机探不到默认项时按候选次序)`})]}),k.map(e=>(0,R.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-2 text-xs`,children:[(0,R.jsx)(u,{value:e.id,id:`env-pref-`+e.id}),(0,R.jsx)(`span`,{children:e.name||e.bin}),(0,R.jsx)(`span`,{className:`text-muted-foreground/70`,children:e.engine}),e.isDefault?(0,R.jsx)(`span`,{className:`text-muted-foreground/70`,children:`系统默认`}):null]},e.id))]}),k.length?(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(t,{size:`sm`,variant:`outline`,disabled:S||N===M,onClick:()=>void O(N===Q?``:N),children:`保存偏好`}),(0,R.jsx)(t,{size:`sm`,variant:`ghost`,disabled:S||M===Q,onClick:()=>void O(``),children:`清除`})]}):(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`候选为空:重新探测后仍为空时,请先在系统里安装或启用一个浏览器。`})]}),(0,R.jsxs)(`div`,{className:`grid gap-1.5 rounded-md border border-border/60 px-3 py-2.5`,children:[(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:`出网条件(隔离登录窗口的分发依据)`}),(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(A?.egress)}),A?.egress?.data?(0,R.jsxs)(`div`,{className:`grid gap-0.5 text-xs`,children:[(0,R.jsxs)(`span`,{className:`text-muted-foreground`,children:[`系统代理:`,G(A?.egress?.data?.proxy)]}),Object.entries(A?.egress?.data?.targets||{}).map(([e,t])=>(0,R.jsxs)(`span`,{className:`text-muted-foreground`,children:[e,`:`,K(t?.ok),t?.stage?`(停在 `+t.stage+(t.detail?` `+t.detail:``)+`)`:``]},e)),Object.keys(A?.egress?.data?.targets||{}).length?null:(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:`还没有目标域被问过:一键登录时会当场判定并记在这里。`})]}):null,A?.egress?.data?.proxy?.state===`off`?(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`没有在用系统代理时,直连不通的授权域只能靠现有浏览器窗口的既有出网路径打开(隔离冷档案会是空白页)。`}):null]}),(0,R.jsxs)(`div`,{className:`grid gap-1.5 rounded-md border border-border/60 px-3 py-2.5`,children:[(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:`运行时与 DSH(安装/升级动作的分发依据)`}),(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(A?.runtime)}),A?.runtime?.data?(0,R.jsxs)(`div`,{className:`grid gap-0.5 text-xs text-muted-foreground`,children:[(0,R.jsxs)(`span`,{children:[U(A?.runtime?.data?.node),` · `,U(A?.runtime?.data?.npm),` · `,U(A?.runtime?.data?.git)]}),(0,R.jsxs)(`span`,{children:[`镜像源:`,A?.runtime?.data?.registry?.origin||`未读出`,A?.runtime?.data?.registry?.mode?`(`+A.runtime.data.registry.mode+`)`:``,` · 候选 `+(A?.runtime?.data?.registry?.candidates||[]).length+` 个`]}),(0,R.jsxs)(`span`,{className:`break-all`,children:[`全局前缀:`,A?.runtime?.data?.prefix||`未实测(npm root -g 未返回)`]})]}):null,(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:`桌面壳所见(装内核时真正用的那一套,与上面的内核读数并排对照)`}),(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(A?.shell)}),F?(0,R.jsxs)(`div`,{className:`grid gap-0.5 text-xs text-muted-foreground`,children:[(0,R.jsx)(`span`,{children:F.available===!0?`壳上报于 `+J(F.ageMs)+`,写入者 `+(F.writtenBy||`未署名`)+`(报告版本 `+(F.schema??`未读出`)+`)`:F.reason===`never-written`?`这台机器的壳还没报过:内核由命令行或别的进程拉起时这是常态,不是故障`:`壳报的文件读不出或版本不符(不是没写过,得查那个文件)`}),F.available===!0?(0,R.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,R.jsx)(`span`,{className:`break-all`,children:X(`Node:`,oe,F.node?.version)}),(0,R.jsx)(`span`,{className:`break-all`,children:X(`npm:`,$,F.npm?.version)}),(0,R.jsx)(`span`,{className:`break-all`,children:X(`镜像源:`,A?.runtime?.data?.registry?.origin,F.registry?.best)}),(0,R.jsx)(`span`,{className:`break-all`,children:X(`全局前缀:`,A?.runtime?.data?.prefix,F.prefix?.dir)}),F.node&&F.node.ok!==!0?(0,R.jsxs)(`span`,{children:[`壳判 Node 达标:`,Y(F.node.ok),`(`,F.node.version||`版本未报`,`,门槛 `,F.node.min||`未报`,`)`]}):null,F.prefix&&F.prefix.writable!==!0?(0,R.jsxs)(`span`,{className:`break-all`,children:[`壳判前缀可写:`,Y(F.prefix.writable),F.prefix.why?`(`+F.prefix.why+`)`:``]}):null,z.length||I?.best?(0,R.jsxs)(`span`,{className:`break-all`,children:[`壳的镜像源候选:`,z.map(e=>(e.url||`?`)+` `+K(e.ok)).join(`、`),typeof V==`number`?`(择优选中用时 `+V+` 毫秒)`:``,H>z.length?`(报告里共 `+H+` 个候选,此处只列前 `+z.length+` 个)`:``]}):null,B.length?(0,R.jsxs)(`span`,{children:[`壳的探测明细 `,B.length,` 条:`,B.slice(0,8).map(Z).join(`;`),B.length>8?`…其余见内核快照文件`:``,F.droppedRecords?`(报告送达时被截断 `+F.droppedRecords+` 条)`:``]}):null]}):null]}):null,(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(A?.dsh)}),A?.dsh?.data?(0,R.jsxs)(`div`,{className:`grid gap-0.5 text-xs text-muted-foreground`,children:[(0,R.jsxs)(`span`,{children:[U(A?.dsh?.data?.dsh),` · `,U(A?.dsh?.data?.selfUpdate)]}),(0,R.jsxs)(`span`,{children:[`看护:`,A?.dsh?.data?.managed?`守卫托管`:`未托管`,A?.dsh?.data?.phase?` · `+A.dsh.data.phase:``]})]}):null]}),(0,R.jsxs)(`div`,{className:`grid gap-1.5 rounded-md border border-border/60 px-3 py-2.5`,children:[(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:`启动既成事实(守卫这一拍真的跑过什么)`}),(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(A?.startup)}),P?(0,R.jsxs)(`div`,{className:`grid gap-0.5 text-xs text-muted-foreground`,children:[(0,R.jsxs)(`span`,{children:[`守卫启动于 `,typeof P.bootAt==`number`?new Date(P.bootAt).toLocaleTimeString():`未读出`,`,环境表单首拍排在启动后 `,P.envDelayMs??`未读出`,` 毫秒`]}),(0,R.jsxs)(`span`,{children:[`选路:自动启动 `,Y(P.routerAutostart),`,模式 `,P.routerMode||`未读出(这一拍没走到那步)`]}),(0,R.jsxs)(`span`,{children:[`更新检查:`,P.updateCheck?P.updateCheck.enabled?`开(首查排在启动后 `+(P.updateCheck.initialDelayMs??`未读出`)+` 毫秒,之后每 `+(P.updateCheck.intervalMs??`未读出`)+` 毫秒)`:`关(配置里就禁掉了,这同样是一条既成事实)`:`未记录`]}),(0,R.jsxs)(`span`,{children:[`壳看护:`,Y(P.shellWatchdog)]}),(0,R.jsx)(`span`,{children:P.lastRefresh?`最近一次表单刷新于 `+(typeof P.lastRefresh.at==`number`?new Date(P.lastRefresh.at).toLocaleTimeString():`未读出`)+`,耗时 `+(P.lastRefresh.tookMs??`未读出`)+` 毫秒,浏览器 `+(P.lastRefresh.browsers??`未读出`)+` 个,分发依据 `+(P.lastRefresh.pick||`未定出`)+`,落盘 `+Y(P.lastRefresh.snapshotWritten)+`;`+ie(P.lastRefresh.dims):`这一拍还没跑过表单刷新(首拍排在上面那个延迟之后)`})]}):null]}),(0,R.jsxs)(`dl`,{className:`grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-xs`,children:[(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`平台`}),(0,R.jsx)(`dd`,{className:`font-mono`,children:[i?.identity?.platform,i?.identity?.arch].filter(Boolean).join(` / `)||`—`}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`图形会话`}),(0,R.jsx)(`dd`,{children:i?.session?.available?`可用(`+(i?.session?.reason||`—`)+`)`:`不可用(`+(i?.session?.reason||`—`)+`)`}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`系统默认项`}),(0,R.jsx)(`dd`,{children:i?.default?i.default.id+`(来源 `+(i.default.source||`未读出`)+`)`:`未读出`}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`候选`}),(0,R.jsx)(`dd`,{children:k.length?k.map(e=>(e.name||e.bin)+`[`+(e.sources||[]).join(`+`)+`]`).join(`、`):`无`}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`探测留痕`}),(0,R.jsx)(`dd`,{className:`grid gap-0.5`,children:(i?.probed??[]).map((e,t)=>(0,R.jsx)(`span`,{className:`text-muted-foreground/80`,children:q(e)},t))}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`快照落盘`}),(0,R.jsxs)(`dd`,{className:`break-all font-mono text-muted-foreground/80`,children:[ne(i?.snapshot,i?.cached===!0),(0,R.jsxs)(`span`,{className:`text-muted-foreground/60`,children:[` `,i?.snapshot?.path||`未给出路径`]})]}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`上一拍留痕`}),(0,R.jsx)(`dd`,{className:`text-muted-foreground`,children:re(te,T)})]})]}),(0,R.jsxs)(ee,{children:[(0,R.jsxs)(t,{variant:`outline`,disabled:y,onClick:()=>void D(!0),children:[(0,R.jsx)(x,{className:`size-4`}),y?`探测中…`:`重新探测`]}),(0,R.jsx)(t,{onClick:()=>r(!1),children:`关闭`})]})]})})]})}var $=new Set([`dist_registry_selected`,`gui_autostart_changed`,`autostart_changed`,`lan_panel_changed`,`lan_harness_token_updated`]);function se(){let{snap:r}=p(),{busy:a,run:s}=D(),c=e(),[u,d]=(0,L.useState)(!1),[f,E]=(0,L.useState)(null),A=r.status,j=A?.native,N=j?.installed??!1,F=j?.state||(N?`installed`:`uninstalled`),z=F===`installing`,B=z||F===`uninstalling`,V=A?.version,U=A?.upgrade,W=w[A?.phase??``]??{label:A?.phase||`未知`,tone:`off`},G=!!A?.dshPid,K=U?.state===`running`,q=(0,L.useMemo)(()=>r.events.filter(e=>!$.has(e.type)),[r.events]);async function J(){await s(`dsh`,()=>G?l.lifecycleStop(`dsh`):l.lifecycleStart(`dsh`),{success:G?`正在停止 DSH…`:`正在启动 DSH…`})}async function Y(){await c({title:`停止 DSH?`,description:`主干 DeepSeek Harness 正在运行;停止会中断进行中的请求,远程访问同时不可用。`,confirmText:`停止 DSH`})&&await J()}async function X(){await s(`web`,()=>_(()=>l.instanceOpenWeb(`main`)).then(()=>void 0))}async function Z(){await s(`chk`,async()=>{let e=await l.nativeCheckUpdate();if(e?.ok===!1){i.error(e.error||`检测失败`);return}e?.updateAvailable&&e.latest?i.success(`发现新版本 `+e.latest+(e.installed?`(当前 `+e.installed+`),可一键升级`:``)):i.success(`已是最新版本`+(e.installed?`(`+e.installed+`)`:``))})}async function ne(){d(!1),await s(`upg`,()=>l.nativeUpgrade(),{success:`升级已开始,请耐心等待…`})}async function re(){await c({title:`在线安装最新版 DeepSeek Harness?`,description:`需数分钟,自动适配最快镜像源。`,confirmText:`安装`})&&await s(`inst`,()=>l.nativeInstall(),{success:`开始安装 DeepSeek Harness…`})}async function ie(){await c({title:`彻底卸载 DeepSeek Harness?`,description:`删除全部文件、数据、缓存与日志,不留残留。`,confirmText:`卸载 DSH`,tone:`destructive`})&&await s(`uni`,()=>l.nativeUninstall(),{success:`开始卸载…`})}(0,L.useEffect)(()=>{N&&l.instances().then(e=>{let t=e?.native?.guardian;typeof t==`boolean`&&E(t)}).catch(()=>{})},[N,A?.dshPid]);async function ae(){let e=f!==!0;await s(`gu`,()=>l.nativeSettings({guardian:e}).then(e=>{let t=e?.main?.guardian;return typeof t==`boolean`&&E(t),e}),{success:e?`已开启 DSH 进程守护(崩溃自动拉起)`:`已关闭 DSH 进程守护(崩溃后不再自动拉起)`,refresh:!1})}let Q=N&&(j?.version||V?.installed)||`—`;return(0,R.jsxs)(`div`,{className:`grid content-start gap-4`,children:[(0,R.jsxs)(M,{children:[(0,R.jsxs)(`div`,{className:`grid grid-cols-1 @min-[720px]:grid-cols-[minmax(0,5fr)_minmax(0,6fr)]`,children:[(0,R.jsxs)(`div`,{className:`flex flex-col gap-5 border-b border-border px-6 py-5 md:border-b-0 md:border-r`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,R.jsxs)(`div`,{className:`flex min-w-0 items-baseline gap-2`,children:[(0,R.jsx)(`h3`,{className:`truncate text-xl font-semibold tracking-[-0.01em] text-foreground`,children:`DeepSeek Harness`}),(0,R.jsxs)(`span`,{className:`shrink-0 font-mono text-sm text-muted-foreground`,children:[`v`,Q]})]}),a===`chk`?(0,R.jsxs)(t,{size:`chip`,disabled:!0,children:[(0,R.jsx)(x,{className:`size-3 animate-spin`}),`检测中…`]}):V?.updateAvailable&&V.latest?(0,R.jsxs)(t,{className:`text-primary-foreground`,size:`chip`,onClick:()=>d(!0),children:[(0,R.jsx)(P,{className:`size-3`}),`升级到 v`,V.latest]}):K?(0,R.jsxs)(t,{size:`chip`,disabled:!0,children:[(0,R.jsx)(x,{className:`size-3 animate-spin`}),`升级中…`]}):(0,R.jsxs)(t,{className:`bg-primary/10 text-primary hover:bg-primary/15`,onClick:()=>void Z(),size:`chip`,variant:`ghost`,children:[(0,R.jsx)(x,{className:`size-3`}),`检测更新`]})]}),B?(0,R.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,R.jsx)(O,{tone:`boot`,ping:!0}),(0,R.jsx)(`span`,{className:`text-base font-semibold leading-none text-foreground`,children:z?`正在安装 DeepSeek Harness…`:`正在卸载 DeepSeek Harness…`})]}):(0,R.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,R.jsx)(O,{tone:W.tone,ping:W.tone===`ok`}),(0,R.jsx)(`span`,{className:`text-base font-semibold leading-none text-foreground`,children:W.label})]}),K&&U?(0,R.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,R.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-primary`}),`正在升级(`,U.step||U.targetVersion||``,`)…`]}):null,U?.state===`failed`?(0,R.jsxs)(`p`,{className:`text-xs text-destructive`,children:[`升级失败:`,U.lastError||`未知原因`,U.rolledBack?`(已回滚)`:``]}):null,B&&(j?.installLog??[]).length?(0,R.jsx)(`pre`,{className:`max-h-[120px] overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/70 p-3 font-mono text-xs leading-relaxed text-muted-foreground`,children:(j?.installLog??[]).slice(-6).join(`
1
+ import{F as e,I as t,L as n,N as r,O as i,R as a,S as o,U as s,V as c,a as l,b as ee,h as u,k as d,m as f,t as p,v as m,x as h,y as g}from"./supervisor-Dfq_YAmt.js";import{n as _,o as v}from"./openExternal-Ds20EFp9.js";import{n as y,t as b}from"./rocket-Dit4Xpeq.js";import{t as x}from"./refresh-cw-CFZGPyP6.js";import{t as S}from"./shield-check-D2xvjEfM.js";import{c as C,f as te,n as w,o as T,t as E}from"./supervisor-BilTj6si.js";import{t as D}from"./useSupervisorAction-DZSdzPif.js";import{c as O,i as k,n as A,o as j,t as M}from"./widgets-M2h3F-43.js";import{t as N}from"./format-QeaTKFhQ.js";var P=r(`arrow-up-right`,[[`path`,{d:`M7 7h10v10`,key:`1tivn9`}],[`path`,{d:`M7 17 17 7`,key:`1vkiza`}]]),F=r(`circle-dot`,[[`circle`,{cx:`12`,cy:`12`,r:`1`,key:`41hilf`}],[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}]]),I=r(`square-terminal`,[[`path`,{d:`m7 11 2-2-2-2`,key:`1lz0vl`}],[`path`,{d:`M11 13h4`,key:`1p7l4v`}],[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,ry:`2`,key:`1m3agn`}]]),L=s(c(),1),R=a();function z(e,t){return e===`dsh-main`||e===`supervisor-api`?`boot`:(t||``).startsWith(`inst:`)?`ok`:e===`relay`?`warn`:e.startsWith(`managed:`)?`boot`:`off`}function B(e){let t={"dsh-main":`DSH 主实例`,"supervisor-api":`管家 API`,user:`沙箱实例`,relay:`局域网隧道`,oauthCallback:`登录回调`,proxyInstance:`反代实例`,providerApi:`供应商 API`,"managed:router-daemon":`智能路由`,"managed:lan-daemon":`远程控制`,dynamic:`动态端口`},n=/^managed:(.+)$/.exec(e.role);return n?t[e.role]??n[1]:t[e.role]??e.role}function V(e,t){let n=e.owner||``;if(e.role===`proxyInstance`){let e=(n.split(`:`).pop()||``).slice(-4),r=(t??[]).find(t=>(t.accounts??[]).some(t=>(t.maskedKey||``).endsWith(e)));return r?r.name:`反代`}return n.startsWith(`inst:`)?`沙箱实例`:n.startsWith(`system:`)?`系统`:n.startsWith(`relay:`)?`局域网隧道`:n.startsWith(`dynamic:`)?`动态`:n.startsWith(`providerApi:`)?`供应商`:n.startsWith(`oauth:`)?`登录回调`:n===`router-daemon`||e.role===`managed:router-daemon`?`智能路由`:n===`lan-daemon`||e.role===`managed:lan-daemon`?`远程控制`:e.role===`oauthCallback`?`登录回调`:e.role}function H({providers:e=[]}){let{snap:t}=p(),r=t.ports?.records??null,i=(0,L.useMemo)(()=>r?[...r.filter(e=>e.role!==`supervisor-api`||e.port!==3100&&e.port!==3101)].sort((e,t)=>!!e.active==!!t.active?e.port-t.port:e.active?-1:1):null,[r]);return(0,R.jsxs)(M,{className:`flex min-h-0 flex-col overflow-hidden`,children:[(0,R.jsx)(A,{title:`运行状态`,subtitle:`核心服务与端口实时状态`,actions:i?(0,R.jsxs)(`span`,{className:`font-mono text-xs text-muted-foreground`,children:[i.length,` 端口`]}):null}),i?(0,R.jsxs)(`div`,{className:`min-h-0 overflow-x-auto`,children:[(0,R.jsxs)(`div`,{className:`grid min-w-[400px] grid-cols-[56px_minmax(0,1fr)_auto_66px] items-center gap-2 border-b border-border/60 bg-muted/60 px-4 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground`,children:[(0,R.jsx)(`span`,{children:`端口`}),(0,R.jsx)(`span`,{children:`服务`}),(0,R.jsx)(`span`,{className:`text-right`,children:`归属`}),(0,R.jsx)(`span`,{className:`text-right`,children:`状态`})]}),(0,R.jsx)(`div`,{className:`max-h-[340px] overflow-y-auto overscroll-contain`,children:i.map((t,r)=>(0,R.jsxs)(`div`,{className:n(`grid grid-cols-[56px_minmax(0,1fr)_auto_66px] items-center gap-2 px-4 py-2 hover:bg-muted/40`,r>0&&`border-t border-border/50`),children:[(0,R.jsx)(`code`,{className:`font-mono text-sm tabular-nums text-foreground`,children:t.port}),(0,R.jsx)(`div`,{className:`flex min-w-0 items-center gap-1.5`,children:(0,R.jsx)(`span`,{className:`truncate text-xs text-foreground`,children:B(t)})}),(0,R.jsx)(`div`,{className:`flex justify-end`,children:(0,R.jsx)(j,{tone:z(t.role,t.owner),children:V(t,e)})}),(0,R.jsx)(`div`,{className:`flex justify-end`,children:t.active===!0?(0,R.jsxs)(`span`,{className:`inline-flex items-center gap-1 whitespace-nowrap text-[11px] text-status-ok`,children:[(0,R.jsx)(F,{className:`size-3`}),`运行中`]}):t.active===!1?(0,R.jsxs)(`span`,{className:`inline-flex items-center gap-1 whitespace-nowrap text-[11px] text-muted-foreground`,children:[(0,R.jsx)(F,{className:`size-3 opacity-50`}),`未运行`]}):(0,R.jsxs)(`span`,{className:`inline-flex items-center gap-1 whitespace-nowrap text-[11px] text-muted-foreground`,children:[(0,R.jsx)(F,{className:`size-3 opacity-40`}),`状态未知`]})})]},t.port+`-`+t.owner))})]}):(0,R.jsx)(`div`,{className:`px-5 py-6 text-center text-xs text-muted-foreground`,children:`运行状态加载中…`})]})}function U(e){if(!e)return`未读出`;let t=String(e.state||`?`),n=e.detail?`(`+String(e.detail)+`)`:``;return(String(e.label||``)||`条目`)+` `+t+n}function W(e){return!e||e.state===`pending`?`未探测(点「重新探测」补齐)`:e.state===`error`?`探测失败:`+(e.error||`未给出原因`):e.state===`empty`?`已探测,无内容`:`已探测`+(e.at?` `+new Date(e.at).toLocaleTimeString():``)}function G(e){let t=e||{};return t.state===`on`?`在用(`+(t.server||t.pac||`地址未读出`)+`)`:t.state===`off`?`系统里明确未启用`:t.state===`unknown`?`取不到`+(t.source?`(`+t.source+`)`:``)+`,按判不出处理`:`未探测`}function K(e){return e===!0?`可达`:e===!1?`不通`:`判不出`}function q(e){return(e.section?e.section+`:`:``)+e.source+`:`+String(e.detail??``)}function J(e){return typeof e!=`number`||!Number.isFinite(e)||e<0?`时间未读出`:e<6e4?`刚刚`:e<36e5?Math.floor(e/6e4)+` 分钟前`:e<864e5?Math.floor(e/36e5)+` 小时前`:Math.floor(e/864e5)+` 天前`}function Y(e){return e===!0?`是`:e===!1?`否`:`未读出`}function X(e,t,n){let r=t||``,i=n||``,a=r&&i&&r!==i?`(两份不一致:装内核用的是壳那套,本进程解析到的是内核这套)`:``;return e+` 内核 `+(r||`未读出`)+` / 壳 `+(i||`未报`)+a}function Z(e){let t=e.ok===!0?`通`:e.ok===!1?`不通`:`判不出`;return(e.probe||`明细`)+` `+t+(e.target?`(`+e.target+`)`:``)+(typeof e.ms==`number`?` `+e.ms+` 毫秒`:``)}function ne(e,t){return e?t?`没落盘(这一拍读的是内核缓存拍)`:e.written===!0?`已写入`:e.error?`失败:`+e.error:`没落盘(也没报错误)`:`未给出(这一拍没装配)`}function re(e,t){if(t)return`读不回:`+t;if(!e)return`未读`;if(e.available===!0){let t=typeof e.at==`number`?new Date(e.at).toLocaleString():`时间未读出`,n=e.data&&e.data.browsers?e.data.browsers.length:null;return t+`(`+J(e.ageMs)+`)`+(n===null?``:`,候选 `+n+` 个`)}return e.reason===`never-written`?`这台机器还没落过盘`:`快照文件读不出或版本不符(不是没写过,得查文件)`}function ie(e){let t=e||{},n=Object.keys(t).filter(e=>t[e]!==`ok`);return n.length?`未补齐:`+n.join(`、`):`全部维度补齐`}function ae(e){let t=e&&e.name?e.name:`未定出`;return!e||!e.how?`现在会用:`+t:e.how===`user-preference`?`现在会用:`+t+`(你选的)`:e.how===`candidate-rank`?`现在会用:`+t+`(系统未报默认项,按候选次序取首个,可在此改)`:e.how===`only-installed`?`现在会用:`+t+`(本机唯一候选)`:e.how===`none-found`?`本机未探到可用浏览器,请安装或启用一个后重新探测`:`现在会用:`+t+`(系统默认项)`}var Q=`__system__`;function oe(){let[e,r]=(0,L.useState)(!1),[i,a]=(0,L.useState)(null),[s,c]=(0,L.useState)(null),[p,_]=(0,L.useState)(null),[y,b]=(0,L.useState)(!1),[S,C]=(0,L.useState)(!1),[te,w]=(0,L.useState)(null),[T,E]=(0,L.useState)(null),D=(0,L.useCallback)(async e=>{e&&b(!0);try{let t=await l.environment(e);a(t),_(null),c(null)}catch(e){c(String(e.message||e))}b(!1),l.environmentLast().then(e=>{w(e),E(null)}).catch(e=>{w(null),E(String(e.message||e))})},[]);(0,L.useEffect)(()=>{e&&D(!1)},[e,D]);let O=async e=>{C(!0);let t={ok:!1,error:`偏好写入未返回结果`};try{t=await l.setExternalBrowser(e)}catch(e){t={ok:!1,error:String(e.message||e)}}if(C(!1),!t||t.ok!==!0){c(t&&t.error||`偏好写入失败`);return}c(null),await D(!0)},k=i?.browsers??[],A=i?.sections,j=i?.pick?.stale===!0,M=i?.preference?.id||Q,N=p===null?M:p,P=A?.startup?.data,F=A?.shell?.data,I=F?.registry,z=I?.probes||[],B=F?.records||[],V=I?.latencyMs,H=I?.probesTotal??0,oe=A?.runtime?.data?.node?.version||null,$=A?.runtime?.data?.npm?.detail||null;return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 whitespace-nowrap`,children:[(0,R.jsxs)(t,{size:`sm`,variant:`ghost`,className:`h-6 gap-1 px-1.5 text-xs text-muted-foreground`,onClick:()=>r(!0),children:[(0,R.jsx)(v,{className:`size-3`}),`环境表单`]}),i?.pick?.name?(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground/70`,children:i.pick.name}):null]}),(0,R.jsx)(m,{open:e,onOpenChange:r,children:(0,R.jsxs)(g,{className:`max-w-[560px]`,children:[(0,R.jsx)(h,{children:(0,R.jsx)(o,{children:`本机环境表单`})}),(0,R.jsxs)(`div`,{className:`grid max-h-[60vh] gap-3 overflow-y-auto text-sm`,children:[(0,R.jsx)(`p`,{className:n(`text-xs`,j||!k.length?`font-semibold text-warning`:`text-muted-foreground`),children:ae(i?.pick)}),j?(0,R.jsxs)(`p`,{className:`inline-flex items-start gap-1.5 rounded-md bg-warning-background px-2 py-1.5 text-xs font-semibold text-warning`,children:[(0,R.jsx)(d,{className:`mt-0.5 size-3.5 shrink-0`}),`你先前选的浏览器已不在本机候选清单(可能已卸载或路径变更),下方选择已回落到系统判定,请重选或清除。`]}):null,s?(0,R.jsx)(`p`,{className:`text-xs text-status-error`,children:s}):null,(0,R.jsxs)(`div`,{className:`grid gap-2 rounded-md border border-border/60 px-3 py-2.5`,children:[(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:`打开地址用哪个浏览器`}),(0,R.jsxs)(f,{value:N,onValueChange:_,className:`grid gap-1.5`,children:[(0,R.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-2 text-xs`,children:[(0,R.jsx)(u,{value:Q,id:`env-pref-system`}),(0,R.jsx)(`span`,{children:`跟随系统默认(本机探不到默认项时按候选次序)`})]}),k.map(e=>(0,R.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-2 text-xs`,children:[(0,R.jsx)(u,{value:e.id,id:`env-pref-`+e.id}),(0,R.jsx)(`span`,{children:e.name||e.bin}),(0,R.jsx)(`span`,{className:`text-muted-foreground/70`,children:e.engine}),e.isDefault?(0,R.jsx)(`span`,{className:`text-muted-foreground/70`,children:`系统默认`}):null]},e.id))]}),k.length?(0,R.jsxs)(`div`,{className:`flex gap-2`,children:[(0,R.jsx)(t,{size:`sm`,variant:`outline`,disabled:S||N===M,onClick:()=>void O(N===Q?``:N),children:`保存偏好`}),(0,R.jsx)(t,{size:`sm`,variant:`ghost`,disabled:S||M===Q,onClick:()=>void O(``),children:`清除`})]}):(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`候选为空:重新探测后仍为空时,请先在系统里安装或启用一个浏览器。`})]}),(0,R.jsxs)(`div`,{className:`grid gap-1.5 rounded-md border border-border/60 px-3 py-2.5`,children:[(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:`出网条件(隔离登录窗口的分发依据)`}),(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(A?.egress)}),A?.egress?.data?(0,R.jsxs)(`div`,{className:`grid gap-0.5 text-xs`,children:[(0,R.jsxs)(`span`,{className:`text-muted-foreground`,children:[`系统代理:`,G(A?.egress?.data?.proxy)]}),Object.entries(A?.egress?.data?.targets||{}).map(([e,t])=>(0,R.jsxs)(`span`,{className:`text-muted-foreground`,children:[e,`:`,K(t?.ok),t?.stage?`(停在 `+t.stage+(t.detail?` `+t.detail:``)+`)`:``]},e)),Object.keys(A?.egress?.data?.targets||{}).length?null:(0,R.jsx)(`span`,{className:`text-muted-foreground`,children:`还没有目标域被问过:一键登录时会当场判定并记在这里。`})]}):null,A?.egress?.data?.proxy?.state===`off`?(0,R.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`没有在用系统代理时,直连不通的授权域只能靠现有浏览器窗口的既有出网路径打开(隔离冷档案会是空白页)。`}):null]}),(0,R.jsxs)(`div`,{className:`grid gap-1.5 rounded-md border border-border/60 px-3 py-2.5`,children:[(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:`运行时与 DSH(安装/升级动作的分发依据)`}),(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(A?.runtime)}),A?.runtime?.data?(0,R.jsxs)(`div`,{className:`grid gap-0.5 text-xs text-muted-foreground`,children:[(0,R.jsxs)(`span`,{children:[U(A?.runtime?.data?.node),` · `,U(A?.runtime?.data?.npm),` · `,U(A?.runtime?.data?.git)]}),A?.runtime?.data?.node?.min?(0,R.jsxs)(`span`,{className:`break-all`,children:[`Node 门槛:`,(A?.runtime?.data?.node).min,(A?.runtime?.data?.node).meets===!1?` ⇒ 本机版本低于门槛,不采纳现有 Node(会安装达标的官方版本)`:` ⇒ 已达门槛`]}):null,(0,R.jsxs)(`span`,{children:[`镜像源:`,A?.runtime?.data?.registry?.origin||`未读出`,A?.runtime?.data?.registry?.mode?`(`+A.runtime.data.registry.mode+`)`:``,` · 候选 `+(A?.runtime?.data?.registry?.candidates||[]).length+` 个`]}),(0,R.jsxs)(`span`,{className:`break-all`,children:[`全局前缀:`,A?.runtime?.data?.prefix||`未实测(npm root -g 未返回)`]})]}):null,(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:`桌面壳所见(装内核时真正用的那一套,与上面的内核读数并排对照)`}),(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(A?.shell)}),F?(0,R.jsxs)(`div`,{className:`grid gap-0.5 text-xs text-muted-foreground`,children:[(0,R.jsx)(`span`,{children:F.available===!0?`壳上报于 `+J(F.ageMs)+`,写入者 `+(F.writtenBy||`未署名`)+`(报告版本 `+(F.schema??`未读出`)+`)`:F.reason===`never-written`?`这台机器的壳还没报过:内核由命令行或别的进程拉起时这是常态,不是故障`:`壳报的文件读不出或版本不符(不是没写过,得查那个文件)`}),F.available===!0?(0,R.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,R.jsx)(`span`,{className:`break-all`,children:X(`Node:`,oe,F.node?.version)}),(0,R.jsx)(`span`,{className:`break-all`,children:X(`npm:`,$,F.npm?.version)}),(0,R.jsx)(`span`,{className:`break-all`,children:X(`镜像源:`,A?.runtime?.data?.registry?.origin,F.registry?.best)}),(0,R.jsx)(`span`,{className:`break-all`,children:X(`全局前缀:`,A?.runtime?.data?.prefix,F.prefix?.dir)}),F.node&&F.node.ok!==!0?(0,R.jsxs)(`span`,{children:[`壳判 Node 达标:`,Y(F.node.ok),`(`,F.node.version||`版本未报`,`,门槛 `,F.node.min||`未报`,`)`]}):null,F.prefix&&F.prefix.writable!==!0?(0,R.jsxs)(`span`,{className:`break-all`,children:[`壳判前缀可写:`,Y(F.prefix.writable),F.prefix.why?`(`+F.prefix.why+`)`:``]}):null,z.length||I?.best?(0,R.jsxs)(`span`,{className:`break-all`,children:[`壳的镜像源候选:`,z.map(e=>(e.url||`?`)+` `+K(e.ok)).join(`、`),typeof V==`number`?`(择优选中用时 `+V+` 毫秒)`:``,H>z.length?`(报告里共 `+H+` 个候选,此处只列前 `+z.length+` 个)`:``]}):null,B.length?(0,R.jsxs)(`span`,{children:[`壳的探测明细 `,B.length,` 条:`,B.slice(0,8).map(Z).join(`;`),B.length>8?`…其余见内核快照文件`:``,F.droppedRecords?`(报告送达时被截断 `+F.droppedRecords+` 条)`:``]}):null]}):null]}):null,(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(A?.dsh)}),A?.dsh?.data?(0,R.jsxs)(`div`,{className:`grid gap-0.5 text-xs text-muted-foreground`,children:[(0,R.jsxs)(`span`,{children:[U(A?.dsh?.data?.dsh),` · `,U(A?.dsh?.data?.selfUpdate)]}),(0,R.jsxs)(`span`,{children:[`看护:`,A?.dsh?.data?.managed?`守卫托管`:`未托管`,A?.dsh?.data?.phase?` · `+A.dsh.data.phase:``]})]}):null]}),(0,R.jsxs)(`div`,{className:`grid gap-1.5 rounded-md border border-border/60 px-3 py-2.5`,children:[(0,R.jsx)(`span`,{className:`text-xs font-medium`,children:`启动既成事实(守卫这一拍真的跑过什么)`}),(0,R.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:W(A?.startup)}),P?(0,R.jsxs)(`div`,{className:`grid gap-0.5 text-xs text-muted-foreground`,children:[(0,R.jsxs)(`span`,{children:[`守卫启动于 `,typeof P.bootAt==`number`?new Date(P.bootAt).toLocaleTimeString():`未读出`,`,环境表单首拍排在启动后 `,P.envDelayMs??`未读出`,` 毫秒`]}),(0,R.jsxs)(`span`,{children:[`选路:自动启动 `,Y(P.routerAutostart),`,模式 `,P.routerMode||`未读出(这一拍没走到那步)`]}),(0,R.jsxs)(`span`,{children:[`更新检查:`,P.updateCheck?P.updateCheck.enabled?`开(首查排在启动后 `+(P.updateCheck.initialDelayMs??`未读出`)+` 毫秒,之后每 `+(P.updateCheck.intervalMs??`未读出`)+` 毫秒)`:`关(配置里就禁掉了,这同样是一条既成事实)`:`未记录`]}),(0,R.jsxs)(`span`,{children:[`壳看护:`,Y(P.shellWatchdog)]}),(0,R.jsx)(`span`,{children:P.lastRefresh?`最近一次表单刷新于 `+(typeof P.lastRefresh.at==`number`?new Date(P.lastRefresh.at).toLocaleTimeString():`未读出`)+`,耗时 `+(P.lastRefresh.tookMs??`未读出`)+` 毫秒,浏览器 `+(P.lastRefresh.browsers??`未读出`)+` 个,分发依据 `+(P.lastRefresh.pick||`未定出`)+`,落盘 `+Y(P.lastRefresh.snapshotWritten)+`;`+ie(P.lastRefresh.dims):`这一拍还没跑过表单刷新(首拍排在上面那个延迟之后)`})]}):null]}),(0,R.jsxs)(`dl`,{className:`grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-xs`,children:[(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`平台`}),(0,R.jsx)(`dd`,{className:`font-mono`,children:[i?.identity?.platform,i?.identity?.arch].filter(Boolean).join(` / `)||`—`}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`图形会话`}),(0,R.jsx)(`dd`,{children:i?.session?.available?`可用(`+(i?.session?.reason||`—`)+`)`:`不可用(`+(i?.session?.reason||`—`)+`)`}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`系统默认项`}),(0,R.jsx)(`dd`,{children:i?.default?i.default.id+`(来源 `+(i.default.source||`未读出`)+`)`:`未读出`}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`候选`}),(0,R.jsx)(`dd`,{children:k.length?k.map(e=>(e.name||e.bin)+`[`+(e.sources||[]).join(`+`)+`]`).join(`、`):`无`}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`探测留痕`}),(0,R.jsx)(`dd`,{className:`grid gap-0.5`,children:(i?.probed??[]).map((e,t)=>(0,R.jsx)(`span`,{className:`text-muted-foreground/80`,children:q(e)},t))}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`快照落盘`}),(0,R.jsxs)(`dd`,{className:`break-all font-mono text-muted-foreground/80`,children:[ne(i?.snapshot,i?.cached===!0),(0,R.jsxs)(`span`,{className:`text-muted-foreground/60`,children:[` `,i?.snapshot?.path||`未给出路径`]})]}),(0,R.jsx)(`dt`,{className:`text-muted-foreground`,children:`上一拍留痕`}),(0,R.jsx)(`dd`,{className:`text-muted-foreground`,children:re(te,T)})]})]}),(0,R.jsxs)(ee,{children:[(0,R.jsxs)(t,{variant:`outline`,disabled:y,onClick:()=>void D(!0),children:[(0,R.jsx)(x,{className:`size-4`}),y?`探测中…`:`重新探测`]}),(0,R.jsx)(t,{onClick:()=>r(!1),children:`关闭`})]})]})})]})}var $=new Set([`dist_registry_selected`,`gui_autostart_changed`,`autostart_changed`,`lan_panel_changed`,`lan_harness_token_updated`]);function se(){let{snap:r}=p(),{busy:a,run:s}=D(),c=e(),[u,d]=(0,L.useState)(!1),[f,E]=(0,L.useState)(null),A=r.status,j=A?.native,N=j?.installed??!1,F=j?.state||(N?`installed`:`uninstalled`),z=F===`installing`,B=z||F===`uninstalling`,V=A?.version,U=A?.upgrade,W=w[A?.phase??``]??{label:A?.phase||`未知`,tone:`off`},G=!!A?.dshPid,K=U?.state===`running`,q=(0,L.useMemo)(()=>r.events.filter(e=>!$.has(e.type)),[r.events]);async function J(){await s(`dsh`,()=>G?l.lifecycleStop(`dsh`):l.lifecycleStart(`dsh`),{success:G?`正在停止 DSH…`:`正在启动 DSH…`})}async function Y(){await c({title:`停止 DSH?`,description:`主干 DeepSeek Harness 正在运行;停止会中断进行中的请求,远程访问同时不可用。`,confirmText:`停止 DSH`})&&await J()}async function X(){await s(`web`,()=>_(()=>l.instanceOpenWeb(`main`)).then(()=>void 0))}async function Z(){await s(`chk`,async()=>{let e=await l.nativeCheckUpdate();if(e?.ok===!1){i.error(e.error||`检测失败`);return}e?.updateAvailable&&e.latest?i.success(`发现新版本 `+e.latest+(e.installed?`(当前 `+e.installed+`),可一键升级`:``)):i.success(`已是最新版本`+(e.installed?`(`+e.installed+`)`:``))})}async function ne(){d(!1),await s(`upg`,()=>l.nativeUpgrade(),{success:`升级已开始,请耐心等待…`})}async function re(){await c({title:`在线安装最新版 DeepSeek Harness?`,description:`需数分钟,自动适配最快镜像源。`,confirmText:`安装`})&&await s(`inst`,()=>l.nativeInstall(),{success:`开始安装 DeepSeek Harness…`})}async function ie(){await c({title:`彻底卸载 DeepSeek Harness?`,description:`删除全部文件、数据、缓存与日志,不留残留。`,confirmText:`卸载 DSH`,tone:`destructive`})&&await s(`uni`,()=>l.nativeUninstall(),{success:`开始卸载…`})}(0,L.useEffect)(()=>{N&&l.instances().then(e=>{let t=e?.native?.guardian;typeof t==`boolean`&&E(t)}).catch(()=>{})},[N,A?.dshPid]);async function ae(){let e=f!==!0;await s(`gu`,()=>l.nativeSettings({guardian:e}).then(e=>{let t=e?.main?.guardian;return typeof t==`boolean`&&E(t),e}),{success:e?`已开启 DSH 进程守护(崩溃自动拉起)`:`已关闭 DSH 进程守护(崩溃后不再自动拉起)`,refresh:!1})}let Q=N&&(j?.version||V?.installed)||`—`;return(0,R.jsxs)(`div`,{className:`grid content-start gap-4`,children:[(0,R.jsxs)(M,{children:[(0,R.jsxs)(`div`,{className:`grid grid-cols-1 @min-[720px]:grid-cols-[minmax(0,5fr)_minmax(0,6fr)]`,children:[(0,R.jsxs)(`div`,{className:`flex flex-col gap-5 border-b border-border px-6 py-5 md:border-b-0 md:border-r`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,R.jsxs)(`div`,{className:`flex min-w-0 items-baseline gap-2`,children:[(0,R.jsx)(`h3`,{className:`truncate text-xl font-semibold tracking-[-0.01em] text-foreground`,children:`DeepSeek Harness`}),(0,R.jsxs)(`span`,{className:`shrink-0 font-mono text-sm text-muted-foreground`,children:[`v`,Q]})]}),a===`chk`?(0,R.jsxs)(t,{size:`chip`,disabled:!0,children:[(0,R.jsx)(x,{className:`size-3 animate-spin`}),`检测中…`]}):V?.updateAvailable&&V.latest?(0,R.jsxs)(t,{className:`text-primary-foreground`,size:`chip`,onClick:()=>d(!0),children:[(0,R.jsx)(P,{className:`size-3`}),`升级到 v`,V.latest]}):K?(0,R.jsxs)(t,{size:`chip`,disabled:!0,children:[(0,R.jsx)(x,{className:`size-3 animate-spin`}),`升级中…`]}):(0,R.jsxs)(t,{className:`bg-primary/10 text-primary hover:bg-primary/15`,onClick:()=>void Z(),size:`chip`,variant:`ghost`,children:[(0,R.jsx)(x,{className:`size-3`}),`检测更新`]})]}),B?(0,R.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,R.jsx)(O,{tone:`boot`,ping:!0}),(0,R.jsx)(`span`,{className:`text-base font-semibold leading-none text-foreground`,children:z?`正在安装 DeepSeek Harness…`:`正在卸载 DeepSeek Harness…`})]}):(0,R.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,R.jsx)(O,{tone:W.tone,ping:W.tone===`ok`}),(0,R.jsx)(`span`,{className:`text-base font-semibold leading-none text-foreground`,children:W.label})]}),K&&U?(0,R.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,R.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-primary`}),`正在升级(`,U.step||U.targetVersion||``,`)…`]}):null,U?.state===`failed`?(0,R.jsxs)(`p`,{className:`text-xs text-destructive`,children:[`升级失败:`,U.lastError||`未知原因`,U.rolledBack?`(已回滚)`:``]}):null,B&&(j?.installLog??[]).length?(0,R.jsx)(`pre`,{className:`max-h-[120px] overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/70 p-3 font-mono text-xs leading-relaxed text-muted-foreground`,children:(j?.installLog??[]).slice(-6).join(`
2
2
  `)}):null]}),(0,R.jsx)(`div`,{className:`flex items-center bg-[image:var(--panel-accent-gradient)] px-6 py-5`,children:(0,R.jsxs)(`div`,{className:`grid w-full grid-cols-2 gap-x-6 gap-y-4 @min-[560px]:grid-cols-4`,children:[(0,R.jsx)(k,{icon:(0,R.jsx)(te,{className:`size-4`}),label:`端口`,value:A?.dshPort?String(A.dshPort):`—`,mono:!0}),(0,R.jsx)(k,{icon:(0,R.jsx)(I,{className:`size-4`}),label:`PID`,value:A?.dshPid?String(A.dshPid):`—`,mono:!0}),(0,R.jsx)(k,{icon:(0,R.jsx)(x,{className:`size-4`}),label:`重启次数`,value:String(A?.restartCount??0),mono:!0}),(0,R.jsx)(k,{icon:(0,R.jsx)(P,{className:`size-4`}),label:`最近故障`,value:A?.lastFailure?T(A?.lastFailure):`无`,warn:!!A?.lastFailure})]})})]}),(0,R.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 border-t border-border/60 px-6 py-3`,children:[(0,R.jsx)(`div`,{className:`hidden lg:block`,children:(0,R.jsx)(ce,{})}),(0,R.jsxs)(`div`,{className:`ml-auto flex flex-wrap items-center gap-2`,children:[!N&&!B?(0,R.jsxs)(t,{size:`sm`,disabled:a===`inst`,onClick:()=>void re(),children:[(0,R.jsx)(b,{className:`size-4`}),`安装 DSH`]}):N&&!B&&!K?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(t,{disabled:!G,onClick:()=>void X(),size:`sm`,variant:`outline`,className:`hidden md:inline-flex`,children:[(0,R.jsx)(v,{className:`size-4`}),`DSH Web`]}),(0,R.jsx)(t,{disabled:a===`dsh`,onClick:()=>void(G?Y():J()),size:`sm`,variant:`outline`,children:G?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(y,{className:`size-4 text-status-error`}),`停止 DSH`]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(b,{className:`size-4 text-primary`}),`启动 DSH`]})}),(0,R.jsx)(`span`,{"aria-hidden":`true`,className:`mx-1 h-5 w-px bg-border`}),(0,R.jsxs)(t,{className:`h-[30px]`,disabled:a===`gu`||f===null,onClick:()=>void ae(),size:`sm`,variant:`outline`,children:[(0,R.jsx)(S,{className:n(`size-4`,f===!0?`text-status-ok`:`text-muted-foreground`)}),f===!0?`停止守护`:`启动守护`]})]}):null,N&&!B?(0,R.jsx)(R.Fragment,{children:(0,R.jsxs)(t,{className:`hidden h-[30px] md:inline-flex`,disabled:a===`uni`,onClick:()=>void ie(),size:`sm`,variant:`destructive`,children:[(0,R.jsx)(C,{className:`size-4`}),`卸载 DSH`]})}):null]})]})]}),(0,R.jsxs)(`div`,{className:`grid items-start gap-4 @min-[860px]:grid-cols-[minmax(0,1fr)_420px]`,children:[(0,R.jsx)(le,{events:q}),(0,R.jsx)(H,{providers:r.providers?.providers??[]})]}),(0,R.jsx)(m,{open:u,onOpenChange:d,children:(0,R.jsxs)(g,{className:`max-w-[420px]`,children:[(0,R.jsx)(h,{children:(0,R.jsx)(o,{children:`升级 DeepSeek Harness`})}),(0,R.jsxs)(`div`,{className:`grid gap-3`,children:[(0,R.jsxs)(`div`,{className:`flex items-center justify-center gap-3 rounded-md bg-muted px-4 py-3`,children:[(0,R.jsxs)(`div`,{className:`text-center`,children:[(0,R.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`当前版本`}),(0,R.jsx)(`strong`,{className:`font-mono text-base text-foreground`,children:V?.installed||Q})]}),(0,R.jsx)(P,{className:`size-4 text-muted-foreground`}),(0,R.jsxs)(`div`,{className:`text-center`,children:[(0,R.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`新版本`}),(0,R.jsx)(`strong`,{className:`font-mono text-base text-primary`,children:V?.latest||`—`})]})]}),(0,R.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`升级将先停止 DSH、安装新版本后自动拉起(需数分钟)。期间进行中的请求会中断,失败会自动回滚到当前版本。`})]}),(0,R.jsxs)(ee,{children:[(0,R.jsx)(t,{onClick:()=>d(!1),variant:`outline`,children:`取消`}),(0,R.jsx)(t,{disabled:a===`upg`||K,onClick:()=>void ne(),children:a===`upg`||K?`升级中…`:`开始升级`})]})]})})]})}function ce(){let[e,t]=(0,L.useState)(null),[r,i]=(0,L.useState)(null);(0,L.useEffect)(()=>{let e=!0,n=async()=>{let[n,r]=await Promise.all([l.nodeLts().catch(()=>null),l.envStatus().catch(()=>null)]);e&&(t(n),i(r?.catalog?.items??null))};n();let r=setInterval(n,6e5);return()=>{e=!1,clearInterval(r)}},[]);let a=Object.entries(r??{}).filter(([,e])=>e.required);return!e?.current&&a.length===0?(0,R.jsx)(`span`,{className:`min-w-[120px] text-xs text-muted-foreground`,children:`环境检测…`}):(0,R.jsxs)(`span`,{className:`inline-flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,R.jsx)(`span`,{className:`whitespace-nowrap`,children:`环境检测`}),a.map(([e,t])=>{let r=t.state===`ok`||t.state===`configured`;return(0,R.jsxs)(`span`,{title:t.detail||void 0,className:n(`inline-flex items-center gap-1 whitespace-nowrap rounded-full px-2 py-0.5`,r?`text-muted-foreground/70`:`bg-warning-background font-semibold text-warning`),children:[!r&&(0,R.jsx)(d,{className:`size-3`}),t.label,` `,t.detail||`—`]},e)}),(0,R.jsx)(oe,{}),e?.ltsLine===!1?(0,R.jsxs)(`span`,{className:`inline-flex items-center gap-1 whitespace-nowrap rounded-full bg-warning-background px-2 py-0.5 font-semibold text-warning`,title:e.suggested||void 0,children:[(0,R.jsx)(d,{className:`size-3`}),`非 LTS 线(建议偶数主版本)`]}):e?.ltsLine===!0?(0,R.jsx)(`span`,{className:`hidden whitespace-nowrap text-muted-foreground/70 sm:inline`,children:`LTS 线`}):null]})}function le({events:e}){let[t,n]=(0,L.useState)(12),r=e.length;(0,L.useEffect)(()=>{n(12)},[e]);let i=(0,L.useRef)(null),a=(0,L.useRef)(!1);(0,L.useEffect)(()=>{let e=i.current;if(!e)return;let t=new IntersectionObserver(e=>{e.some(e=>e.isIntersecting)&&(a.current||(a.current=!0,n(e=>Math.min(e+12,r)),setTimeout(()=>{a.current=!1},80)))},{rootMargin:`120px 0px`});return t.observe(e),()=>t.disconnect()},[r]);let o=e.slice(0,t),s=t<r;return(0,R.jsxs)(M,{className:`flex min-h-0 flex-col overflow-hidden`,children:[(0,R.jsx)(A,{title:`事件日志`,subtitle:`核心运行状态遥测`,actions:(0,R.jsx)(`span`,{className:`font-mono text-xs text-muted-foreground`,children:r})}),r?(0,R.jsxs)(`div`,{className:`flex max-h-[450px] min-h-0 flex-col overflow-y-auto overscroll-contain`,children:[o.map((e,t)=>(0,R.jsx)(ue,{e},e.seq??t)),(0,R.jsx)(`div`,{ref:i,className:`px-5 py-2 text-center text-[11px] text-muted-foreground`,children:s?`下滑加载更多…`:`已加载全部`})]}):(0,R.jsx)(`div`,{className:`px-5 py-6 text-center text-xs text-muted-foreground`,children:`暂无核心运行状态事件`})]})}function ue({e}){let t=fe[e.type]??`boot`,n=E[e.type]??e.type,r=de(e);return(0,R.jsxs)(`div`,{className:`grid min-w-0 grid-cols-[64px_auto_minmax(0,1fr)] items-center gap-2.5 border-b border-border/60 px-5 py-2 last:border-b-0 max-[640px]:grid-cols-[56px_auto_minmax(0,1fr)] max-[640px]:gap-2`,children:[(0,R.jsx)(`span`,{className:`text-xs tabular-nums text-muted-foreground`,children:N(e.ts)}),(0,R.jsx)(j,{tone:t,children:n}),(0,R.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:r})]})}function de(e){let t=e.data;if(!t)return``;let n=e=>Number(e??0).toLocaleString(`en-US`);if(typeof t.message==`string`)return t.message;if(typeof t.reason==`string`)return T(t.reason);if(typeof t.desired==`string`)return`期望 `+t.desired;if(e.type===`router_usage`)return(t.model||``)+(t.model?` · `:``)+n(t.tokens)+` tokens`;if(e.type===`router_pick`)return[t.provider||``,t.key||``].filter(Boolean).join(` · `);if(e.type===`account_ready`||e.type===`account_frozen`||e.type===`account_banned`||e.type===`account_recovered`||e.type===`account_review`||e.type===`account_exhausted`)return(t.key||``)+(t.key?` · `:``)+(t.provider||``);if(e.type===`provider_quota_refreshed`)return(t.provider||``)+` 额度已刷新`;if(e.type===`proxy_update_available`)return[t.pkg||``,t.from||``,t.to||``].filter(Boolean).join(` → `);if(e.type===`proxy_instance_started`)return`port=`+(t.port??``)+(t.pid?` pid=`+t.pid:``);if(e.type===`harness_guardian_changed`||e.type===`inst_guardian_changed`)return(t.name||(t.id===`main`?`原生 DSH`:t.id||`实例`))+` · 进程守护`+(t.enabled===!0?` → 开启`:` → 关闭`);if(e.type===`harness_remote_changed`||e.type===`inst_remote_changed`)return(t.name||(t.id===`main`?`原生 DSH`:t.id||`实例`))+` · 远程控制 → `+(t.mode===`lan`?`局域网`:t.mode===`wan`?`公网`:`关闭`);if(e.type===`harness_remote_token_changed`||e.type===`inst_remote_token_changed`)return(t.name||(t.id===`main`?`原生 DSH`:t.id||`实例`))+` · 访问令牌`+(t.tokenSet===!0?` → 已设置`:` → 已清除`);let r=[];return t.pid!==void 0&&r.push(`pid=`+t.pid),t.port!==void 0&&r.push(`port=`+String(t.port)),t.version!==void 0&&r.push(`v`+String(t.version)),t.model&&t.tokens!==void 0&&r.push(n(t.tokens)+` tok`),t.ms!==void 0&&r.push(n(t.ms)+`ms`),r.join(` · `)}var fe={running:`ok`,adopted:`ok`,spawned:`ok`,main_instance_registered:`ok`,upgrade_installed:`ok`,upgrade_done:`ok`,api_listening:`ok`,account_ready:`ok`,account_confirmed:`ok`,account_recovered:`ok`,proxy_instance_started:`ok`,proxy_update_applied:`ok`,router_provider_activated:`ok`,router_provider_endpoint:`ok`,inst_running:`ok`,inst_added:`ok`,inst_started:`ok`,lan_instance_started:`ok`,frpc_installed:`ok`,frpc_started:`ok`,plugin_install_done:`ok`,native_installed:`ok`,inst_upgraded:`ok`,plugin_update_done:`ok`,account_frozen:`err`,account_banned:`err`,harness_exited:`err`,unhealthy:`err`,spawn_failed:`err`,spawn_error:`err`,upgrade_failed:`err`,api_error:`err`,api_offline:`err`,proxy_instance_failed:`err`,inst_failed:`err`,inst_start_failed:`err`,native_install_failed:`err`,native_uninstall_failed:`err`,plugin_install_job_failed:`err`,plugin_update_job_failed:`err`,plugin_uninstall_job_failed:`err`,frpc_install_failed:`err`,router_stream_aborted:`err`,sigkill_sent:`err`,start_timeout:`err`,crash_loop_entered:`err`,guard_exit:`warn`,version_check_failed:`warn`,restart_triggered:`warn`,harness_not_installed:`warn`,sigterm_sent:`warn`,account_review:`warn`,harness_guardian_changed:`warn`,inst_guardian_changed:`warn`,harness_remote_changed:`warn`,inst_remote_changed:`warn`,harness_remote_token_changed:`warn`,inst_remote_token_changed:`warn`,lan_frp_blocked:`warn`,proxy_update_available:`warn`,upgrade_started:`warn`,upgrade_stopping_harness:`warn`,inst_restarted:`warn`,native_uninstall_started:`warn`,account_discarded:`off`,router_stopped:`off`,proxy_instance_stopped:`off`,inst_stopped:`off`,inst_removed:`off`,lan_instance_removed:`off`,frpc_stopped:`off`,plugin_uninstall_done:`off`,native_uninstalled:`off`,upgrade_skipped:`off`,router_provider_deactivated:`off`,stop:`off`};export{se as OverviewPage};
@@ -1 +1 @@
1
- import{E as e,F as t,I as n,L as r,N as i,O as a,R as o,S as s,U as c,V as l,_ as u,a as d,d as f,f as p,h as m,l as h,m as g,p as _,u as v,v as y,x as b,y as x}from"./supervisor-Dfq_YAmt.js";import{n as S,t as C}from"./rocket-Dit4Xpeq.js";import{t as w}from"./refresh-cw-CFZGPyP6.js";import{t as T}from"./jobs-BjLbfJTM.js";import{c as E,u as D}from"./supervisor-BZTzTZDT.js";import{t as O}from"./useSupervisorAction-DZSdzPif.js";import{n as k,o as A,t as j}from"./widgets-M2h3F-43.js";var M=i(`search`,[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]),N=i(`store`,[[`path`,{d:`M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5`,key:`slp6dd`}],[`path`,{d:`M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244`,key:`o0xfot`}],[`path`,{d:`M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05`,key:`wn3emo`}]]),P=c(l(),1);function F(e){return e>=1073741824?`${(e/1024/1024/1024).toFixed(1)} GB`:e>=1048576?`${(e/1024/1024).toFixed(0)} MB`:e>=1024?`${(e/1024).toFixed(0)} KB`:`${e} B`}var I=o(),L=24;async function R(e,t,n){if(!e.length)return;let r=a.loading(`正在`+t+` `+n+` 个插件…(0/`+e.length+`)`),i=0,o=0;for(let s of e){let c=await T(()=>d.pluginInstallStatus(s));c.state===`done`?i++:c.state===`failed`&&o++,a.loading(`正在`+t+` `+n+` 个插件…(`+(i+o)+`/`+e.length+`)`,{id:r})}o===0?a.success(t+`完成(`+i+`/`+e.length+`)`,{id:r}):a.warning(t+`结束:成功 `+i+`,失败 `+o,{id:r})}async function z(e,t,n=3e5,r=2e3){let i=await e(),a=Date.now()+n;for(;t(i)&&Date.now()<a;)await new Promise(e=>setTimeout(e,r)),i=await e();return i}function B(){let[e,t]=(0,P.useState)(`market`),[i,a]=(0,P.useState)(0);return(0,I.jsxs)(`div`,{className:`grid content-start gap-4`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,I.jsx)(`div`,{className:`flex gap-1 rounded-lg bg-muted p-1`,children:[`market`,`installed`].map(i=>(0,I.jsxs)(n,{className:r(`font-medium`,e===i?`bg-card text-foreground shadow-sm`:`bg-transparent text-muted-foreground hover:bg-card/60 hover:text-foreground`),onClick:()=>t(i),size:`sm`,variant:`ghost`,children:[i===`market`?(0,I.jsx)(N,{className:`size-3.5`}):(0,I.jsx)(D,{className:`size-3.5`}),i===`market`?`插件商店`:`已安装`]},i))}),e===`market`?(0,I.jsx)(V,{onSettled:()=>a(e=>e+1)}):null]}),e===`market`?(0,I.jsx)(H,{nonce:i}):(0,I.jsx)(G,{})]})}function V({onSettled:e}){let[t,i]=(0,P.useState)(!1);async function o(){i(!0);try{let t=await d.market(!0),n=t.building?await z(()=>d.market(),e=>!!e.building):t;n.error?a.error(`索引刷新失败:`+n.error+`(暂用旧索引的 `+n.plugins.length+` 个)`):n.plugins.length?a.success(`插件索引已刷新(`+n.plugins.length+` 个)`):a.error(`索引刷新失败:无结果`),e?.()}catch(e){a.error(String(e))}i(!1)}return(0,I.jsxs)(n,{disabled:t,onClick:()=>void o(),size:`chip`,variant:`outline`,children:[(0,I.jsx)(w,{className:r(`size-3.5`,t&&`animate-spin`)}),`刷新`]})}function H({nonce:e=0}){let[t,i]=(0,P.useState)(null),[o,c]=(0,P.useState)(!1),[l,S]=(0,P.useState)(null),[C,w]=(0,P.useState)(``),[E,D]=(0,P.useState)(`all`),[O,k]=(0,P.useState)(`all`),[j,N]=(0,P.useState)(0),[F,R]=(0,P.useState)(null),[B,V]=(0,P.useState)([]),[H,G]=(0,P.useState)(`native`);(0,P.useEffect)(()=>{let e=!0;return(async()=>{try{let t=await d.market();if(t.building&&(e&&c(!0),t=await z(()=>d.market(),e=>!!e.building)),!e)return;c(!1),i(t.plugins.length?t:null),S(t.plugins.length?null:t.error||`索引为空,点「刷新」重建`),N(L)}catch(t){e&&(c(!1),S(String(t)))}})(),()=>{e=!1}},[e]);let K=(0,P.useMemo)(()=>{if(!t)return[];let e=C.trim().toLowerCase();return t.plugins.filter(t=>(E===`all`||t.category===E)&&(O===`all`||t.source===O)&&(!e||(t.name+` `+(t.description||``)).toLowerCase().includes(e)))},[t,C,E,O]),q=(0,P.useMemo)(()=>{let e={};for(let n of t?.plugins??[])e[n.category]=(e[n.category]||0)+1;return Object.entries(e).sort((e,t)=>t[1]-e[1])},[t]);async function J(e){R(e),G(`native`);try{let e=await d.instances();V((e.instances??[]).filter(e=>e.domain===`sandbox`).map(e=>({id:e.id,name:e.name})))}catch{V([])}}async function Y(){if(F)try{let e=await d.pluginInstall(F.name,H);if(e.ok===!1){a.error(e.error||`安装失败`);return}if(R(null),e.jobId){let t=a.loading(`正在安装 `+F.name+`…`),n=await T(()=>d.pluginInstallStatus(e.jobId));n.state===`done`?a.success(`已安装 `+F.name,{id:t}):n.state===`failed`?a.error(`安装失败:`+(n.error||`未知原因`),{id:t}):a.warning(`安装仍在进行(超时未完成,可稍后查看)`,{id:t})}else a.success(`安装任务已提交`)}catch(e){a.error(String(e))}}return(0,I.jsxs)(`div`,{className:`grid content-start gap-3`,children:[(0,I.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,I.jsxs)(`div`,{className:`relative min-w-[220px] flex-1`,children:[(0,I.jsx)(M,{className:`absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground`}),(0,I.jsx)(u,{className:`pl-8`,placeholder:`搜索插件名称、描述…`,value:C,onChange:e=>w(e.target.value)})]}),(0,I.jsxs)(h,{value:E,onValueChange:D,children:[(0,I.jsx)(p,{className:`h-9 w-[150px] shrink-0`,children:(0,I.jsx)(_,{placeholder:`全部分类`})}),(0,I.jsxs)(v,{children:[(0,I.jsx)(f,{value:`all`,children:`全部分类`}),q.map(([e,t])=>(0,I.jsxs)(f,{value:e,children:[e,` (`,t,`)`]},e))]})]}),(0,I.jsxs)(h,{value:O,onValueChange:k,children:[(0,I.jsx)(p,{className:`h-9 w-[130px] shrink-0`,children:(0,I.jsx)(_,{placeholder:`全部来源`})}),(0,I.jsxs)(v,{children:[(0,I.jsx)(f,{value:`all`,children:`全部来源`}),(0,I.jsx)(f,{value:`npm`,children:`npm`}),(0,I.jsx)(f,{value:`github`,children:`GitHub`}),(0,I.jsx)(f,{value:`community`,children:`社区`}),(0,I.jsx)(f,{value:`official`,children:`官方`})]})]})]}),t?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`共 `,t.plugins.length,` 个插件 · 更新 `,t.indexedAt?new Date(t.indexedAt).toLocaleString():`—`,` · npm `,t.sources?.npm||0,` · GitHub `,t.sources?.github||0,` · 社区 `,t.sources?.community||0]}),K.length?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`div`,{className:`grid grid-cols-1 gap-3 @min-[640px]:grid-cols-2 @min-[1000px]:grid-cols-3`,children:K.slice(0,j).map(e=>(0,I.jsxs)(`div`,{className:`flex min-h-[150px] flex-col rounded-lg border border-border bg-card p-4`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,I.jsx)(`strong`,{className:`truncate font-mono text-sm text-foreground`,children:e.name}),(0,I.jsx)(A,{tone:W(e.source),children:U(e.source)})]}),(0,I.jsx)(`p`,{className:`mt-2 line-clamp-3 min-h-[36px] text-xs leading-relaxed text-muted-foreground`,children:e.description||`(无描述)`}),(0,I.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,I.jsx)(`span`,{className:`rounded bg-muted px-1.5 py-0.5`,children:e.category}),e.version?(0,I.jsxs)(`span`,{className:`font-mono`,children:[`v`,e.version]}):null,e.stars?(0,I.jsxs)(`span`,{children:[`⭐`,e.stars]}):null]}),(0,I.jsxs)(`div`,{className:`mt-auto flex items-center justify-between gap-2 pt-3`,children:[(0,I.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:e.author||``}),(0,I.jsx)(n,{onClick:()=>void J(e),size:`chip`,children:`安装`})]})]},e.name))}),j<K.length?(0,I.jsxs)(n,{className:`justify-self-center`,onClick:()=>N(e=>e+L),variant:`outline`,children:[`加载更多(`,j,`/`,K.length,`)`]}):null]}):(0,I.jsx)(`div`,{className:`grid place-items-center rounded-lg border border-dashed border-border py-16 text-sm text-muted-foreground`,children:`无匹配插件`})]}):(0,I.jsx)(`div`,{className:`grid place-items-center py-20 text-sm text-muted-foreground`,children:o?`正在构建插件索引(首次约需数分钟,可留在本页)…`:l||`加载插件索引…`}),(0,I.jsx)(y,{open:!!F,onOpenChange:e=>!e&&R(null),children:(0,I.jsxs)(x,{className:`max-w-[400px]`,children:[(0,I.jsx)(b,{children:(0,I.jsxs)(s,{children:[`安装插件 — `,F?.name]})}),(0,I.jsx)(`div`,{className:`grid gap-2`,children:(0,I.jsx)(g,{value:H,onValueChange:G,className:`grid gap-2`,children:[[`native`,`原生实例`],[`all`,`所有实例(含原生)`]].concat(B.map(e=>[`id:`+e.id,e.name+`(`+e.id.slice(0,8)+`…)`])).map(([e,t])=>(0,I.jsxs)(`label`,{className:r(`flex cursor-pointer items-center gap-2 rounded-md border px-3 py-2 text-sm`,H===e?`border-primary/40 bg-primary/[0.05] text-foreground`:`border-border text-muted-foreground hover:bg-muted`),children:[(0,I.jsx)(m,{value:e}),t]},e))})}),(0,I.jsxs)(`div`,{className:`mt-3 flex justify-end gap-2`,children:[(0,I.jsx)(n,{onClick:()=>R(null),variant:`outline`,children:`取消`}),(0,I.jsx)(n,{onClick:()=>void Y(),children:`开始安装`})]})]})})]})}var U=e=>({npm:`npm`,github:`GitHub`,community:`社区`,official:`官方`})[e]??e,W=e=>e===`official`?`boot`:e===`npm`?`ok`:e===`github`?`warn`:`off`;function G(){let[i,o]=(0,P.useState)(null),[s,c]=(0,P.useState)(`all`),[l,u]=(0,P.useState)(new Set),[f,p]=(0,P.useState)(new Map),[m,h]=(0,P.useState)(!1),{busy:g,run:_}=O(),v=t(),y=async()=>{let e=await d.pluginsInstalled().catch(()=>null);o(e)};(0,P.useEffect)(()=>{y()},[]);let b=i?.thirdParty??[],x=e=>e.targets&&e.targets.length?e.targets:[`native`],T=b.filter(e=>s===`all`||x(e).includes(s)),M=e=>u(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),N=T.length>0&&T.every(e=>l.has(e.name)),L=()=>u(N?new Set:new Set(T.map(e=>e.name))),B=T.filter(e=>l.has(e.name)),V=B.some(e=>f.has(e.name)),H=B.filter(e=>e.enabled),U=B.filter(e=>!e.enabled);async function W(){h(!0);try{let e=await d.pluginsCheckUpdates(!0),t=e.refreshing?await z(()=>d.pluginsCheckUpdates(),e=>!!e.refreshing):e,n=new Map;for(let e of t.plugins??[]){if(!e.updateAvailable)continue;let t=e.targets?.find(e=>e.latest)?.latest||``;n.set(e.name,t)}p(n);let r=(t.plugins??[]).filter(e=>e.error),i=n.size?`发现 `+n.size+` 个可更新插件`:`全部插件已是最新`;!t.checkedAt&&t.error?a.error(`检查更新失败:`+t.error):r.length?a.warning(r.length+` 个插件取不到最新版本(`+(r[0].error||``)+(r.length>1?` 等`:``)+`)· `+i):a.success(i),await y()}catch(e){a.error(String(e))}h(!1)}async function G(){let e=B.filter(e=>f.has(e.name)).map(e=>e.name);if(!e.length){a.info(`所选插件均无可用更新`);return}u(new Set),p(t=>{let n=new Map(t);for(let t of e)n.delete(t);return n}),await _(`upd-sel`,async()=>{let t=[];for(let n of e)try{let e=await d.pluginUpdate(n);e.jobId&&t.push(e.jobId)}catch{}await R(t,`更新`,e.length)},{success:`已提交 `+e.length+` 个插件的更新任务`,refresh:!1,onDone:()=>void y()})}async function K(){let e=B.map(e=>e.name);await v({title:`卸载所选插件?`,description:(0,I.jsxs)(I.Fragment,{children:[`将卸载所选 `,e.length,` 个插件:`,(0,I.jsx)(`ul`,{className:`mt-2 max-h-[180px] overflow-auto rounded-md border border-border/70 bg-muted/40 px-3 py-2`,children:e.map(e=>(0,I.jsx)(`li`,{className:`truncate text-foreground`,children:e},e))})]}),confirmText:`卸载`,tone:`destructive`})&&(u(new Set),await _(`uni-sel`,async()=>{let t=[];for(let n of e)try{let e=await d.pluginUninstall(n);e.jobId&&t.push(e.jobId)}catch{}await R(t,`卸载`,e.length)},{success:`已提交 `+e.length+` 个插件的卸载任务`,refresh:!1,onDone:()=>void y()}))}async function q(){let e=H.map(e=>e.name);u(new Set),await _(`stop-sel`,async()=>{for(let t of e)try{await d.pluginDisable(t)}catch{}},{success:`已停止 `+e.length+` 个插件`,refresh:!1,onDone:()=>void y()})}async function J(){let e=U.map(e=>e.name);u(new Set),await _(`start-sel`,async()=>{for(let t of e)try{await d.pluginEnable(t)}catch{}},{success:`已启动 `+e.length+` 个插件`,refresh:!1,onDone:()=>void y()})}let Y=`grid grid-cols-[88px_minmax(0,1fr)_120px_84px_36px] items-center gap-3`;return(0,I.jsxs)(j,{className:`overflow-hidden`,children:[(0,I.jsx)(k,{title:`已安装插件`+(i?`(`+T.length+`)`:``),subtitle:s===`all`?`全部实例`:`实例:`+((i?.targets??[]).find(e=>e.id===s)?.name??s),actions:(0,I.jsxs)(I.Fragment,{children:[V?(0,I.jsxs)(n,{disabled:g===`upd-sel`,onClick:()=>void G(),size:`sm`,children:[(0,I.jsx)(w,{className:`size-3.5`}),`更新(`,B.filter(e=>f.has(e.name)).length,`)`]}):(0,I.jsxs)(n,{disabled:m,onClick:()=>void W(),size:`sm`,variant:`outline`,children:[(0,I.jsx)(w,{className:r(`size-3.5`,m&&`animate-spin`)}),m?`检查中…`:`检查更新`]}),B.length>0?(0,I.jsxs)(I.Fragment,{children:[H.length>0?(0,I.jsxs)(n,{disabled:g===`stop-sel`,onClick:()=>void q(),size:`sm`,variant:`outline`,children:[(0,I.jsx)(S,{className:`size-3.5`}),`停用(`,H.length,`)`]}):null,U.length>0?(0,I.jsxs)(n,{disabled:g===`start-sel`,onClick:()=>void J(),size:`sm`,variant:`outline`,children:[(0,I.jsx)(C,{className:`size-3.5`}),`启动(`,U.length,`)`]}):null,(0,I.jsxs)(n,{className:`h-[30px]`,disabled:g===`uni-sel`,onClick:()=>void K(),size:`sm`,variant:`destructive`,children:[(0,I.jsx)(E,{className:`size-3.5`}),`卸载(`,B.length,`)`]})]}):null]})}),(0,I.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5 border-b border-border/60 px-5 py-2.5`,children:[(0,I.jsx)(n,{className:r(s===`all`?`bg-primary/10 text-primary hover:bg-primary/15`:`text-muted-foreground hover:bg-muted hover:text-foreground`),onClick:()=>c(`all`),size:`sm`,variant:`ghost`,children:`全部实例`}),(i?.targets??[]).map(e=>(0,I.jsx)(n,{className:r(s===e.id?`bg-primary/10 text-primary hover:bg-primary/15`:`text-muted-foreground hover:bg-muted hover:text-foreground`),onClick:()=>c(e.id),size:`sm`,variant:`ghost`,children:e.name},e.id))]}),i?T.length?(0,I.jsx)(I.Fragment,{children:(0,I.jsxs)(`div`,{className:`overflow-x-auto`,children:[(0,I.jsxs)(`div`,{className:r(Y,`min-w-[720px] border-b border-border/70 bg-muted px-5 py-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground`),children:[(0,I.jsx)(`span`,{children:`来源`}),(0,I.jsx)(`span`,{children:`插件`}),(0,I.jsx)(`span`,{children:`版本`}),(0,I.jsx)(`span`,{className:`text-right`,children:`大小`}),(0,I.jsx)(`span`,{className:`flex justify-end`,children:(0,I.jsx)(e,{"aria-label":`全选`,checked:N,onChange:L})})]}),(0,I.jsx)(`div`,{className:`max-h-[560px] overflow-auto`,children:T.map(t=>{let n=l.has(t.name),i=f.get(t.name);return(0,I.jsxs)(`label`,{className:r(Y,`min-h-[46px] min-w-[720px] w-full cursor-pointer border-b border-border/50 px-5 py-2 text-left transition-colors last:border-b-0 hover:bg-muted/40`,n&&`bg-muted/70 shadow-[inset_3px_0_0_var(--primary)]`),children:[(0,I.jsx)(`span`,{className:`inline-flex w-fit min-w-0 items-center`,children:(0,I.jsx)(A,{tone:t.bundle?`boot`:t.source?.includes(`github`)?`warn`:t.source===`npm`?`ok`:`off`,children:t.bundle?`bundle`:t.source===`npm`?`npm`:t.source?.includes(`github`)?`GitHub`:t.source&&t.source!==t.name?`本地`:`—`})}),(0,I.jsx)(`span`,{className:`grid min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-2`,children:(0,I.jsxs)(`span`,{className:`grid min-w-0 gap-0.5`,children:[(0,I.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2`,children:[(0,I.jsx)(`strong`,{className:`truncate font-mono text-[13px] font-semibold leading-tight text-foreground`,children:t.name}),(0,I.jsx)(A,{tone:t.enabled?`ok`:`off`,children:t.enabled?`已启用`:`已停用`})]}),t.description?(0,I.jsx)(`span`,{className:`truncate text-xs leading-tight text-muted-foreground`,children:t.description}):null]})}),(0,I.jsx)(`span`,{className:`min-w-0`,children:i?(0,I.jsxs)(`span`,{className:`inline-flex flex-wrap items-center gap-1.5`,children:[(0,I.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:t.version?`v`+t.version:`—`}),(0,I.jsx)(A,{tone:`warn`,children:`可更新`})]}):(0,I.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:t.version?`v`+t.version:`—`})}),(0,I.jsx)(`span`,{className:`text-right font-mono text-xs tabular-nums text-foreground`,children:t.size?F(t.size):`—`}),(0,I.jsx)(`span`,{className:`flex justify-end`,children:(0,I.jsx)(e,{"aria-label":`选择 `+t.name,checked:n,onChange:()=>M(t.name)})})]},t.name)})})]})}):(0,I.jsxs)(`div`,{className:`grid place-items-center rounded-lg border-0 py-16 text-center`,children:[(0,I.jsx)(D,{className:`mx-auto mb-3 size-8 text-muted-foreground`}),(0,I.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`当前实例均未安装第三方插件`})]}):(0,I.jsx)(`div`,{className:`py-16 text-center text-sm text-muted-foreground`,children:`加载中…`})]})}export{B as PluginsPage};
1
+ import{E as e,F as t,I as n,L as r,N as i,O as a,R as o,S as s,U as c,V as l,_ as u,a as d,d as f,f as p,h as m,l as h,m as g,p as _,u as v,v as y,x as b,y as x}from"./supervisor-Dfq_YAmt.js";import{n as S,t as C}from"./rocket-Dit4Xpeq.js";import{t as w}from"./refresh-cw-CFZGPyP6.js";import{t as T}from"./jobs-BjLbfJTM.js";import{c as E,u as D}from"./supervisor-BilTj6si.js";import{t as O}from"./useSupervisorAction-DZSdzPif.js";import{n as k,o as A,t as j}from"./widgets-M2h3F-43.js";var M=i(`search`,[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]),N=i(`store`,[[`path`,{d:`M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5`,key:`slp6dd`}],[`path`,{d:`M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244`,key:`o0xfot`}],[`path`,{d:`M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05`,key:`wn3emo`}]]),P=c(l(),1);function F(e){return e>=1073741824?`${(e/1024/1024/1024).toFixed(1)} GB`:e>=1048576?`${(e/1024/1024).toFixed(0)} MB`:e>=1024?`${(e/1024).toFixed(0)} KB`:`${e} B`}var I=o(),L=24;async function R(e,t,n){if(!e.length)return;let r=a.loading(`正在`+t+` `+n+` 个插件…(0/`+e.length+`)`),i=0,o=0;for(let s of e){let c=await T(()=>d.pluginInstallStatus(s));c.state===`done`?i++:c.state===`failed`&&o++,a.loading(`正在`+t+` `+n+` 个插件…(`+(i+o)+`/`+e.length+`)`,{id:r})}o===0?a.success(t+`完成(`+i+`/`+e.length+`)`,{id:r}):a.warning(t+`结束:成功 `+i+`,失败 `+o,{id:r})}async function z(e,t,n=3e5,r=2e3){let i=await e(),a=Date.now()+n;for(;t(i)&&Date.now()<a;)await new Promise(e=>setTimeout(e,r)),i=await e();return i}function B(){let[e,t]=(0,P.useState)(`market`),[i,a]=(0,P.useState)(0);return(0,I.jsxs)(`div`,{className:`grid content-start gap-4`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,I.jsx)(`div`,{className:`flex gap-1 rounded-lg bg-muted p-1`,children:[`market`,`installed`].map(i=>(0,I.jsxs)(n,{className:r(`font-medium`,e===i?`bg-card text-foreground shadow-sm`:`bg-transparent text-muted-foreground hover:bg-card/60 hover:text-foreground`),onClick:()=>t(i),size:`sm`,variant:`ghost`,children:[i===`market`?(0,I.jsx)(N,{className:`size-3.5`}):(0,I.jsx)(D,{className:`size-3.5`}),i===`market`?`插件商店`:`已安装`]},i))}),e===`market`?(0,I.jsx)(V,{onSettled:()=>a(e=>e+1)}):null]}),e===`market`?(0,I.jsx)(H,{nonce:i}):(0,I.jsx)(G,{})]})}function V({onSettled:e}){let[t,i]=(0,P.useState)(!1);async function o(){i(!0);try{let t=await d.market(!0),n=t.building?await z(()=>d.market(),e=>!!e.building):t;n.error?a.error(`索引刷新失败:`+n.error+`(暂用旧索引的 `+n.plugins.length+` 个)`):n.plugins.length?a.success(`插件索引已刷新(`+n.plugins.length+` 个)`):a.error(`索引刷新失败:无结果`),e?.()}catch(e){a.error(String(e))}i(!1)}return(0,I.jsxs)(n,{disabled:t,onClick:()=>void o(),size:`chip`,variant:`outline`,children:[(0,I.jsx)(w,{className:r(`size-3.5`,t&&`animate-spin`)}),`刷新`]})}function H({nonce:e=0}){let[t,i]=(0,P.useState)(null),[o,c]=(0,P.useState)(!1),[l,S]=(0,P.useState)(null),[C,w]=(0,P.useState)(``),[E,D]=(0,P.useState)(`all`),[O,k]=(0,P.useState)(`all`),[j,N]=(0,P.useState)(0),[F,R]=(0,P.useState)(null),[B,V]=(0,P.useState)([]),[H,G]=(0,P.useState)(`native`);(0,P.useEffect)(()=>{let e=!0;return(async()=>{try{let t=await d.market();if(t.building&&(e&&c(!0),t=await z(()=>d.market(),e=>!!e.building)),!e)return;c(!1),i(t.plugins.length?t:null),S(t.plugins.length?null:t.error||`索引为空,点「刷新」重建`),N(L)}catch(t){e&&(c(!1),S(String(t)))}})(),()=>{e=!1}},[e]);let K=(0,P.useMemo)(()=>{if(!t)return[];let e=C.trim().toLowerCase();return t.plugins.filter(t=>(E===`all`||t.category===E)&&(O===`all`||t.source===O)&&(!e||(t.name+` `+(t.description||``)).toLowerCase().includes(e)))},[t,C,E,O]),q=(0,P.useMemo)(()=>{let e={};for(let n of t?.plugins??[])e[n.category]=(e[n.category]||0)+1;return Object.entries(e).sort((e,t)=>t[1]-e[1])},[t]);async function J(e){R(e),G(`native`);try{let e=await d.instances();V((e.instances??[]).filter(e=>e.domain===`sandbox`).map(e=>({id:e.id,name:e.name})))}catch{V([])}}async function Y(){if(F)try{let e=await d.pluginInstall(F.name,H);if(e.ok===!1){a.error(e.error||`安装失败`);return}if(R(null),e.jobId){let t=a.loading(`正在安装 `+F.name+`…`),n=await T(()=>d.pluginInstallStatus(e.jobId));n.state===`done`?a.success(`已安装 `+F.name,{id:t}):n.state===`failed`?a.error(`安装失败:`+(n.error||`未知原因`),{id:t}):a.warning(`安装仍在进行(超时未完成,可稍后查看)`,{id:t})}else a.success(`安装任务已提交`)}catch(e){a.error(String(e))}}return(0,I.jsxs)(`div`,{className:`grid content-start gap-3`,children:[(0,I.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,I.jsxs)(`div`,{className:`relative min-w-[220px] flex-1`,children:[(0,I.jsx)(M,{className:`absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground`}),(0,I.jsx)(u,{className:`pl-8`,placeholder:`搜索插件名称、描述…`,value:C,onChange:e=>w(e.target.value)})]}),(0,I.jsxs)(h,{value:E,onValueChange:D,children:[(0,I.jsx)(p,{className:`h-9 w-[150px] shrink-0`,children:(0,I.jsx)(_,{placeholder:`全部分类`})}),(0,I.jsxs)(v,{children:[(0,I.jsx)(f,{value:`all`,children:`全部分类`}),q.map(([e,t])=>(0,I.jsxs)(f,{value:e,children:[e,` (`,t,`)`]},e))]})]}),(0,I.jsxs)(h,{value:O,onValueChange:k,children:[(0,I.jsx)(p,{className:`h-9 w-[130px] shrink-0`,children:(0,I.jsx)(_,{placeholder:`全部来源`})}),(0,I.jsxs)(v,{children:[(0,I.jsx)(f,{value:`all`,children:`全部来源`}),(0,I.jsx)(f,{value:`npm`,children:`npm`}),(0,I.jsx)(f,{value:`github`,children:`GitHub`}),(0,I.jsx)(f,{value:`community`,children:`社区`}),(0,I.jsx)(f,{value:`official`,children:`官方`})]})]})]}),t?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`共 `,t.plugins.length,` 个插件 · 更新 `,t.indexedAt?new Date(t.indexedAt).toLocaleString():`—`,` · npm `,t.sources?.npm||0,` · GitHub `,t.sources?.github||0,` · 社区 `,t.sources?.community||0]}),K.length?(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`div`,{className:`grid grid-cols-1 gap-3 @min-[640px]:grid-cols-2 @min-[1000px]:grid-cols-3`,children:K.slice(0,j).map(e=>(0,I.jsxs)(`div`,{className:`flex min-h-[150px] flex-col rounded-lg border border-border bg-card p-4`,children:[(0,I.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,I.jsx)(`strong`,{className:`truncate font-mono text-sm text-foreground`,children:e.name}),(0,I.jsx)(A,{tone:W(e.source),children:U(e.source)})]}),(0,I.jsx)(`p`,{className:`mt-2 line-clamp-3 min-h-[36px] text-xs leading-relaxed text-muted-foreground`,children:e.description||`(无描述)`}),(0,I.jsxs)(`div`,{className:`mt-2 flex flex-wrap items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,I.jsx)(`span`,{className:`rounded bg-muted px-1.5 py-0.5`,children:e.category}),e.version?(0,I.jsxs)(`span`,{className:`font-mono`,children:[`v`,e.version]}):null,e.stars?(0,I.jsxs)(`span`,{children:[`⭐`,e.stars]}):null]}),(0,I.jsxs)(`div`,{className:`mt-auto flex items-center justify-between gap-2 pt-3`,children:[(0,I.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:e.author||``}),(0,I.jsx)(n,{onClick:()=>void J(e),size:`chip`,children:`安装`})]})]},e.name))}),j<K.length?(0,I.jsxs)(n,{className:`justify-self-center`,onClick:()=>N(e=>e+L),variant:`outline`,children:[`加载更多(`,j,`/`,K.length,`)`]}):null]}):(0,I.jsx)(`div`,{className:`grid place-items-center rounded-lg border border-dashed border-border py-16 text-sm text-muted-foreground`,children:`无匹配插件`})]}):(0,I.jsx)(`div`,{className:`grid place-items-center py-20 text-sm text-muted-foreground`,children:o?`正在构建插件索引(首次约需数分钟,可留在本页)…`:l||`加载插件索引…`}),(0,I.jsx)(y,{open:!!F,onOpenChange:e=>!e&&R(null),children:(0,I.jsxs)(x,{className:`max-w-[400px]`,children:[(0,I.jsx)(b,{children:(0,I.jsxs)(s,{children:[`安装插件 — `,F?.name]})}),(0,I.jsx)(`div`,{className:`grid gap-2`,children:(0,I.jsx)(g,{value:H,onValueChange:G,className:`grid gap-2`,children:[[`native`,`原生实例`],[`all`,`所有实例(含原生)`]].concat(B.map(e=>[`id:`+e.id,e.name+`(`+e.id.slice(0,8)+`…)`])).map(([e,t])=>(0,I.jsxs)(`label`,{className:r(`flex cursor-pointer items-center gap-2 rounded-md border px-3 py-2 text-sm`,H===e?`border-primary/40 bg-primary/[0.05] text-foreground`:`border-border text-muted-foreground hover:bg-muted`),children:[(0,I.jsx)(m,{value:e}),t]},e))})}),(0,I.jsxs)(`div`,{className:`mt-3 flex justify-end gap-2`,children:[(0,I.jsx)(n,{onClick:()=>R(null),variant:`outline`,children:`取消`}),(0,I.jsx)(n,{onClick:()=>void Y(),children:`开始安装`})]})]})})]})}var U=e=>({npm:`npm`,github:`GitHub`,community:`社区`,official:`官方`})[e]??e,W=e=>e===`official`?`boot`:e===`npm`?`ok`:e===`github`?`warn`:`off`;function G(){let[i,o]=(0,P.useState)(null),[s,c]=(0,P.useState)(`all`),[l,u]=(0,P.useState)(new Set),[f,p]=(0,P.useState)(new Map),[m,h]=(0,P.useState)(!1),{busy:g,run:_}=O(),v=t(),y=async()=>{let e=await d.pluginsInstalled().catch(()=>null);o(e)};(0,P.useEffect)(()=>{y()},[]);let b=i?.thirdParty??[],x=e=>e.targets&&e.targets.length?e.targets:[`native`],T=b.filter(e=>s===`all`||x(e).includes(s)),M=e=>u(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),N=T.length>0&&T.every(e=>l.has(e.name)),L=()=>u(N?new Set:new Set(T.map(e=>e.name))),B=T.filter(e=>l.has(e.name)),V=B.some(e=>f.has(e.name)),H=B.filter(e=>e.enabled),U=B.filter(e=>!e.enabled);async function W(){h(!0);try{let e=await d.pluginsCheckUpdates(!0),t=e.refreshing?await z(()=>d.pluginsCheckUpdates(),e=>!!e.refreshing):e,n=new Map;for(let e of t.plugins??[]){if(!e.updateAvailable)continue;let t=e.targets?.find(e=>e.latest)?.latest||``;n.set(e.name,t)}p(n);let r=(t.plugins??[]).filter(e=>e.error),i=n.size?`发现 `+n.size+` 个可更新插件`:`全部插件已是最新`;!t.checkedAt&&t.error?a.error(`检查更新失败:`+t.error):r.length?a.warning(r.length+` 个插件取不到最新版本(`+(r[0].error||``)+(r.length>1?` 等`:``)+`)· `+i):a.success(i),await y()}catch(e){a.error(String(e))}h(!1)}async function G(){let e=B.filter(e=>f.has(e.name)).map(e=>e.name);if(!e.length){a.info(`所选插件均无可用更新`);return}u(new Set),p(t=>{let n=new Map(t);for(let t of e)n.delete(t);return n}),await _(`upd-sel`,async()=>{let t=[];for(let n of e)try{let e=await d.pluginUpdate(n);e.jobId&&t.push(e.jobId)}catch{}await R(t,`更新`,e.length)},{success:`已提交 `+e.length+` 个插件的更新任务`,refresh:!1,onDone:()=>void y()})}async function K(){let e=B.map(e=>e.name);await v({title:`卸载所选插件?`,description:(0,I.jsxs)(I.Fragment,{children:[`将卸载所选 `,e.length,` 个插件:`,(0,I.jsx)(`ul`,{className:`mt-2 max-h-[180px] overflow-auto rounded-md border border-border/70 bg-muted/40 px-3 py-2`,children:e.map(e=>(0,I.jsx)(`li`,{className:`truncate text-foreground`,children:e},e))})]}),confirmText:`卸载`,tone:`destructive`})&&(u(new Set),await _(`uni-sel`,async()=>{let t=[];for(let n of e)try{let e=await d.pluginUninstall(n);e.jobId&&t.push(e.jobId)}catch{}await R(t,`卸载`,e.length)},{success:`已提交 `+e.length+` 个插件的卸载任务`,refresh:!1,onDone:()=>void y()}))}async function q(){let e=H.map(e=>e.name);u(new Set),await _(`stop-sel`,async()=>{for(let t of e)try{await d.pluginDisable(t)}catch{}},{success:`已停止 `+e.length+` 个插件`,refresh:!1,onDone:()=>void y()})}async function J(){let e=U.map(e=>e.name);u(new Set),await _(`start-sel`,async()=>{for(let t of e)try{await d.pluginEnable(t)}catch{}},{success:`已启动 `+e.length+` 个插件`,refresh:!1,onDone:()=>void y()})}let Y=`grid grid-cols-[88px_minmax(0,1fr)_120px_84px_36px] items-center gap-3`;return(0,I.jsxs)(j,{className:`overflow-hidden`,children:[(0,I.jsx)(k,{title:`已安装插件`+(i?`(`+T.length+`)`:``),subtitle:s===`all`?`全部实例`:`实例:`+((i?.targets??[]).find(e=>e.id===s)?.name??s),actions:(0,I.jsxs)(I.Fragment,{children:[V?(0,I.jsxs)(n,{disabled:g===`upd-sel`,onClick:()=>void G(),size:`sm`,children:[(0,I.jsx)(w,{className:`size-3.5`}),`更新(`,B.filter(e=>f.has(e.name)).length,`)`]}):(0,I.jsxs)(n,{disabled:m,onClick:()=>void W(),size:`sm`,variant:`outline`,children:[(0,I.jsx)(w,{className:r(`size-3.5`,m&&`animate-spin`)}),m?`检查中…`:`检查更新`]}),B.length>0?(0,I.jsxs)(I.Fragment,{children:[H.length>0?(0,I.jsxs)(n,{disabled:g===`stop-sel`,onClick:()=>void q(),size:`sm`,variant:`outline`,children:[(0,I.jsx)(S,{className:`size-3.5`}),`停用(`,H.length,`)`]}):null,U.length>0?(0,I.jsxs)(n,{disabled:g===`start-sel`,onClick:()=>void J(),size:`sm`,variant:`outline`,children:[(0,I.jsx)(C,{className:`size-3.5`}),`启动(`,U.length,`)`]}):null,(0,I.jsxs)(n,{className:`h-[30px]`,disabled:g===`uni-sel`,onClick:()=>void K(),size:`sm`,variant:`destructive`,children:[(0,I.jsx)(E,{className:`size-3.5`}),`卸载(`,B.length,`)`]})]}):null]})}),(0,I.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5 border-b border-border/60 px-5 py-2.5`,children:[(0,I.jsx)(n,{className:r(s===`all`?`bg-primary/10 text-primary hover:bg-primary/15`:`text-muted-foreground hover:bg-muted hover:text-foreground`),onClick:()=>c(`all`),size:`sm`,variant:`ghost`,children:`全部实例`}),(i?.targets??[]).map(e=>(0,I.jsx)(n,{className:r(s===e.id?`bg-primary/10 text-primary hover:bg-primary/15`:`text-muted-foreground hover:bg-muted hover:text-foreground`),onClick:()=>c(e.id),size:`sm`,variant:`ghost`,children:e.name},e.id))]}),i?T.length?(0,I.jsx)(I.Fragment,{children:(0,I.jsxs)(`div`,{className:`overflow-x-auto`,children:[(0,I.jsxs)(`div`,{className:r(Y,`min-w-[720px] border-b border-border/70 bg-muted px-5 py-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground`),children:[(0,I.jsx)(`span`,{children:`来源`}),(0,I.jsx)(`span`,{children:`插件`}),(0,I.jsx)(`span`,{children:`版本`}),(0,I.jsx)(`span`,{className:`text-right`,children:`大小`}),(0,I.jsx)(`span`,{className:`flex justify-end`,children:(0,I.jsx)(e,{"aria-label":`全选`,checked:N,onChange:L})})]}),(0,I.jsx)(`div`,{className:`max-h-[560px] overflow-auto`,children:T.map(t=>{let n=l.has(t.name),i=f.get(t.name);return(0,I.jsxs)(`label`,{className:r(Y,`min-h-[46px] min-w-[720px] w-full cursor-pointer border-b border-border/50 px-5 py-2 text-left transition-colors last:border-b-0 hover:bg-muted/40`,n&&`bg-muted/70 shadow-[inset_3px_0_0_var(--primary)]`),children:[(0,I.jsx)(`span`,{className:`inline-flex w-fit min-w-0 items-center`,children:(0,I.jsx)(A,{tone:t.bundle?`boot`:t.source?.includes(`github`)?`warn`:t.source===`npm`?`ok`:`off`,children:t.bundle?`bundle`:t.source===`npm`?`npm`:t.source?.includes(`github`)?`GitHub`:t.source&&t.source!==t.name?`本地`:`—`})}),(0,I.jsx)(`span`,{className:`grid min-w-0 grid-cols-[minmax(0,1fr)_auto] items-center gap-2`,children:(0,I.jsxs)(`span`,{className:`grid min-w-0 gap-0.5`,children:[(0,I.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2`,children:[(0,I.jsx)(`strong`,{className:`truncate font-mono text-[13px] font-semibold leading-tight text-foreground`,children:t.name}),(0,I.jsx)(A,{tone:t.enabled?`ok`:`off`,children:t.enabled?`已启用`:`已停用`})]}),t.description?(0,I.jsx)(`span`,{className:`truncate text-xs leading-tight text-muted-foreground`,children:t.description}):null]})}),(0,I.jsx)(`span`,{className:`min-w-0`,children:i?(0,I.jsxs)(`span`,{className:`inline-flex flex-wrap items-center gap-1.5`,children:[(0,I.jsx)(`span`,{className:`truncate text-xs text-muted-foreground`,children:t.version?`v`+t.version:`—`}),(0,I.jsx)(A,{tone:`warn`,children:`可更新`})]}):(0,I.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:t.version?`v`+t.version:`—`})}),(0,I.jsx)(`span`,{className:`text-right font-mono text-xs tabular-nums text-foreground`,children:t.size?F(t.size):`—`}),(0,I.jsx)(`span`,{className:`flex justify-end`,children:(0,I.jsx)(e,{"aria-label":`选择 `+t.name,checked:n,onChange:()=>M(t.name)})})]},t.name)})})]})}):(0,I.jsxs)(`div`,{className:`grid place-items-center rounded-lg border-0 py-16 text-center`,children:[(0,I.jsx)(D,{className:`mx-auto mb-3 size-8 text-muted-foreground`}),(0,I.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`当前实例均未安装第三方插件`})]}):(0,I.jsx)(`div`,{className:`py-16 text-center text-sm text-muted-foreground`,children:`加载中…`})]})}export{B as PluginsPage};
@@ -1 +1 @@
1
- import{A as e,F as t,I as n,L as r,N as i,O as a,R as o,S as s,U as c,V as l,_ as u,a as d,d as f,f as p,g as m,l as h,n as g,o as _,p as v,t as y,u as b,v as x,x as S,y as C}from"./supervisor-Dfq_YAmt.js";import{a as w,i as T,n as E,s as D,t as O}from"./openExternal-Ds20EFp9.js";import{n as k,t as A}from"./rocket-Dit4Xpeq.js";import{t as j}from"./refresh-cw-CFZGPyP6.js";import{t as M}from"./jobs-BjLbfJTM.js";import{c as N,f as P,l as F}from"./supervisor-BZTzTZDT.js";import{t as I}from"./useSupervisorAction-DZSdzPif.js";import{a as L,c as R,i as z,o as B,s as V,t as H}from"./widgets-M2h3F-43.js";import{n as U}from"./format-QeaTKFhQ.js";var W=i(`ban`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M4.929 4.929 19.07 19.071`,key:`196cmz`}]]),G=i(`circle-x`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m15 9-6 6`,key:`1uzhvr`}],[`path`,{d:`m9 9 6 6`,key:`z0biqf`}]]),K=i(`repeat`,[[`path`,{d:`m17 2 4 4-4 4`,key:`nntrym`}],[`path`,{d:`M3 11v-1a4 4 0 0 1 4-4h14`,key:`84bu3i`}],[`path`,{d:`m7 22-4-4 4-4`,key:`1wqhfi`}],[`path`,{d:`M21 13v1a4 4 0 0 1-4 4H3`,key:`1rx37r`}]]),q=i(`terminal`,[[`path`,{d:`M12 19h8`,key:`baeox8`}],[`path`,{d:`m4 17 6-6-6-6`,key:`1yngyt`}]]),J=c(l(),1),Y=o();function X(e){if(!e)return!1;let t=e=>!!(e&&(e.status===`rate-limited`||Number(e.percent)>=100));return t(e.rolling)||t(e.weekly)||t(e.monthly)}function Z(e){return!e||!Number.isFinite(e)?``:new Date(e).toLocaleString(`zh-CN`,{year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`})}function Q(e){return[...e].sort((e,t)=>{let n=e=>e.selected?0:e.usable&&!X(e.quota)?1:2;return n(e)-n(t)})}var $=`grid-cols-[minmax(0,1fr)_230px_84px]`;function ee({onRegisterActions:t}){let{snap:i}=y(),{busy:a,run:o}=I(),[s,c]=(0,J.useState)(!1),[l,u]=(0,J.useState)(!1),f=i.router,p=i.providers;(0,J.useEffect)(()=>(t?.({onAdd:()=>c(!0),onDelete:()=>u(!0)}),()=>t?.(null)),[t]);function m(e,t,n){return o(e,t,{success:n})}let h=p?.providers??[];return(0,Y.jsxs)(`div`,{className:`grid content-start gap-4`,children:[(0,Y.jsxs)(H,{children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 border-b border-border/70 px-5 py-3.5`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Y.jsx)(R,{tone:f?.running?`ok`:`off`,ping:!!f?.running}),(0,Y.jsx)(`strong`,{className:`text-xl font-semibold tracking-[-0.01em] text-foreground`,children:f?.running?`路由运行中`:`路由已停止`})]}),(0,Y.jsx)(n,{"aria-label":f?.running?`停止路由`:`启动路由`,className:r(`px-1`,f?.running?`text-status-error`:`text-primary`),disabled:a===`sw`,onClick:()=>void m(`sw`,()=>f?.running?d.lifecycleStop(`router`):d.lifecycleStart(`router`),f?.running?`路由已停止`:`路由已启动`),title:f?.running?`停止路由`:`启动路由`,variant:`ghost`,children:f?.running?(0,Y.jsx)(k,{className:`size-6`}):(0,Y.jsx)(A,{className:`size-6`})})]}),(0,Y.jsxs)(`div`,{className:`grid grid-cols-1 divide-y divide-border/60 sm:grid-cols-2 sm:divide-y-0 lg:grid-cols-4 lg:divide-x lg:divide-border/60`,children:[(0,Y.jsx)(`div`,{className:`px-5 py-3.5`,children:(0,Y.jsx)(z,{icon:(0,Y.jsx)(P,{className:`size-4`}),label:`总请求 / 失败`,value:U(f?.usage?.requests)+` / `+U(f?.usage?.errors),mono:!0})}),(0,Y.jsx)(`div`,{className:`px-5 py-3.5`,children:(0,Y.jsx)(z,{icon:(0,Y.jsx)(e,{className:`size-4`}),label:`总 Tokens`,value:U(f?.usage?.totalTokens),mono:!0})}),(0,Y.jsx)(`div`,{className:`px-5 py-3.5`,children:(0,Y.jsx)(z,{icon:(0,Y.jsx)(q,{className:`size-4`}),label:`Prompt / Completion`,value:U(f?.usage?.promptTokens)+` / `+U(f?.usage?.completionTokens),mono:!0})}),(0,Y.jsx)(`div`,{className:`px-5 py-3.5`,children:(0,Y.jsx)(z,{icon:(0,Y.jsx)(G,{className:`size-4`}),label:`估算费用`,value:f?.usage?.costUsd?`$`+Number(f.usage.costUsd).toFixed(4):`—`,mono:!0,warn:!f?.usage?.costUsd})})]})]}),h.length?(0,Y.jsx)(`div`,{className:`grid gap-4 @min-[900px]:grid-cols-2`,children:h.map(e=>(0,Y.jsx)(ne,{p:e,proxyApps:p?.proxyApps??[],busy:a===e.id,onAction:m},e.id))}):(0,Y.jsx)(`div`,{className:`grid min-h-[200px] place-items-center rounded-lg border border-dashed border-border text-center`,children:(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(P,{className:`mx-auto mb-3 size-8 text-muted-foreground`}),(0,Y.jsx)(`p`,{className:`text-sm font-medium text-foreground`,children:`尚未添加供应商`}),(0,Y.jsx)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:`点击「添加供应商」录入 API Key / Command Code`})]})}),(0,Y.jsx)(se,{open:s,onOpenChange:c,presets:p?.presets??[],proxyApps:p?.proxyApps??[],onDone:()=>g.refresh()}),(0,Y.jsx)(te,{open:l,onOpenChange:u,providers:h})]})}function te({open:e,onOpenChange:r,providers:i}){let[o,c]=(0,J.useState)(null),l=t();async function u(e){if(await l({title:`删除供应商「`+e.name+`」?`,description:`其下全部账号与 Key 将被移除,不可恢复。`,confirmText:`删除`,tone:`destructive`})){c(e.id);try{await d.providerRemove(e.id),a.success(`已删除供应商「`+e.name+`」`),await g.refresh()}catch(e){a.error(String(e))}finally{c(null)}}}return(0,Y.jsx)(x,{open:e,onOpenChange:r,children:(0,Y.jsxs)(C,{className:`max-w-[440px]`,children:[(0,Y.jsx)(S,{children:(0,Y.jsx)(s,{children:`删除供应商`})}),(0,Y.jsx)(`div`,{className:`grid gap-1.5`,children:i.length?i.map(e=>(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-md border border-border/70 bg-muted/40 px-3 py-2`,children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,Y.jsx)(`strong`,{className:`truncate text-sm font-medium text-foreground`,children:e.name}),(0,Y.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.kind===`proxy`?`反代`:`直连`,` · `,(e.accounts??[]).length,` 账号`]})]}),(0,Y.jsxs)(n,{disabled:o===e.id,onClick:()=>void u(e),size:`chip`,variant:`destructive`,children:[o===e.id?(0,Y.jsx)(j,{className:`size-3 animate-spin`}):(0,Y.jsx)(N,{className:`size-3`}),`删除`]})]},e.id)):(0,Y.jsx)(`p`,{className:`py-8 text-center text-sm text-muted-foreground`,children:`暂无供应商`})}),(0,Y.jsx)(`div`,{className:`mt-3 flex justify-end`,children:(0,Y.jsx)(n,{onClick:()=>r(!1),variant:`outline`,children:`关闭`})})]})})}function ne({p:e,proxyApps:t,busy:i,onAction:o}){let s=Q(e.accounts??[]),c=s.find(e=>e.selected)||s.find(e=>e.usable&&!X(e.quota))||s[0],[l,u]=(0,J.useState)(!1),f=e.kind===`proxy`?(t??[]).find(t=>t.id===e.proxyAppId)??null:null,p=e.apiBase||(e.apiPort?`http://127.0.0.1:`+e.apiPort+`/v1`:null);return(0,Y.jsxs)(H,{className:`flex min-h-0 flex-col overflow-hidden`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 border-b border-border/70 bg-muted px-5 py-3`,children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,Y.jsx)(`strong`,{className:`truncate text-sm font-semibold text-foreground`,children:e.name}),e.kind===`proxy`&&f&&f.installed?f.updateAvailable?(0,Y.jsxs)(n,{className:`gap-1 rounded-full px-2.5 text-xs text-warning`,disabled:i,onClick:()=>void o(`proxy-upd-`+e.id,async()=>{let t=e.proxyAppId,n=await d.proxyUpdateApply(t);if(n.ok===!1){a.error(n.error||`提交失败`);return}let r=a.loading(`正在更新 `+e.name+` 的全部实例…`),i=await M(()=>d.proxyUpdateStatus(t),{onTick:t=>{let n=t?.steps||[],i=n.filter(e=>e.state===`done`).length;n.length&&a.loading(`正在更新 `+e.name+`…(`+i+`/`+n.length+` 实例)`,{id:r})}}),o=i.snapshot;i.state===`done`?a.success(`更新完成`+(o?.restarted?`(已重启 `+o.restarted+` 个实例)`:``),{id:r}):i.state===`failed`?a.error(`更新失败:`+(i.error||(o?.errors?o.errors+` 个实例失败`:`未知原因`)),{id:r}):a.warning(`更新仍在进行(超时未完成,可稍后查看)`,{id:r}),await g.refresh()},void 0),size:`chip`,title:`检测到新版本,点击更新该应用全部实例`,variant:`outline`,children:[(0,Y.jsx)(j,{className:`size-3`}),`更新 v`,f.latest]}):(0,Y.jsxs)(n,{className:`gap-1 rounded-full px-2.5 text-xs font-mono text-muted-foreground`,disabled:i,onClick:()=>{o(`proxy-chk-`+e.id,async()=>{let t=await d.proxyUpdateCheck();if(await g.refresh(),!t.ok){a.error(t.error||`版本检测失败`);return}let n=t.versions?.[e.proxyAppId||``]||null,r=f.installed;a.info(n&&n!==r?`发现新版本 v`+n+`,点击版本胶囊更新`:`已是最新版本 v`+r)},void 0)},size:`chip`,title:`检测是否有新版本`,variant:`outline`,children:[`v`,f.installed,(0,Y.jsx)(j,{className:r(`size-3`,i&&`animate-spin`)})]}):null]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center gap-1.5`,children:[(0,Y.jsxs)(n,{disabled:i,onClick:()=>u(!0),size:`sm`,variant:`outline`,children:[(0,Y.jsx)(F,{className:`size-3.5`}),`添加`]}),e.activated?(0,Y.jsxs)(n,{disabled:i,onClick:()=>void o(`deact`,()=>d.providerDeactivate(e.id).then(()=>void 0),`已停用供应商(资源已回收)`),size:`sm`,variant:`outline`,children:[(0,Y.jsx)(k,{className:`size-3.5`}),`停用`]}):(0,Y.jsxs)(n,{disabled:i,onClick:()=>void o(`act`,()=>d.providerActivate(e.id).then(()=>void 0),`已启用供应商`),size:`sm`,variant:`outline`,children:[(0,Y.jsx)(A,{className:`size-3.5`}),`启用`]})]})]}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border/60 px-5 py-2.5`,children:[(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`API 地址`}),(0,Y.jsx)(`div`,{className:`flex h-8 min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-card px-2.5`,children:e.activated&&p?(0,Y.jsx)(`code`,{className:`min-w-0 flex-1 truncate font-mono text-xs text-foreground`,children:p}):(0,Y.jsx)(`span`,{className:`truncate text-xs text-muted-foreground/70`,children:`服务未启用`})}),e.activated&&p?(0,Y.jsxs)(n,{onClick:()=>void navigator.clipboard.writeText(p||``).then(()=>a.success(`已复制 API 地址`)),size:`sm`,title:`复制该供应商 API 地址`,variant:`outline`,children:[(0,Y.jsx)(D,{className:`size-3.5`}),`复制`]}):null]}),c?(0,Y.jsx)(ie,{acc:c,busy:i,p:e,onAction:o}):(0,Y.jsx)(`div`,{className:`px-5 py-3 text-xs text-muted-foreground`,children:`暂无账号数据`}),s.length?(0,Y.jsxs)(`div`,{className:`flex min-h-0 flex-col border-t border-border/60`,children:[(0,Y.jsxs)(`div`,{className:r(`grid items-center gap-2 border-b border-border/60 bg-muted/60 px-5 py-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground`,$),children:[(0,Y.jsx)(`span`,{children:`Key`}),(0,Y.jsx)(`span`,{className:`text-center`,children:`用量`}),(0,Y.jsx)(`span`,{className:`text-center`,children:`操作`})]}),(0,Y.jsx)(`div`,{className:`max-h-[288px] min-h-0 overflow-y-auto overscroll-contain`,children:s.map((t,n)=>(0,Y.jsx)(`div`,{className:r(n>0&&`border-t border-border/50`),children:(0,Y.jsx)(ae,{a:t,p:e,busy:i,onAction:o})},t.keyId))})]}):(0,Y.jsx)(`p`,{className:`border-t border-border/60 px-5 py-3 text-xs text-muted-foreground`,children:`暂无 Keys — 点「添加」录入`}),(0,Y.jsx)(re,{open:l,onOpenChange:u,p:e})]})}function re({open:e,onOpenChange:r,p:i}){let o=i.accounts??[],c=t(),[l,u]=(0,J.useState)(``),[f,p]=(0,J.useState)(!1),[h,v]=(0,J.useState)(!1),[y,b]=(0,J.useState)(``),D=i.kind===`proxy`;(0,J.useEffect)(()=>{e&&b(``)},[e]);async function k(){v(!0);try{let e=await E(()=>d.proxyLoginStart());if(b(w(e)),!e||e.ok!==!0)return;let t=T(e);t&&a.warning(t,{duration:12e3});let n=await d.proxyLoginWait(e.waitMs??18e4);if(!n.ok||!n.apiKey){a.error(n.error||`登录未完成`);return}await d.proxyAddKey(i.id,n.apiKey),a.success(`已通过登录添加账号 `+(n.userName||n.keyName||``)),r(!1),await g.refresh()}catch(e){a.error(String(e))}finally{v(!1)}}async function A(){let e=l.split(/[,;\s]+/).map(e=>e.trim()).filter(Boolean);if(!e.length){a.error(`请输入至少一个 Key`);return}p(!0);try{if(D)for(let t of e){let e=await d.proxyAddKey(i.id,t);if(e&&e.limited===`credits`){let t=e.account?.limit?.recovery;a.warning(`已添加:该账号额度用尽`+(t?.type===`at`&&t.at?`(预计 ${Z(t.at)} 自动恢复)`:`(等待月度重置后自动恢复)`))}}else{let t=await d.providerKeysSet(i.id,{add:e});if(t.ok===!1){a.error(t.error||`添加失败`);return}let n=typeof t.added==`number`?t.added:e.length,o=t.discardedKeys||[];if(o.length){let e=o.slice(0,3).map(e=>`${e.key}(${e.error})`).join(`;`);a.warning(`已添加 ${n} 个,${o.length} 个失败被丢弃:${e}${o.length>3?` …`:``}`)}else a.success(`已添加 `+n+` 个 Key(`+(D?`反代账号`:`API Key`)+`)`);u(``),r(!1),await g.refresh();return}a.success(`已添加 `+e.length+` 个 Key(`+(D?`反代账号`:`API Key`)+`)`),u(``),r(!1),await g.refresh()}catch(e){a.error(String(e))}finally{p(!1)}}async function j(e){if(await c({title:`移除 Key `+e+`?`,description:`该凭据将从供应商中移除,不可恢复。`,confirmText:`移除`,tone:`destructive`})){p(!0);try{if(D){let t=o.find(t=>t.maskedKey===e||e.startsWith(t.maskedKey));t&&await d.proxyRemoveKey(i.id,t.keyId)}else{let t=await d.providerKeysSet(i.id,{removeMasked:[e]});if(t.ok===!1){a.error(t.error||`移除失败`);return}}a.success(`已移除`),r(!1),await g.refresh()}catch(e){a.error(String(e))}finally{p(!1)}}}return(0,Y.jsx)(x,{open:e,onOpenChange:r,children:(0,Y.jsxs)(C,{className:`max-w-[440px]`,children:[(0,Y.jsx)(S,{children:(0,Y.jsxs)(s,{children:[`添加 / 管理 Key — `,i.name]})}),(0,Y.jsxs)(`div`,{className:`grid gap-3`,children:[D?(0,Y.jsxs)(`div`,{className:`grid gap-2 rounded-md border border-border/70 bg-muted/40 px-3 py-2.5`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,Y.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,Y.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`一键登录`}),(0,Y.jsx)(`span`,{className:`text-[11px] leading-tight text-muted-foreground`,children:`浏览器打开 Command Code 授权,自动添加账号`})]}),(0,Y.jsx)(n,{disabled:h||f,onClick:()=>void k(),size:`sm`,children:h?`等待授权…`:`一键登录`})]}),y?(0,Y.jsxs)(`div`,{className:`grid gap-1 border-t border-border/60 pt-2`,children:[(0,Y.jsx)(`span`,{className:`text-[11px] leading-tight text-muted-foreground`,children:h?`等待授权中。窗口没弹出或停在空白页时,复制这一行在你的浏览器里打开:`:`本轮授权地址(窗口停在空白页时复制这一行手动打开):`}),(0,Y.jsx)(O,{url:y})]}):null]}):null,(0,Y.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,Y.jsxs)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:[D?`已录入账号(反代)`:`已录入 API Key`,`(`,o.length,`)`]}),o.length?(0,Y.jsx)(`div`,{className:`grid max-h-[180px] gap-1 overflow-auto`,children:o.map(e=>(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-md border border-border/70 bg-muted/40 px-2.5 py-1.5`,children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5`,children:[(0,Y.jsx)(`code`,{className:`truncate font-mono text-xs`,children:e.maskedKey}),e.selected?(0,Y.jsx)(B,{tone:`ok`,children:`当前`}):null]}),(0,Y.jsx)(n,{size:`chip`,variant:`ghost`,className:`text-destructive`,disabled:f,onClick:()=>void j(e.maskedKey),title:`移除该 Key`,children:(0,Y.jsx)(N,{className:`size-3.5`})})]},e.keyId))}):(0,Y.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`尚未录入 `,D?`账号`:`Key`]})]}),(0,Y.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,Y.jsxs)(m,{className:`text-xs text-muted-foreground`,children:[`添加 `,D?`账号 Key / Command Code`:`API Key`,`(每行一个,支持逗号/分号分隔)`]}),(0,Y.jsx)(_,{className:`h-20 resize-none font-mono text-xs`,placeholder:D?`sk-... 或 Command Code,每行一个`:`sk-... 每行一个`,value:l,onChange:e=>u(e.target.value)})]})]}),(0,Y.jsxs)(`div`,{className:`mt-3 flex justify-end gap-2`,children:[(0,Y.jsx)(n,{onClick:()=>r(!1),variant:`outline`,children:`取消`}),(0,Y.jsx)(n,{disabled:f||!l.trim(),onClick:()=>void A(),children:f?`保存中…`:`添加`})]})]})})}function ie({acc:t,busy:i,p:a,onAction:o}){let s=t.quota,c=!!t.selected,l=!!t.locked,u=s&&s.monthlyRemaining,f=s?.monthly?.percent,p=Number.isFinite(Number(f))?f+`%`:Number.isFinite(Number(u))?`$ `+Number(u).toFixed(2):`—`;return(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4 px-5 py-3`,children:[(0,Y.jsxs)(`div`,{className:`grid min-w-[180px] content-center gap-1`,children:[(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:c?l?`当前账号(锁定)`:`当前在用账号`:`选择账号`}),(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,Y.jsx)(L,{className:`max-w-[150px]`,children:t.maskedKey}),c?(0,Y.jsxs)(n,{className:`gap-1 px-2`,disabled:i,onClick:()=>o(`refresh`,()=>d.providerRefresh(a.id).then(()=>void 0),`额度已刷新`),size:`chip`,variant:`outline`,children:[(0,Y.jsx)(j,{className:r(`size-3`,i&&`animate-spin`)}),`刷新`]}):null]})]}),(0,Y.jsxs)(`div`,{className:`grid min-w-0 flex-1 grid-cols-3 items-stretch gap-2`,children:[(0,Y.jsx)(V,{icon:(0,Y.jsx)(j,{className:`size-3.5`}),label:`5小时`,value:(s?.rolling?.percent??0)+`%`,danger:s?.rolling?.status===`rate-limited`}),(0,Y.jsx)(V,{icon:(0,Y.jsx)(e,{className:`size-3.5`}),label:`每周`,value:(s?.weekly?.percent??0)+`%`,danger:s?.weekly?.status===`rate-limited`}),(0,Y.jsx)(V,{icon:(0,Y.jsx)(P,{className:`size-3.5`}),label:`每月`,value:p,danger:s?.monthly?.status===`rate-limited`||Number(s?.monthly?.percent??0)>=100})]})]})}function ae({a:e,p:t,busy:i,onAction:a}){let o=!!e.selected,s=e.instanceStatus===`frozen`?`frozen`:e.status||``,c=e.limit?.kind,l=s===`frozen`||!!c||!o&&X(e.quota),u=c===`credits`?e.limit?.recovery?.type===`at`&&e.limit?.recovery?.at?`额度用尽(预计 ${Z(e.limit.recovery.at)} 月度重置后自动恢复)`:`额度用尽(待月度重置后自动恢复)`:c===`window`?e.limit?.reason??`时间窗额度已用尽(到 resetAt 自动恢复)`:c===`banned`?`账号被封禁`:null,f=U(e.requests||0)+` 次 · `+U(e.totalTokens||0)+` tok`,[p,m]=(0,J.useState)(!1),h;return h=l&&!o?(0,Y.jsxs)(n,{size:`chip`,variant:`outline`,className:`w-[70px] gap-1 px-1.5`,onClick:()=>m(!0),title:u??`查看该账号限额情况`,children:[(0,Y.jsx)(W,{className:`size-3.5`}),`限额`]}):o?(0,Y.jsxs)(n,{disabled:i,onClick:()=>a(`refresh`,()=>d.providerRefresh(t.id).then(()=>void 0),`额度已刷新`),size:`chip`,variant:`outline`,className:`w-[70px] gap-1 px-1.5`,children:[(0,Y.jsx)(j,{className:r(`size-3.5`,i&&`animate-spin`)}),`刷新`]}):(0,Y.jsxs)(n,{disabled:i,size:`chip`,variant:`outline`,className:`w-[70px] gap-1 px-1.5`,onClick:()=>{t.kind===`proxy`?a(`sel`,()=>d.proxySelect(t.id,e.keyId).then(()=>void 0),`已切换账号`):a(`use`,()=>d.providerKeyUse(t.id,e.keyId).then(()=>void 0),`已锁定 Key`)},children:[(0,Y.jsx)(K,{className:`size-3.5`}),`切换`]}),(0,Y.jsxs)(`div`,{className:r(`grid items-center gap-2 px-5 py-2.5 hover:bg-muted/40`,$,o&&`bg-muted/60 shadow-[inset_3px_0_0_var(--primary)]`),children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5`,children:[(0,Y.jsx)(L,{children:e.maskedKey}),s===`registering`?(0,Y.jsx)(B,{tone:`off`,children:`检测中…`}):null,s===`banned`?(0,Y.jsx)(B,{tone:`err`,children:`封号`}):null,c===`credits`?(0,Y.jsx)(`span`,{title:e.limit?.reason??`额度用尽`,children:(0,Y.jsx)(B,{tone:`err`,children:`额度用尽`})}):null,c===`window`?(0,Y.jsx)(`span`,{title:e.limit?.reason??`时间窗额度已用尽`,children:(0,Y.jsx)(B,{tone:`warn`,children:`窗口用尽`})}):null]}),(0,Y.jsx)(`span`,{className:`truncate text-right text-xs tabular-nums text-muted-foreground`,title:f,children:f}),(0,Y.jsx)(`div`,{className:`flex justify-end`,children:h}),(0,Y.jsx)(oe,{open:p,onOpenChange:m,a:e,p:t})]})}function oe({open:e,onOpenChange:t,a:r,p:i}){let a=r.quota,o=(()=>{let e=a?.monthly?.percent;if(e!=null&&Number.isFinite(Number(e)))return Number(e);let t=Number(a?.credits?.monthlyCredits??a?.monthlyRemaining);return Number.isFinite(t)&&t>=0?Math.min(100,Math.round((10-t)/10*100)):0})(),c=a?.monthly?.status?{...a.monthly,percent:o}:{status:`ok`,percent:o,resetsAt:a?.monthly?.resetsAt},l=(()=>{let e=a?.credits?.monthlyCredits,t=a?.monthlyRemaining,n=e!=null&&Number.isFinite(Number(e))?Number(e):t!=null&&Number.isFinite(Number(t))?Number(t):null;return n===null?null:`剩余 $`+n.toFixed(2)})(),u=(e,t,n)=>(0,Y.jsxs)(`div`,{className:`grid gap-1 rounded-md border border-border/70 bg-muted/40 px-3 py-2.5`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Y.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:t}),(0,Y.jsx)(B,{tone:e?.status===`rate-limited`||Number(e?.percent)>=100?`err`:`ok`,children:e?.status===`rate-limited`||Number(e?.percent)>=100?`已限额`:`正常`})]}),(0,Y.jsxs)(`strong`,{className:`text-xl font-semibold tabular-nums text-foreground`,children:[e?.percent??0,`%`]}),n?(0,Y.jsx)(`span`,{className:`text-[11px] leading-tight text-muted-foreground`,children:n}):null,e?.resetsAt?(0,Y.jsxs)(`span`,{className:`text-[11px] leading-tight text-muted-foreground`,children:[`重置:`,new Date(e.resetsAt).toLocaleString(`zh-CN`,{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`})]}):null]});return(0,Y.jsx)(x,{open:e,onOpenChange:t,children:(0,Y.jsxs)(C,{className:`max-w-[420px]`,children:[(0,Y.jsx)(S,{children:(0,Y.jsx)(s,{children:`限额详情`})}),(0,Y.jsxs)(`div`,{className:`grid gap-1`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,Y.jsx)(`span`,{children:`账号`}),(0,Y.jsx)(`code`,{className:`font-mono`,children:r.maskedKey}),(0,Y.jsx)(`span`,{className:`ml-auto text-xs`,children:i.name})]}),a?(0,Y.jsxs)(`div`,{className:`grid grid-cols-3 gap-2`,children:[u(a.rolling,`5小时`),u(a.weekly,`每周`),u(c,`每月`),a.credits||a.monthlyRemaining!=null?(0,Y.jsxs)(`div`,{className:`col-span-3 flex flex-col gap-1 rounded-md border border-border/70 bg-muted/40 px-3 py-2`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,Y.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`月度额度(Command)`}),a.credits?.belowThreshold?(0,Y.jsx)(B,{tone:`warn`,children:`低于充值线`}):a.credits&&Number.isFinite(Number(a.credits.monthlyCredits))&&Number(a.credits.monthlyCredits)<=0?(0,Y.jsx)(B,{tone:`err`,children:`额度用尽`}):(0,Y.jsx)(B,{tone:`ok`,children:`正常`})]}),(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,Y.jsx)(`span`,{className:`text-[11px] leading-tight text-muted-foreground`,children:Number(a.monthlyResetAt)>Date.now()?`月度额度预计 ${Z(Number(a.monthlyResetAt))} 重置(随订阅续期)`:`月度额度已于 ${Z(Number(a.monthlyResetAt))} 重置`}),l?(0,Y.jsx)(`span`,{className:`text-sm font-semibold tabular-nums text-foreground`,children:l}):null]})]}):null]}):(0,Y.jsx)(`p`,{className:`py-6 text-center text-sm text-muted-foreground`,children:`暂无额度数据 — 点「刷新」获取`}),a?(0,Y.jsxs)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:[`当前用量统计:`,U(r.requests||0),` 次请求 · `,U(r.totalTokens||0),` tokens`,a.monthly?.resetsAt?`。最迟限额将于月窗口重置后自动解除。`:``]}):null]}),(0,Y.jsx)(`div`,{className:`mt-3 flex justify-end`,children:(0,Y.jsx)(n,{onClick:()=>t(!1),variant:`outline`,children:`关闭`})})]})})}function se({open:e,onOpenChange:t,presets:i,proxyApps:o,onDone:c}){let[l,g]=(0,J.useState)(``),[_,y]=(0,J.useState)(``),[w,T]=(0,J.useState)(``),[E,D]=(0,J.useState)(`preset`),[O,k]=(0,J.useState)(!1);async function A(){if(E===`preset`&&!l){a.error(`请选择供应商`);return}if(E===`proxy`&&!_){a.error(`请选择反代应用`);return}k(!0);try{let e=E===`preset`?await d.providerAdd({presetId:l,name:w||void 0,keys:[]}):await d.providerAdd({kind:`proxy`,appId:_,name:w||void 0,keys:[]});if(e.ok===!1){a.error(e.error||`添加失败`);return}a.success(`已添加供应商,请在卡片上点「添加」录入 Key`),t(!1),T(``),g(``),y(``),c()}catch(e){a.error(String(e))}finally{k(!1)}}let j=(i??[]).find(e=>e.id===l);return(0,Y.jsx)(x,{open:e,onOpenChange:t,children:(0,Y.jsxs)(C,{className:`max-w-[420px]`,children:[(0,Y.jsx)(S,{children:(0,Y.jsx)(s,{children:`添加供应商`})}),(0,Y.jsxs)(`div`,{className:`grid gap-3`,children:[(0,Y.jsx)(`div`,{className:`flex gap-1.5 rounded-lg bg-muted p-1`,children:[`preset`,`proxy`].map(e=>(0,Y.jsx)(n,{className:r(`flex-1 rounded-md font-medium`,E===e?`bg-card text-foreground shadow-sm`:`bg-transparent text-muted-foreground hover:bg-card/60 hover:text-foreground`),onClick:()=>D(e),size:`sm`,variant:`ghost`,children:e===`preset`?`直连预设`:`反代应用`},e))}),E===`preset`?(0,Y.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,Y.jsx)(m,{children:`供应商`}),(0,Y.jsxs)(h,{value:l,onValueChange:g,children:[(0,Y.jsx)(p,{className:`w-full`,children:(0,Y.jsx)(v,{placeholder:`-- 选择供应商 --`})}),(0,Y.jsx)(b,{children:(i??[]).map(e=>(0,Y.jsx)(f,{value:e.id,children:e.name},e.id))})]}),j?.note?(0,Y.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:j.note}):null]}):(0,Y.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,Y.jsx)(m,{children:`反代应用`}),(0,Y.jsxs)(h,{value:_,onValueChange:y,children:[(0,Y.jsx)(p,{className:`w-full`,children:(0,Y.jsx)(v,{placeholder:`-- 选择应用 --`})}),(0,Y.jsx)(b,{children:(o??[]).map(e=>(0,Y.jsx)(f,{value:e.id,children:e.name},e.id))})]})]}),(0,Y.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,Y.jsx)(m,{children:`供应商名称(可选)`}),(0,Y.jsx)(u,{placeholder:`自定义名称,如:Open Code ZEN`,value:w,onChange:e=>T(e.target.value)})]}),(0,Y.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`只添加供应商不填 Key;添加后在供应商卡片上点「添加」录入 API Key。`})]}),(0,Y.jsxs)(`div`,{className:`mt-4 flex justify-end gap-2`,children:[(0,Y.jsx)(n,{onClick:()=>t(!1),variant:`outline`,children:`取消`}),(0,Y.jsx)(n,{disabled:O,onClick:()=>void A(),children:O?`添加中…`:`添加供应商`})]})]})})}export{ee as RouterPage};
1
+ import{A as e,F as t,I as n,L as r,N as i,O as a,R as o,S as s,U as c,V as l,_ as u,a as d,d as f,f as p,g as m,l as h,n as g,o as _,p as v,t as y,u as b,v as x,x as S,y as C}from"./supervisor-Dfq_YAmt.js";import{a as w,i as T,n as E,s as D,t as O}from"./openExternal-Ds20EFp9.js";import{n as k,t as A}from"./rocket-Dit4Xpeq.js";import{t as j}from"./refresh-cw-CFZGPyP6.js";import{t as M}from"./jobs-BjLbfJTM.js";import{c as N,f as P,l as F}from"./supervisor-BilTj6si.js";import{t as I}from"./useSupervisorAction-DZSdzPif.js";import{a as L,c as R,i as z,o as B,s as V,t as H}from"./widgets-M2h3F-43.js";import{n as U}from"./format-QeaTKFhQ.js";var W=i(`ban`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M4.929 4.929 19.07 19.071`,key:`196cmz`}]]),G=i(`circle-x`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m15 9-6 6`,key:`1uzhvr`}],[`path`,{d:`m9 9 6 6`,key:`z0biqf`}]]),K=i(`repeat`,[[`path`,{d:`m17 2 4 4-4 4`,key:`nntrym`}],[`path`,{d:`M3 11v-1a4 4 0 0 1 4-4h14`,key:`84bu3i`}],[`path`,{d:`m7 22-4-4 4-4`,key:`1wqhfi`}],[`path`,{d:`M21 13v1a4 4 0 0 1-4 4H3`,key:`1rx37r`}]]),q=i(`terminal`,[[`path`,{d:`M12 19h8`,key:`baeox8`}],[`path`,{d:`m4 17 6-6-6-6`,key:`1yngyt`}]]),J=c(l(),1),Y=o();function X(e){if(!e)return!1;let t=e=>!!(e&&(e.status===`rate-limited`||Number(e.percent)>=100));return t(e.rolling)||t(e.weekly)||t(e.monthly)}function Z(e){return!e||!Number.isFinite(e)?``:new Date(e).toLocaleString(`zh-CN`,{year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`})}function Q(e){return[...e].sort((e,t)=>{let n=e=>e.selected?0:e.usable&&!X(e.quota)?1:2;return n(e)-n(t)})}var $=`grid-cols-[minmax(0,1fr)_230px_84px]`;function ee({onRegisterActions:t}){let{snap:i}=y(),{busy:a,run:o}=I(),[s,c]=(0,J.useState)(!1),[l,u]=(0,J.useState)(!1),f=i.router,p=i.providers;(0,J.useEffect)(()=>(t?.({onAdd:()=>c(!0),onDelete:()=>u(!0)}),()=>t?.(null)),[t]);function m(e,t,n){return o(e,t,{success:n})}let h=p?.providers??[];return(0,Y.jsxs)(`div`,{className:`grid content-start gap-4`,children:[(0,Y.jsxs)(H,{children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 border-b border-border/70 px-5 py-3.5`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Y.jsx)(R,{tone:f?.running?`ok`:`off`,ping:!!f?.running}),(0,Y.jsx)(`strong`,{className:`text-xl font-semibold tracking-[-0.01em] text-foreground`,children:f?.running?`路由运行中`:`路由已停止`})]}),(0,Y.jsx)(n,{"aria-label":f?.running?`停止路由`:`启动路由`,className:r(`px-1`,f?.running?`text-status-error`:`text-primary`),disabled:a===`sw`,onClick:()=>void m(`sw`,()=>f?.running?d.lifecycleStop(`router`):d.lifecycleStart(`router`),f?.running?`路由已停止`:`路由已启动`),title:f?.running?`停止路由`:`启动路由`,variant:`ghost`,children:f?.running?(0,Y.jsx)(k,{className:`size-6`}):(0,Y.jsx)(A,{className:`size-6`})})]}),(0,Y.jsxs)(`div`,{className:`grid grid-cols-1 divide-y divide-border/60 sm:grid-cols-2 sm:divide-y-0 lg:grid-cols-4 lg:divide-x lg:divide-border/60`,children:[(0,Y.jsx)(`div`,{className:`px-5 py-3.5`,children:(0,Y.jsx)(z,{icon:(0,Y.jsx)(P,{className:`size-4`}),label:`总请求 / 失败`,value:U(f?.usage?.requests)+` / `+U(f?.usage?.errors),mono:!0})}),(0,Y.jsx)(`div`,{className:`px-5 py-3.5`,children:(0,Y.jsx)(z,{icon:(0,Y.jsx)(e,{className:`size-4`}),label:`总 Tokens`,value:U(f?.usage?.totalTokens),mono:!0})}),(0,Y.jsx)(`div`,{className:`px-5 py-3.5`,children:(0,Y.jsx)(z,{icon:(0,Y.jsx)(q,{className:`size-4`}),label:`Prompt / Completion`,value:U(f?.usage?.promptTokens)+` / `+U(f?.usage?.completionTokens),mono:!0})}),(0,Y.jsx)(`div`,{className:`px-5 py-3.5`,children:(0,Y.jsx)(z,{icon:(0,Y.jsx)(G,{className:`size-4`}),label:`估算费用`,value:f?.usage?.costUsd?`$`+Number(f.usage.costUsd).toFixed(4):`—`,mono:!0,warn:!f?.usage?.costUsd})})]})]}),h.length?(0,Y.jsx)(`div`,{className:`grid gap-4 @min-[900px]:grid-cols-2`,children:h.map(e=>(0,Y.jsx)(ne,{p:e,proxyApps:p?.proxyApps??[],busy:a===e.id,onAction:m},e.id))}):(0,Y.jsx)(`div`,{className:`grid min-h-[200px] place-items-center rounded-lg border border-dashed border-border text-center`,children:(0,Y.jsxs)(`div`,{children:[(0,Y.jsx)(P,{className:`mx-auto mb-3 size-8 text-muted-foreground`}),(0,Y.jsx)(`p`,{className:`text-sm font-medium text-foreground`,children:`尚未添加供应商`}),(0,Y.jsx)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:`点击「添加供应商」录入 API Key / Command Code`})]})}),(0,Y.jsx)(se,{open:s,onOpenChange:c,presets:p?.presets??[],proxyApps:p?.proxyApps??[],onDone:()=>g.refresh()}),(0,Y.jsx)(te,{open:l,onOpenChange:u,providers:h})]})}function te({open:e,onOpenChange:r,providers:i}){let[o,c]=(0,J.useState)(null),l=t();async function u(e){if(await l({title:`删除供应商「`+e.name+`」?`,description:`其下全部账号与 Key 将被移除,不可恢复。`,confirmText:`删除`,tone:`destructive`})){c(e.id);try{await d.providerRemove(e.id),a.success(`已删除供应商「`+e.name+`」`),await g.refresh()}catch(e){a.error(String(e))}finally{c(null)}}}return(0,Y.jsx)(x,{open:e,onOpenChange:r,children:(0,Y.jsxs)(C,{className:`max-w-[440px]`,children:[(0,Y.jsx)(S,{children:(0,Y.jsx)(s,{children:`删除供应商`})}),(0,Y.jsx)(`div`,{className:`grid gap-1.5`,children:i.length?i.map(e=>(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-md border border-border/70 bg-muted/40 px-3 py-2`,children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,Y.jsx)(`strong`,{className:`truncate text-sm font-medium text-foreground`,children:e.name}),(0,Y.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.kind===`proxy`?`反代`:`直连`,` · `,(e.accounts??[]).length,` 账号`]})]}),(0,Y.jsxs)(n,{disabled:o===e.id,onClick:()=>void u(e),size:`chip`,variant:`destructive`,children:[o===e.id?(0,Y.jsx)(j,{className:`size-3 animate-spin`}):(0,Y.jsx)(N,{className:`size-3`}),`删除`]})]},e.id)):(0,Y.jsx)(`p`,{className:`py-8 text-center text-sm text-muted-foreground`,children:`暂无供应商`})}),(0,Y.jsx)(`div`,{className:`mt-3 flex justify-end`,children:(0,Y.jsx)(n,{onClick:()=>r(!1),variant:`outline`,children:`关闭`})})]})})}function ne({p:e,proxyApps:t,busy:i,onAction:o}){let s=Q(e.accounts??[]),c=s.find(e=>e.selected)||s.find(e=>e.usable&&!X(e.quota))||s[0],[l,u]=(0,J.useState)(!1),f=e.kind===`proxy`?(t??[]).find(t=>t.id===e.proxyAppId)??null:null,p=e.apiBase||(e.apiPort?`http://127.0.0.1:`+e.apiPort+`/v1`:null);return(0,Y.jsxs)(H,{className:`flex min-h-0 flex-col overflow-hidden`,children:[(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 border-b border-border/70 bg-muted px-5 py-3`,children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,Y.jsx)(`strong`,{className:`truncate text-sm font-semibold text-foreground`,children:e.name}),e.kind===`proxy`&&f&&f.installed?f.updateAvailable?(0,Y.jsxs)(n,{className:`gap-1 rounded-full px-2.5 text-xs text-warning`,disabled:i,onClick:()=>void o(`proxy-upd-`+e.id,async()=>{let t=e.proxyAppId,n=await d.proxyUpdateApply(t);if(n.ok===!1){a.error(n.error||`提交失败`);return}let r=a.loading(`正在更新 `+e.name+` 的全部实例…`),i=await M(()=>d.proxyUpdateStatus(t),{onTick:t=>{let n=t?.steps||[],i=n.filter(e=>e.state===`done`).length;n.length&&a.loading(`正在更新 `+e.name+`…(`+i+`/`+n.length+` 实例)`,{id:r})}}),o=i.snapshot;i.state===`done`?a.success(`更新完成`+(o?.restarted?`(已重启 `+o.restarted+` 个实例)`:``),{id:r}):i.state===`failed`?a.error(`更新失败:`+(i.error||(o?.errors?o.errors+` 个实例失败`:`未知原因`)),{id:r}):a.warning(`更新仍在进行(超时未完成,可稍后查看)`,{id:r}),await g.refresh()},void 0),size:`chip`,title:`检测到新版本,点击更新该应用全部实例`,variant:`outline`,children:[(0,Y.jsx)(j,{className:`size-3`}),`更新 v`,f.latest]}):(0,Y.jsxs)(n,{className:`gap-1 rounded-full px-2.5 text-xs font-mono text-muted-foreground`,disabled:i,onClick:()=>{o(`proxy-chk-`+e.id,async()=>{let t=await d.proxyUpdateCheck();if(await g.refresh(),!t.ok){a.error(t.error||`版本检测失败`);return}let n=t.versions?.[e.proxyAppId||``]||null,r=f.installed;a.info(n&&n!==r?`发现新版本 v`+n+`,点击版本胶囊更新`:`已是最新版本 v`+r)},void 0)},size:`chip`,title:`检测是否有新版本`,variant:`outline`,children:[`v`,f.installed,(0,Y.jsx)(j,{className:r(`size-3`,i&&`animate-spin`)})]}):null]}),(0,Y.jsxs)(`div`,{className:`flex shrink-0 flex-wrap items-center gap-1.5`,children:[(0,Y.jsxs)(n,{disabled:i,onClick:()=>u(!0),size:`sm`,variant:`outline`,children:[(0,Y.jsx)(F,{className:`size-3.5`}),`添加`]}),e.activated?(0,Y.jsxs)(n,{disabled:i,onClick:()=>void o(`deact`,()=>d.providerDeactivate(e.id).then(()=>void 0),`已停用供应商(资源已回收)`),size:`sm`,variant:`outline`,children:[(0,Y.jsx)(k,{className:`size-3.5`}),`停用`]}):(0,Y.jsxs)(n,{disabled:i,onClick:()=>void o(`act`,()=>d.providerActivate(e.id).then(()=>void 0),`已启用供应商`),size:`sm`,variant:`outline`,children:[(0,Y.jsx)(A,{className:`size-3.5`}),`启用`]})]})]}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border/60 px-5 py-2.5`,children:[(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`API 地址`}),(0,Y.jsx)(`div`,{className:`flex h-8 min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-card px-2.5`,children:e.activated&&p?(0,Y.jsx)(`code`,{className:`min-w-0 flex-1 truncate font-mono text-xs text-foreground`,children:p}):(0,Y.jsx)(`span`,{className:`truncate text-xs text-muted-foreground/70`,children:`服务未启用`})}),e.activated&&p?(0,Y.jsxs)(n,{onClick:()=>void navigator.clipboard.writeText(p||``).then(()=>a.success(`已复制 API 地址`)),size:`sm`,title:`复制该供应商 API 地址`,variant:`outline`,children:[(0,Y.jsx)(D,{className:`size-3.5`}),`复制`]}):null]}),c?(0,Y.jsx)(ie,{acc:c,busy:i,p:e,onAction:o}):(0,Y.jsx)(`div`,{className:`px-5 py-3 text-xs text-muted-foreground`,children:`暂无账号数据`}),s.length?(0,Y.jsxs)(`div`,{className:`flex min-h-0 flex-col border-t border-border/60`,children:[(0,Y.jsxs)(`div`,{className:r(`grid items-center gap-2 border-b border-border/60 bg-muted/60 px-5 py-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground`,$),children:[(0,Y.jsx)(`span`,{children:`Key`}),(0,Y.jsx)(`span`,{className:`text-center`,children:`用量`}),(0,Y.jsx)(`span`,{className:`text-center`,children:`操作`})]}),(0,Y.jsx)(`div`,{className:`max-h-[288px] min-h-0 overflow-y-auto overscroll-contain`,children:s.map((t,n)=>(0,Y.jsx)(`div`,{className:r(n>0&&`border-t border-border/50`),children:(0,Y.jsx)(ae,{a:t,p:e,busy:i,onAction:o})},t.keyId))})]}):(0,Y.jsx)(`p`,{className:`border-t border-border/60 px-5 py-3 text-xs text-muted-foreground`,children:`暂无 Keys — 点「添加」录入`}),(0,Y.jsx)(re,{open:l,onOpenChange:u,p:e})]})}function re({open:e,onOpenChange:r,p:i}){let o=i.accounts??[],c=t(),[l,u]=(0,J.useState)(``),[f,p]=(0,J.useState)(!1),[h,v]=(0,J.useState)(!1),[y,b]=(0,J.useState)(``),D=i.kind===`proxy`;(0,J.useEffect)(()=>{e&&b(``)},[e]);async function k(){v(!0);try{let e=await E(()=>d.proxyLoginStart());if(b(w(e)),!e||e.ok!==!0)return;let t=T(e);t&&a.warning(t,{duration:12e3});let n=await d.proxyLoginWait(e.waitMs??18e4);if(!n.ok||!n.apiKey){a.error(n.error||`登录未完成`);return}await d.proxyAddKey(i.id,n.apiKey),a.success(`已通过登录添加账号 `+(n.userName||n.keyName||``)),r(!1),await g.refresh()}catch(e){a.error(String(e))}finally{v(!1)}}async function A(){let e=l.split(/[,;\s]+/).map(e=>e.trim()).filter(Boolean);if(!e.length){a.error(`请输入至少一个 Key`);return}p(!0);try{if(D)for(let t of e){let e=await d.proxyAddKey(i.id,t);if(e&&e.limited===`credits`){let t=e.account?.limit?.recovery;a.warning(`已添加:该账号额度用尽`+(t?.type===`at`&&t.at?`(预计 ${Z(t.at)} 自动恢复)`:`(等待月度重置后自动恢复)`))}}else{let t=await d.providerKeysSet(i.id,{add:e});if(t.ok===!1){a.error(t.error||`添加失败`);return}let n=typeof t.added==`number`?t.added:e.length,o=t.discardedKeys||[];if(o.length){let e=o.slice(0,3).map(e=>`${e.key}(${e.error})`).join(`;`);a.warning(`已添加 ${n} 个,${o.length} 个失败被丢弃:${e}${o.length>3?` …`:``}`)}else a.success(`已添加 `+n+` 个 Key(`+(D?`反代账号`:`API Key`)+`)`);u(``),r(!1),await g.refresh();return}a.success(`已添加 `+e.length+` 个 Key(`+(D?`反代账号`:`API Key`)+`)`),u(``),r(!1),await g.refresh()}catch(e){a.error(String(e))}finally{p(!1)}}async function j(e){if(await c({title:`移除 Key `+e+`?`,description:`该凭据将从供应商中移除,不可恢复。`,confirmText:`移除`,tone:`destructive`})){p(!0);try{if(D){let t=o.find(t=>t.maskedKey===e||e.startsWith(t.maskedKey));t&&await d.proxyRemoveKey(i.id,t.keyId)}else{let t=await d.providerKeysSet(i.id,{removeMasked:[e]});if(t.ok===!1){a.error(t.error||`移除失败`);return}}a.success(`已移除`),r(!1),await g.refresh()}catch(e){a.error(String(e))}finally{p(!1)}}}return(0,Y.jsx)(x,{open:e,onOpenChange:r,children:(0,Y.jsxs)(C,{className:`max-w-[440px]`,children:[(0,Y.jsx)(S,{children:(0,Y.jsxs)(s,{children:[`添加 / 管理 Key — `,i.name]})}),(0,Y.jsxs)(`div`,{className:`grid gap-3`,children:[D?(0,Y.jsxs)(`div`,{className:`grid gap-2 rounded-md border border-border/70 bg-muted/40 px-3 py-2.5`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,Y.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,Y.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`一键登录`}),(0,Y.jsx)(`span`,{className:`text-[11px] leading-tight text-muted-foreground`,children:`浏览器打开 Command Code 授权,自动添加账号`})]}),(0,Y.jsx)(n,{disabled:h||f,onClick:()=>void k(),size:`sm`,children:h?`等待授权…`:`一键登录`})]}),y?(0,Y.jsxs)(`div`,{className:`grid gap-1 border-t border-border/60 pt-2`,children:[(0,Y.jsx)(`span`,{className:`text-[11px] leading-tight text-muted-foreground`,children:h?`等待授权中。窗口没弹出或停在空白页时,复制这一行在你的浏览器里打开:`:`本轮授权地址(窗口停在空白页时复制这一行手动打开):`}),(0,Y.jsx)(O,{url:y})]}):null]}):null,(0,Y.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,Y.jsxs)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:[D?`已录入账号(反代)`:`已录入 API Key`,`(`,o.length,`)`]}),o.length?(0,Y.jsx)(`div`,{className:`grid max-h-[180px] gap-1 overflow-auto`,children:o.map(e=>(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-md border border-border/70 bg-muted/40 px-2.5 py-1.5`,children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5`,children:[(0,Y.jsx)(`code`,{className:`truncate font-mono text-xs`,children:e.maskedKey}),e.selected?(0,Y.jsx)(B,{tone:`ok`,children:`当前`}):null]}),(0,Y.jsx)(n,{size:`chip`,variant:`ghost`,className:`text-destructive`,disabled:f,onClick:()=>void j(e.maskedKey),title:`移除该 Key`,children:(0,Y.jsx)(N,{className:`size-3.5`})})]},e.keyId))}):(0,Y.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`尚未录入 `,D?`账号`:`Key`]})]}),(0,Y.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,Y.jsxs)(m,{className:`text-xs text-muted-foreground`,children:[`添加 `,D?`账号 Key / Command Code`:`API Key`,`(每行一个,支持逗号/分号分隔)`]}),(0,Y.jsx)(_,{className:`h-20 resize-none font-mono text-xs`,placeholder:D?`sk-... 或 Command Code,每行一个`:`sk-... 每行一个`,value:l,onChange:e=>u(e.target.value)})]})]}),(0,Y.jsxs)(`div`,{className:`mt-3 flex justify-end gap-2`,children:[(0,Y.jsx)(n,{onClick:()=>r(!1),variant:`outline`,children:`取消`}),(0,Y.jsx)(n,{disabled:f||!l.trim(),onClick:()=>void A(),children:f?`保存中…`:`添加`})]})]})})}function ie({acc:t,busy:i,p:a,onAction:o}){let s=t.quota,c=!!t.selected,l=!!t.locked,u=s&&s.monthlyRemaining,f=s?.monthly?.percent,p=Number.isFinite(Number(f))?f+`%`:Number.isFinite(Number(u))?`$ `+Number(u).toFixed(2):`—`;return(0,Y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4 px-5 py-3`,children:[(0,Y.jsxs)(`div`,{className:`grid min-w-[180px] content-center gap-1`,children:[(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:c?l?`当前账号(锁定)`:`当前在用账号`:`选择账号`}),(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,Y.jsx)(L,{className:`max-w-[150px]`,children:t.maskedKey}),c?(0,Y.jsxs)(n,{className:`gap-1 px-2`,disabled:i,onClick:()=>o(`refresh`,()=>d.providerRefresh(a.id).then(()=>void 0),`额度已刷新`),size:`chip`,variant:`outline`,children:[(0,Y.jsx)(j,{className:r(`size-3`,i&&`animate-spin`)}),`刷新`]}):null]})]}),(0,Y.jsxs)(`div`,{className:`grid min-w-0 flex-1 grid-cols-3 items-stretch gap-2`,children:[(0,Y.jsx)(V,{icon:(0,Y.jsx)(j,{className:`size-3.5`}),label:`5小时`,value:(s?.rolling?.percent??0)+`%`,danger:s?.rolling?.status===`rate-limited`}),(0,Y.jsx)(V,{icon:(0,Y.jsx)(e,{className:`size-3.5`}),label:`每周`,value:(s?.weekly?.percent??0)+`%`,danger:s?.weekly?.status===`rate-limited`}),(0,Y.jsx)(V,{icon:(0,Y.jsx)(P,{className:`size-3.5`}),label:`每月`,value:p,danger:s?.monthly?.status===`rate-limited`||Number(s?.monthly?.percent??0)>=100})]})]})}function ae({a:e,p:t,busy:i,onAction:a}){let o=!!e.selected,s=e.instanceStatus===`frozen`?`frozen`:e.status||``,c=e.limit?.kind,l=s===`frozen`||!!c||!o&&X(e.quota),u=c===`credits`?e.limit?.recovery?.type===`at`&&e.limit?.recovery?.at?`额度用尽(预计 ${Z(e.limit.recovery.at)} 月度重置后自动恢复)`:`额度用尽(待月度重置后自动恢复)`:c===`window`?e.limit?.reason??`时间窗额度已用尽(到 resetAt 自动恢复)`:c===`banned`?`账号被封禁`:null,f=U(e.requests||0)+` 次 · `+U(e.totalTokens||0)+` tok`,[p,m]=(0,J.useState)(!1),h;return h=l&&!o?(0,Y.jsxs)(n,{size:`chip`,variant:`outline`,className:`w-[70px] gap-1 px-1.5`,onClick:()=>m(!0),title:u??`查看该账号限额情况`,children:[(0,Y.jsx)(W,{className:`size-3.5`}),`限额`]}):o?(0,Y.jsxs)(n,{disabled:i,onClick:()=>a(`refresh`,()=>d.providerRefresh(t.id).then(()=>void 0),`额度已刷新`),size:`chip`,variant:`outline`,className:`w-[70px] gap-1 px-1.5`,children:[(0,Y.jsx)(j,{className:r(`size-3.5`,i&&`animate-spin`)}),`刷新`]}):(0,Y.jsxs)(n,{disabled:i,size:`chip`,variant:`outline`,className:`w-[70px] gap-1 px-1.5`,onClick:()=>{t.kind===`proxy`?a(`sel`,()=>d.proxySelect(t.id,e.keyId).then(()=>void 0),`已切换账号`):a(`use`,()=>d.providerKeyUse(t.id,e.keyId).then(()=>void 0),`已锁定 Key`)},children:[(0,Y.jsx)(K,{className:`size-3.5`}),`切换`]}),(0,Y.jsxs)(`div`,{className:r(`grid items-center gap-2 px-5 py-2.5 hover:bg-muted/40`,$,o&&`bg-muted/60 shadow-[inset_3px_0_0_var(--primary)]`),children:[(0,Y.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5`,children:[(0,Y.jsx)(L,{children:e.maskedKey}),s===`registering`?(0,Y.jsx)(B,{tone:`off`,children:`检测中…`}):null,s===`banned`?(0,Y.jsx)(B,{tone:`err`,children:`封号`}):null,c===`credits`?(0,Y.jsx)(`span`,{title:e.limit?.reason??`额度用尽`,children:(0,Y.jsx)(B,{tone:`err`,children:`额度用尽`})}):null,c===`window`?(0,Y.jsx)(`span`,{title:e.limit?.reason??`时间窗额度已用尽`,children:(0,Y.jsx)(B,{tone:`warn`,children:`窗口用尽`})}):null]}),(0,Y.jsx)(`span`,{className:`truncate text-right text-xs tabular-nums text-muted-foreground`,title:f,children:f}),(0,Y.jsx)(`div`,{className:`flex justify-end`,children:h}),(0,Y.jsx)(oe,{open:p,onOpenChange:m,a:e,p:t})]})}function oe({open:e,onOpenChange:t,a:r,p:i}){let a=r.quota,o=(()=>{let e=a?.monthly?.percent;if(e!=null&&Number.isFinite(Number(e)))return Number(e);let t=Number(a?.credits?.monthlyCredits??a?.monthlyRemaining);return Number.isFinite(t)&&t>=0?Math.min(100,Math.round((10-t)/10*100)):0})(),c=a?.monthly?.status?{...a.monthly,percent:o}:{status:`ok`,percent:o,resetsAt:a?.monthly?.resetsAt},l=(()=>{let e=a?.credits?.monthlyCredits,t=a?.monthlyRemaining,n=e!=null&&Number.isFinite(Number(e))?Number(e):t!=null&&Number.isFinite(Number(t))?Number(t):null;return n===null?null:`剩余 $`+n.toFixed(2)})(),u=(e,t,n)=>(0,Y.jsxs)(`div`,{className:`grid gap-1 rounded-md border border-border/70 bg-muted/40 px-3 py-2.5`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Y.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:t}),(0,Y.jsx)(B,{tone:e?.status===`rate-limited`||Number(e?.percent)>=100?`err`:`ok`,children:e?.status===`rate-limited`||Number(e?.percent)>=100?`已限额`:`正常`})]}),(0,Y.jsxs)(`strong`,{className:`text-xl font-semibold tabular-nums text-foreground`,children:[e?.percent??0,`%`]}),n?(0,Y.jsx)(`span`,{className:`text-[11px] leading-tight text-muted-foreground`,children:n}):null,e?.resetsAt?(0,Y.jsxs)(`span`,{className:`text-[11px] leading-tight text-muted-foreground`,children:[`重置:`,new Date(e.resetsAt).toLocaleString(`zh-CN`,{month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`})]}):null]});return(0,Y.jsx)(x,{open:e,onOpenChange:t,children:(0,Y.jsxs)(C,{className:`max-w-[420px]`,children:[(0,Y.jsx)(S,{children:(0,Y.jsx)(s,{children:`限额详情`})}),(0,Y.jsxs)(`div`,{className:`grid gap-1`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,Y.jsx)(`span`,{children:`账号`}),(0,Y.jsx)(`code`,{className:`font-mono`,children:r.maskedKey}),(0,Y.jsx)(`span`,{className:`ml-auto text-xs`,children:i.name})]}),a?(0,Y.jsxs)(`div`,{className:`grid grid-cols-3 gap-2`,children:[u(a.rolling,`5小时`),u(a.weekly,`每周`),u(c,`每月`),a.credits||a.monthlyRemaining!=null?(0,Y.jsxs)(`div`,{className:`col-span-3 flex flex-col gap-1 rounded-md border border-border/70 bg-muted/40 px-3 py-2`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,Y.jsx)(`span`,{className:`text-xs font-medium text-foreground`,children:`月度额度(Command)`}),a.credits?.belowThreshold?(0,Y.jsx)(B,{tone:`warn`,children:`低于充值线`}):a.credits&&Number.isFinite(Number(a.credits.monthlyCredits))&&Number(a.credits.monthlyCredits)<=0?(0,Y.jsx)(B,{tone:`err`,children:`额度用尽`}):(0,Y.jsx)(B,{tone:`ok`,children:`正常`})]}),(0,Y.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,Y.jsx)(`span`,{className:`text-[11px] leading-tight text-muted-foreground`,children:Number(a.monthlyResetAt)>Date.now()?`月度额度预计 ${Z(Number(a.monthlyResetAt))} 重置(随订阅续期)`:`月度额度已于 ${Z(Number(a.monthlyResetAt))} 重置`}),l?(0,Y.jsx)(`span`,{className:`text-sm font-semibold tabular-nums text-foreground`,children:l}):null]})]}):null]}):(0,Y.jsx)(`p`,{className:`py-6 text-center text-sm text-muted-foreground`,children:`暂无额度数据 — 点「刷新」获取`}),a?(0,Y.jsxs)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:[`当前用量统计:`,U(r.requests||0),` 次请求 · `,U(r.totalTokens||0),` tokens`,a.monthly?.resetsAt?`。最迟限额将于月窗口重置后自动解除。`:``]}):null]}),(0,Y.jsx)(`div`,{className:`mt-3 flex justify-end`,children:(0,Y.jsx)(n,{onClick:()=>t(!1),variant:`outline`,children:`关闭`})})]})})}function se({open:e,onOpenChange:t,presets:i,proxyApps:o,onDone:c}){let[l,g]=(0,J.useState)(``),[_,y]=(0,J.useState)(``),[w,T]=(0,J.useState)(``),[E,D]=(0,J.useState)(`preset`),[O,k]=(0,J.useState)(!1);async function A(){if(E===`preset`&&!l){a.error(`请选择供应商`);return}if(E===`proxy`&&!_){a.error(`请选择反代应用`);return}k(!0);try{let e=E===`preset`?await d.providerAdd({presetId:l,name:w||void 0,keys:[]}):await d.providerAdd({kind:`proxy`,appId:_,name:w||void 0,keys:[]});if(e.ok===!1){a.error(e.error||`添加失败`);return}a.success(`已添加供应商,请在卡片上点「添加」录入 Key`),t(!1),T(``),g(``),y(``),c()}catch(e){a.error(String(e))}finally{k(!1)}}let j=(i??[]).find(e=>e.id===l);return(0,Y.jsx)(x,{open:e,onOpenChange:t,children:(0,Y.jsxs)(C,{className:`max-w-[420px]`,children:[(0,Y.jsx)(S,{children:(0,Y.jsx)(s,{children:`添加供应商`})}),(0,Y.jsxs)(`div`,{className:`grid gap-3`,children:[(0,Y.jsx)(`div`,{className:`flex gap-1.5 rounded-lg bg-muted p-1`,children:[`preset`,`proxy`].map(e=>(0,Y.jsx)(n,{className:r(`flex-1 rounded-md font-medium`,E===e?`bg-card text-foreground shadow-sm`:`bg-transparent text-muted-foreground hover:bg-card/60 hover:text-foreground`),onClick:()=>D(e),size:`sm`,variant:`ghost`,children:e===`preset`?`直连预设`:`反代应用`},e))}),E===`preset`?(0,Y.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,Y.jsx)(m,{children:`供应商`}),(0,Y.jsxs)(h,{value:l,onValueChange:g,children:[(0,Y.jsx)(p,{className:`w-full`,children:(0,Y.jsx)(v,{placeholder:`-- 选择供应商 --`})}),(0,Y.jsx)(b,{children:(i??[]).map(e=>(0,Y.jsx)(f,{value:e.id,children:e.name},e.id))})]}),j?.note?(0,Y.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:j.note}):null]}):(0,Y.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,Y.jsx)(m,{children:`反代应用`}),(0,Y.jsxs)(h,{value:_,onValueChange:y,children:[(0,Y.jsx)(p,{className:`w-full`,children:(0,Y.jsx)(v,{placeholder:`-- 选择应用 --`})}),(0,Y.jsx)(b,{children:(o??[]).map(e=>(0,Y.jsx)(f,{value:e.id,children:e.name},e.id))})]})]}),(0,Y.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,Y.jsx)(m,{children:`供应商名称(可选)`}),(0,Y.jsx)(u,{placeholder:`自定义名称,如:Open Code ZEN`,value:w,onChange:e=>T(e.target.value)})]}),(0,Y.jsx)(`p`,{className:`text-xs leading-relaxed text-muted-foreground`,children:`只添加供应商不填 Key;添加后在供应商卡片上点「添加」录入 API Key。`})]}),(0,Y.jsxs)(`div`,{className:`mt-4 flex justify-end gap-2`,children:[(0,Y.jsx)(n,{onClick:()=>t(!1),variant:`outline`,children:`取消`}),(0,Y.jsx)(n,{disabled:O,onClick:()=>void A(),children:O?`添加中…`:`添加供应商`})]})]})})}export{ee as RouterPage};
@@ -1 +1 @@
1
- import{C as e,F as t,I as n,L as r,M as i,O as a,R as o,S as s,T as c,U as l,V as u,_ as d,a as f,d as p,f as m,h,i as g,j as _,l as v,m as y,p as b,s as x,u as S,v as C,w,x as T,y as E}from"./supervisor-Dfq_YAmt.js";import{t as D}from"./refresh-cw-CFZGPyP6.js";import{c as O,l as k}from"./supervisor-BZTzTZDT.js";import{t as A}from"./useSupervisorAction-DZSdzPif.js";import{n as j,o as M,t as N}from"./widgets-M2h3F-43.js";var P=l(u(),1),F=o();function I(){let[e,t]=(0,P.useState)(null),[r,i]=(0,P.useState)(null),[o,s]=(0,P.useState)(null),[c,l]=(0,P.useState)(``),[u,h]=(0,P.useState)(`hide`),{busy:_,run:y}=A(),C=(0,P.useCallback)(async()=>{let[e,n,r,a]=await Promise.all([f.autostart().catch(()=>null),f.lanPanel().catch(()=>null),f.accessKey().catch(()=>null),f.closeAction().catch(()=>null)]);e&&t(e.on),n&&i(n),r&&s(r),a&&h(a.closeAction)},[]);(0,P.useEffect)(()=>{C()},[C]);async function w(e){t(e);try{let n=await f.setAutostart(e);n.ok===!1?(a.error(n.error||`设置失败`),t(!e)):a.success(e?`已开启开机自启(整条服务链)`:`已关闭开机自启`)}catch(n){a.error(String(n)),t(!e)}}async function T(e){i(t=>t&&{...t,enabled:e});try{let t=await f.setLanPanel(e);if(t.ok===!1){a.error(t.error||`设置失败`),i(t=>t&&{...t,enabled:!e});return}i(t),a.success(e?`已开启局域网访问`:`已关闭局域网访问(仅本机)`)}catch(t){a.error(String(t)),i(t=>t&&{...t,enabled:!e})}}async function E(){let e=c.trim();if(e&&e.length<8){a.error(`访问密钥至少 8 位(建议 16+ 位随机串)`);return}await y(`akk`,()=>f.setAccessKey(e),{success:e?`访问密钥已设置`:`访问密钥已清除`,refresh:!1,onDone:()=>{l(``),C()}})&&g(e)}async function D(e){let t=e===`exit`?`exit`:`hide`;h(t),await y(`ca`,()=>f.setCloseAction(t),{success:t===`exit`?`已设为:关闭窗口时退出管家`:`已设为:关闭窗口时隐藏至托盘`,refresh:!1})}return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(N,{children:[(0,F.jsx)(j,{title:`启动`,subtitle:`开机行为与偏好`}),(0,F.jsxs)(`div`,{className:`grid gap-4 px-5 py-4`,children:[(0,F.jsxs)(`div`,{className:`flex items-start justify-between gap-6`,children:[(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(`strong`,{className:`block text-sm font-medium text-foreground`,children:`开机自动启动管家`}),(0,F.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:`开机登录后自动启动 DeepSeek Harness 管家(本程序)。不会自动启动任何单个实例——实例是否被自动拉起,由各自「进程守护」开关决定。`})]}),e===null?(0,F.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`…`}):(0,F.jsx)(`span`,{title:`开机自启`,children:(0,F.jsx)(x,{checked:e,onCheckedChange:e=>void w(e)})})]}),(0,F.jsxs)(`div`,{className:`flex items-start justify-between gap-6 border-t border-border/60 pt-4`,children:[(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(`strong`,{className:`block text-sm font-medium text-foreground`,children:`关闭窗口时`}),(0,F.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:`隐藏至托盘:管家与服务继续在后台运行;退出管家:关闭并停止全部服务。`})]}),(0,F.jsxs)(v,{value:u,onValueChange:e=>void D(e),children:[(0,F.jsx)(m,{className:`w-[150px]`,children:(0,F.jsx)(b,{})}),(0,F.jsxs)(S,{children:[(0,F.jsx)(p,{value:`hide`,children:`隐藏至托盘`}),(0,F.jsx)(p,{value:`exit`,children:`退出管家`})]})]})]})]})]}),(0,F.jsxs)(N,{children:[(0,F.jsx)(j,{title:`访问`}),(0,F.jsxs)(`div`,{className:`grid gap-4 px-5 py-4`,children:[(0,F.jsxs)(`div`,{className:`flex items-start justify-between gap-6`,children:[(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(`strong`,{className:`block text-sm font-medium text-foreground`,children:`管家局域网访问`}),r?r.enabled?(0,F.jsxs)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:[`开启后,局域网内设备可通过\xA0`,(r.urls??[]).map((e,t)=>(0,F.jsxs)(`span`,{children:[t>0?`、 `:null,(0,F.jsx)(`code`,{className:`rounded bg-muted px-1 py-px font-mono text-foreground`,children:e})]},e)),`\xA0访问本面板。`]}):(0,F.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:`关闭后仅本机可访问,局域网设备不可用。`}):null]}),r===null?(0,F.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`…`}):(0,F.jsx)(`span`,{title:`局域网访问`,children:(0,F.jsx)(x,{checked:r.enabled,onCheckedChange:e=>void T(e)})})]}),(0,F.jsx)(`div`,{className:`flex items-start justify-between gap-6 border-t border-border/60 pt-4`,children:(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(`strong`,{className:`block text-sm font-medium text-foreground`,children:`访问密钥`}),(0,F.jsxs)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:[`局域网或公网访问本面板需携带此密钥;本机访问不受影响。留空保存可清除。`,o?.configured?(0,F.jsx)(`span`,{className:`mt-1 block text-status-ok`,children:`当前:已设置`}):(0,F.jsx)(`span`,{className:`mt-1 block text-muted-foreground`,children:`当前:未设置`})]})]})}),(0,F.jsxs)(`div`,{className:`flex gap-2`,children:[(0,F.jsx)(d,{type:`password`,autoComplete:`new-password`,placeholder:`输入 ≥8 位访问密钥(建议随机长串)`,value:c,onChange:e=>l(e.target.value),onKeyDown:e=>{e.key===`Enter`&&E()},className:`flex-1`}),(0,F.jsx)(n,{variant:`outline`,onClick:()=>l(``),disabled:!c&&!o?.configured,children:`清除`}),(0,F.jsx)(n,{disabled:_===`akk`,onClick:()=>void E(),children:o?.configured?`更新密钥`:`设置密钥`})]})]})]})]})}function L(){let[t,o]=(0,P.useState)(null),[s,l]=(0,P.useState)(`auto`),[u,p]=(0,P.useState)([]),[m,g]=(0,P.useState)(``),[v,b]=(0,P.useState)(``),[x,S]=(0,P.useState)(!1),C=(0,P.useRef)(null),{busy:T,run:E}=A();(0,P.useEffect)(()=>{if(!x||!C.current)return;let e=window.setTimeout(()=>{let e=C.current;e&&e.scrollIntoView({block:`start`,behavior:`smooth`})},320);return()=>window.clearTimeout(e)},[x]);let I=(0,P.useCallback)(async()=>{let e=await f.registry().catch(()=>null);o(e)},[]);(0,P.useEffect)(()=>{I()},[I]),(0,P.useEffect)(()=>{t&&(l(t.mode||`auto`),p((t.candidates??[]).map(e=>e.origin)),g(t.manualOrigin||``))},[t]);let L=()=>{let e=v.trim();if(!/^https?:\/\//.test(e)){a.error(`请输入合法的镜像 URL`);return}if(u.includes(e)){a.info(`已在列表中`);return}p(t=>[...t,e]),b(``)};async function z(){let e={mode:s,origins:u};if(s===`manual`){if(!/^https?:\/\//.test(m.trim())){a.error(`手动模式需提供合法镜像 URL`);return}e.manualOrigin=m.trim()}await E(`reg`,()=>f.registrySet(e),{success:`已保存镜像配置`,refresh:!1,onDone:()=>void I()})}async function B(){await E(`regr`,()=>f.registryRefresh(),{success:`已探测镜像`,refresh:!1,onDone:()=>void I()})}let V=e=>{let n=(t?.probes??[]).find(t=>t.origin===e);return n&&n.ok?n.latencyMs:null},H=e=>{let n=(t?.registries??[]).find(t=>t.base===e);if(n&&!n.usable)return`形态非法:`+(n.violation||`未知`);let r=(t?.probes??[]).find(t=>t.origin===e);return r&&!r.ok?`不可达:`+(r.error||`未知`):`未探测`};return(0,F.jsxs)(N,{children:[(0,F.jsx)(j,{title:`镜像源`,subtitle:`npm 拉取 / 更新检测共用此源`}),(0,F.jsxs)(`div`,{className:`grid gap-3 px-5 py-4`,children:[(0,F.jsxs)(y,{value:s,onValueChange:e=>l(e),className:`flex gap-3`,children:[(0,F.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-1.5 text-sm`,children:[(0,F.jsx)(h,{value:`auto`,id:`reg-auto`}),(0,F.jsx)(`span`,{children:`自动(按延迟选最快)`})]}),(0,F.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-1.5 text-sm`,children:[(0,F.jsx)(h,{value:`manual`,id:`reg-manual`}),(0,F.jsx)(`span`,{children:`手动(固定指定)`})]})]}),s===`manual`?(0,F.jsx)(`div`,{className:`grid gap-1.5`,children:(0,F.jsxs)(`div`,{className:`flex gap-2`,children:[(0,F.jsx)(d,{placeholder:`https://registry.npmmirror.com`,value:m,onChange:e=>g(e.target.value),className:`flex-1`}),(0,F.jsx)(n,{variant:`outline`,onClick:()=>void R(m),children:`测试`})]})}):null,(0,F.jsxs)(e,{open:x,onOpenChange:S,className:`grid gap-1`,children:[(0,F.jsxs)(c,{ref:C,children:[(0,F.jsxs)(`span`,{className:`text-xs font-medium text-foreground`,children:[`候选镜像列表(`,u.length,`)`]}),x?(0,F.jsx)(_,{className:`size-3.5 text-muted-foreground`}):(0,F.jsx)(i,{className:`size-3.5 text-muted-foreground`})]}),x?null:(0,F.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-md border border-border/70 px-3 py-1.5`,children:[(0,F.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,F.jsx)(M,{tone:`ok`,children:`当前`}),(0,F.jsx)(`code`,{className:`truncate font-mono text-xs text-muted-foreground`,children:t?.origin||`未选择`})]}),t?.origin&&V(t.origin)!=null?(0,F.jsxs)(`span`,{className:`shrink-0 text-xs font-medium tabular-nums`,children:[V(t.origin),`ms`]}):null]}),(0,F.jsx)(w,{children:(0,F.jsx)(`div`,{className:`rounded-md border border-border/70`,children:u.map((e,r)=>(0,F.jsxs)(`div`,{className:`flex items-center justify-between gap-2 border-b border-border/50 px-3 py-1.5 last:border-b-0`,children:[(0,F.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[t?.origin===e?(0,F.jsx)(M,{tone:`ok`,children:`当前`}):null,(0,F.jsx)(`code`,{className:`truncate font-mono text-xs text-muted-foreground`,children:e})]}),(0,F.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[V(e)==null?(0,F.jsx)(`span`,{className:`text-xs text-muted-foreground/50`,title:H(e),children:`—`}):(0,F.jsxs)(`span`,{className:`text-xs font-medium tabular-nums`,title:`延迟毫秒数(自动探测)`,children:[V(e),(0,F.jsx)(`span`,{className:`text-muted-foreground/60`,children:`ms`})]}),(0,F.jsx)(n,{size:`chip`,variant:`ghost`,onClick:()=>p(t=>t.filter(t=>t!==e)),title:`移除该候选镜像`,children:(0,F.jsx)(O,{className:`size-3.5 text-destructive`})})]})]},r))})})]}),(0,F.jsxs)(`div`,{className:`flex gap-2`,children:[(0,F.jsx)(d,{placeholder:`https://… 添加自定义镜像`,value:v,onChange:e=>b(e.target.value),className:`flex-1`,onKeyDown:e=>{e.key===`Enter`&&L()}}),(0,F.jsxs)(n,{variant:`outline`,onClick:L,children:[(0,F.jsx)(k,{className:`size-4`}),`添加`]})]}),(0,F.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,F.jsxs)(n,{size:`sm`,disabled:T===`regr`,onClick:()=>void B(),variant:`outline`,children:[(0,F.jsx)(D,{className:r(`size-3.5`,T===`regr`&&`animate-spin`)}),`重新探测`]}),(0,F.jsx)(n,{disabled:T===`reg`,onClick:()=>void z(),children:`保存`})]})]})]})}async function R(e){if(!/^https?:\/\//.test(e)){a.error(`请输入合法镜像 URL`);return}a.info(`测试中…`);try{let t=await f.registryProbe(e.replace(/\/+$/,``));t&&t.ok===!0&&typeof t.latencyMs==`number`?a.success(`可达,延迟 `+t.latencyMs+` ms`):t&&typeof t.error==`string`&&t.error?a.error(`探测失败:`+t.error):a.error(`不可达`)}catch(e){a.error(`探测失败:`+(e instanceof Error?e.message:String(e)))}}var z=`lobox:kernel-update-request`,B=`lobox:kernel-update-result`,V=`lobox:kernel-update-progress`,H=12e5;function U(e){return new Promise(t=>{if(!W()){t({ok:!1,error:`内核更新由桌面壳执行:请在桌面壳面板中操作。`});return}let n=`kupd-`+Date.now()+`-`+Math.random().toString(36).slice(2,8),r=Date.now(),i=!1,a=null,o=setTimeout(s,H);function s(){l(a?{ok:!1,error:`桌面壳无响应(更新请求超时;最后一次进度:`+a+`)`}:{ok:!1,error:`桌面壳无响应(更新请求超时)`})}let c=e=>{clearTimeout(o),o=setTimeout(s,Math.max(0,e))},l=e=>{i||(i=!0,window.removeEventListener(`message`,u),clearTimeout(o),t(e))},u=t=>{let i=t.data;if(!(!i||typeof i!=`object`)&&t.source===window.parent&&i.v===2&&(i.type===B||i.type===V)&&i.requestId===n){if(i.type===V){let t=typeof i.status==`string`&&i.status?i.status:null;t&&(a=t),e?.({stage:typeof i.stage==`string`?i.stage:null,status:t,progress:typeof i.progress==`number`?i.progress:null});let n=typeof i.maxWaitMs==`number`?i.maxWaitMs:0;n>0&&c(n-(Date.now()-r));return}l({ok:i.ok===!0,stage:i.stage??null,version:i.version??null,restartUncertain:i.restartUncertain===!0,error:i.error??null})}};window.addEventListener(`message`,u);try{window.parent.postMessage({v:2,type:z,requestId:n},`*`)}catch(e){l({ok:!1,error:String(e)})}})}function W(){try{return window.parent!==window}catch{return!1}}var G=`DeepSeek Harness 管家`,K=`独立于 Harness 运行的系统级守卫:负责启动、存活监测与故障自动重启被监管目标,提供生命周期管理、智能路由、远程控制与多实例沙箱的运维面板。`,q=e=>e?String(e).replace(/^v/i,``):`—`;function J(){let[e,i]=(0,P.useState)(null),[o,c]=(0,P.useState)(null),[l,u]=(0,P.useState)(!1),[d,p]=(0,P.useState)(`dsh`),[m,h]=(0,P.useState)(``),[g,_]=(0,P.useState)(null),{busy:v,run:y}=A(),b=t(),x=(0,P.useCallback)(async e=>{p(e),h(``),u(!0);try{let t=e===`dsh`?await f.dshChangelog():await f.guardChangelog();h(t||`(无内容)`)}catch(e){h(`加载失败:`+String(e))}},[]),S=(0,P.useCallback)(async()=>{let[e,t]=await Promise.all([f.guardVersion().catch(()=>null),f.shellStatus().catch(()=>null)]);i(e||{}),c(t?{version:t.identity?.version||null,capable:t.identity?.selfUpdateCapable===!0,installKind:t.identity?.installKind}:{})},[]);(0,P.useEffect)(()=>{S()},[S]),(0,P.useEffect)(()=>{let e=!0;return(async()=>{let[t,n]=await Promise.all([f.selfUpdateStatus().catch(()=>null),f.shellCheckUpdate().catch(()=>null)]);e&&(t&&t.ok!==!1&&i(e=>({...e||{},...t})),n&&c(e=>({...e||{},latest:n.latest||null,updateAvailable:n.updateAvailable===!0,error:n.error||null})))})(),()=>{e=!1}},[]);let w=async()=>{await y(`chk`,async()=>{let e=`内核:状态未知`,t=await f.selfUpdateStatus().catch(()=>null);if(t&&t.ok!==!1)i(t||{}),e=t.updateAvailable&&t.latest?`内核有新版本 `+q(t.latest)+`(当前 `+q(t.installed)+`)`:`内核已是最新(`+q(t.installed)+`)`;else{let n=await f.guardVersion().catch(()=>null);if(n?.upstream===`git-repo`){let t=await f.guardVersionCheck().catch(()=>null);i({...n||{},...t||{}}),e=t?.updateAvailable?`内核源码仓库有上游更新(当前提交 `+(t.commit||n?.commit||`—`)+`)`:`内核源码仓库已是最新(提交 `+(n?.commit||t?.commit||`—`)+`)`}else e=`内核:`+(t&&t.error||`自更新未配置`)}let n=await f.shellCheckUpdate().catch(()=>null),r=`桌面壳:状态未知`;n&&n.ok!==!1?(c(e=>({...e||{},latest:n.latest||null,updateAvailable:n.updateAvailable===!0,error:null})),r=n.updateAvailable&&n.latest?`桌面壳有新版本 `+q(n.latest)+`(当前 `+q(n.installed)+`)`:`桌面壳已是最新(`+q(n.installed)+`)`):(c(e=>({...e||{},error:n&&n.error||`检测失败`})),r=`桌面壳:`+(n&&n.error||`检测失败`)),t?.updateAvailable&&t?.latest||n?.updateAvailable&&n?.latest?a.warning(e+`;`+r):a.success(e+`;`+r)},{refresh:!1})},O=async()=>{if(!W()){a.error(`内核更新由桌面壳执行:请在桌面壳面板中操作。`);return}await b({title:`发现内核新版本 `+q(e?.latest)+`,是否立即更新?`,description:`内核将由桌面壳安装,并自动重启守卫。`,confirmText:`更新`})&&await y(`upd`,async()=>{_({status:`已向桌面壳发出更新请求,等待响应…`});let t=await U(_);if(!t.ok){a.error(t.error||`更新失败`);return}let n=q(t.version||e?.latest);t.restartUncertain?a.warning(`内核已更新至 `+n+`,但守卫可能未自动重启,请手动确认。`):a.success(`内核已更新至 `+n+`,守卫已重启。`)},{refresh:!0,onDone:()=>_(null)})},k=async()=>{await b({title:`将重启桌面壳以应用更新 `+q(o?.latest)+`,是否继续?`,description:`桌面壳窗口会关闭并重新打开;内核与被管实例不受影响。`,confirmText:`重启桌面壳`})&&await y(`shupd`,async()=>{let e=await f.shellRestart();if(e?.ok===!1){a.error(e.error||`重启桌面壳失败`);return}a.success(`桌面壳正在重启,将在启动时自动更新至 `+q(o?.latest))},{refresh:!1})},I=!!(e?.updateAvailable&&e?.latest&&e.latest!==e?.installed),L=!!(o?.updateAvailable&&o?.latest&&o.latest!==o?.version),R=o?.capable===!1;return(0,F.jsxs)(N,{children:[(0,F.jsx)(j,{title:`关于`,subtitle:G,actions:(0,F.jsxs)(n,{size:`sm`,disabled:v===`chk`,onClick:()=>void w(),variant:`outline`,children:[(0,F.jsx)(D,{className:r(`size-3.5`,v===`chk`&&`animate-spin`)}),`检查更新`]})}),(0,F.jsxs)(`div`,{className:`grid gap-3 px-5 py-4`,children:[(0,F.jsxs)(`div`,{className:`grid grid-cols-[96px_minmax(0,1fr)] items-baseline gap-3`,children:[(0,F.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`桌面壳版本`}),(0,F.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2 text-sm font-medium text-foreground`,children:[q(o?.version),o?.installKind?(0,F.jsxs)(`span`,{className:`text-xs font-normal text-muted-foreground`,children:[`(`,o.installKind,`)`]}):null,L?(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(M,{tone:`warn`,children:[`可更新 `,q(o?.latest)]}),(0,F.jsxs)(n,{size:`chip`,disabled:v===`shupd`,onClick:()=>void k(),variant:`outline`,children:[(0,F.jsx)(D,{className:r(`size-3`,v===`shupd`&&`animate-spin`)}),`重启并更新`]})]}):null,R?(0,F.jsx)(M,{tone:`off`,children:`当前形态不支持自更新`}):null,o?.error?(0,F.jsx)(`span`,{className:`text-xs font-normal text-muted-foreground`,children:o.error}):null]})]}),(0,F.jsxs)(`div`,{className:`grid grid-cols-[96px_minmax(0,1fr)] items-baseline gap-3`,children:[(0,F.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`内核版本`}),(0,F.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2 text-sm font-medium text-foreground`,children:[q(e?.installed||e?.version),I?(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(M,{tone:`warn`,children:[`可更新 `,q(e?.latest)]}),W()?(0,F.jsxs)(n,{size:`chip`,disabled:v===`upd`,onClick:()=>void O(),variant:`outline`,children:[(0,F.jsx)(D,{className:r(`size-3`,v===`upd`&&`animate-spin`)}),`更新`]}):(0,F.jsx)(M,{tone:`off`,children:`请在桌面壳中更新`})]}):null]})]}),g?(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-xs leading-relaxed text-muted-foreground`,children:[(0,F.jsx)(D,{className:`size-3 shrink-0 animate-spin`}),(0,F.jsx)(`span`,{className:`min-w-0 flex-1 break-words`,children:g.status||`桌面壳处理中…`}),typeof g.progress==`number`?(0,F.jsxs)(`span`,{className:`tabular-nums font-medium text-foreground`,children:[Math.round(g.progress*100),`%`]}):null]}):null,(0,F.jsx)(`p`,{className:`border-t border-border/60 pt-3 text-xs leading-relaxed text-muted-foreground`,children:K}),(0,F.jsxs)(`div`,{className:`flex items-center gap-2 border-t border-border/60 pt-3`,children:[(0,F.jsx)(n,{size:`chip`,variant:`outline`,onClick:()=>void x(`dsh`),children:`DSH 更新日志`}),(0,F.jsx)(n,{size:`chip`,variant:`outline`,onClick:()=>void x(`guard`),children:`管家更新日志`})]})]}),(0,F.jsx)(C,{open:l,onOpenChange:u,children:(0,F.jsxs)(E,{className:`max-w-[560px]`,children:[(0,F.jsx)(T,{children:(0,F.jsx)(s,{children:d===`dsh`?`DeepSeek Harness 更新日志`:`管家更新日志`})}),(0,F.jsx)(`pre`,{className:`max-h-[50vh] overflow-auto whitespace-pre-wrap break-words rounded-md border border-border/60 bg-muted/30 p-3 text-xs leading-relaxed text-foreground`,children:m||`加载中…`})]})})]})}function Y(){return(0,F.jsxs)(`div`,{className:`grid content-start gap-4`,children:[(0,F.jsx)(I,{}),(0,F.jsx)(L,{}),(0,F.jsx)(J,{})]})}export{Y as SettingsPage};
1
+ import{C as e,F as t,I as n,L as r,M as i,O as a,R as o,S as s,T as c,U as l,V as u,_ as d,a as f,d as p,f as m,h,i as g,j as _,l as v,m as y,p as b,s as x,u as S,v as C,w,x as T,y as E}from"./supervisor-Dfq_YAmt.js";import{t as D}from"./refresh-cw-CFZGPyP6.js";import{c as O,l as k}from"./supervisor-BilTj6si.js";import{t as A}from"./useSupervisorAction-DZSdzPif.js";import{n as j,o as M,t as N}from"./widgets-M2h3F-43.js";var P=l(u(),1),F=o();function I(){let[e,t]=(0,P.useState)(null),[r,i]=(0,P.useState)(null),[o,s]=(0,P.useState)(null),[c,l]=(0,P.useState)(``),[u,h]=(0,P.useState)(`hide`),{busy:_,run:y}=A(),C=(0,P.useCallback)(async()=>{let[e,n,r,a]=await Promise.all([f.autostart().catch(()=>null),f.lanPanel().catch(()=>null),f.accessKey().catch(()=>null),f.closeAction().catch(()=>null)]);e&&t(e.on),n&&i(n),r&&s(r),a&&h(a.closeAction)},[]);(0,P.useEffect)(()=>{C()},[C]);async function w(e){t(e);try{let n=await f.setAutostart(e);n.ok===!1?(a.error(n.error||`设置失败`),t(!e)):a.success(e?`已开启开机自启(整条服务链)`:`已关闭开机自启`)}catch(n){a.error(String(n)),t(!e)}}async function T(e){i(t=>t&&{...t,enabled:e});try{let t=await f.setLanPanel(e);if(t.ok===!1){a.error(t.error||`设置失败`),i(t=>t&&{...t,enabled:!e});return}i(t),a.success(e?`已开启局域网访问`:`已关闭局域网访问(仅本机)`)}catch(t){a.error(String(t)),i(t=>t&&{...t,enabled:!e})}}async function E(){let e=c.trim();if(e&&e.length<8){a.error(`访问密钥至少 8 位(建议 16+ 位随机串)`);return}await y(`akk`,()=>f.setAccessKey(e),{success:e?`访问密钥已设置`:`访问密钥已清除`,refresh:!1,onDone:()=>{l(``),C()}})&&g(e)}async function D(e){let t=e===`exit`?`exit`:`hide`;h(t),await y(`ca`,()=>f.setCloseAction(t),{success:t===`exit`?`已设为:关闭窗口时退出管家`:`已设为:关闭窗口时隐藏至托盘`,refresh:!1})}return(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(N,{children:[(0,F.jsx)(j,{title:`启动`,subtitle:`开机行为与偏好`}),(0,F.jsxs)(`div`,{className:`grid gap-4 px-5 py-4`,children:[(0,F.jsxs)(`div`,{className:`flex items-start justify-between gap-6`,children:[(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(`strong`,{className:`block text-sm font-medium text-foreground`,children:`开机自动启动管家`}),(0,F.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:`开机登录后自动启动 DeepSeek Harness 管家(本程序)。不会自动启动任何单个实例——实例是否被自动拉起,由各自「进程守护」开关决定。`})]}),e===null?(0,F.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`…`}):(0,F.jsx)(`span`,{title:`开机自启`,children:(0,F.jsx)(x,{checked:e,onCheckedChange:e=>void w(e)})})]}),(0,F.jsxs)(`div`,{className:`flex items-start justify-between gap-6 border-t border-border/60 pt-4`,children:[(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(`strong`,{className:`block text-sm font-medium text-foreground`,children:`关闭窗口时`}),(0,F.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:`隐藏至托盘:管家与服务继续在后台运行;退出管家:关闭并停止全部服务。`})]}),(0,F.jsxs)(v,{value:u,onValueChange:e=>void D(e),children:[(0,F.jsx)(m,{className:`w-[150px]`,children:(0,F.jsx)(b,{})}),(0,F.jsxs)(S,{children:[(0,F.jsx)(p,{value:`hide`,children:`隐藏至托盘`}),(0,F.jsx)(p,{value:`exit`,children:`退出管家`})]})]})]})]})]}),(0,F.jsxs)(N,{children:[(0,F.jsx)(j,{title:`访问`}),(0,F.jsxs)(`div`,{className:`grid gap-4 px-5 py-4`,children:[(0,F.jsxs)(`div`,{className:`flex items-start justify-between gap-6`,children:[(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(`strong`,{className:`block text-sm font-medium text-foreground`,children:`管家局域网访问`}),r?r.enabled?(0,F.jsxs)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:[`开启后,局域网内设备可通过\xA0`,(r.urls??[]).map((e,t)=>(0,F.jsxs)(`span`,{children:[t>0?`、 `:null,(0,F.jsx)(`code`,{className:`rounded bg-muted px-1 py-px font-mono text-foreground`,children:e})]},e)),`\xA0访问本面板。`]}):(0,F.jsx)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:`关闭后仅本机可访问,局域网设备不可用。`}):null]}),r===null?(0,F.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`…`}):(0,F.jsx)(`span`,{title:`局域网访问`,children:(0,F.jsx)(x,{checked:r.enabled,onCheckedChange:e=>void T(e)})})]}),(0,F.jsx)(`div`,{className:`flex items-start justify-between gap-6 border-t border-border/60 pt-4`,children:(0,F.jsxs)(`div`,{className:`min-w-0`,children:[(0,F.jsx)(`strong`,{className:`block text-sm font-medium text-foreground`,children:`访问密钥`}),(0,F.jsxs)(`p`,{className:`mt-1 text-xs leading-relaxed text-muted-foreground`,children:[`局域网或公网访问本面板需携带此密钥;本机访问不受影响。留空保存可清除。`,o?.configured?(0,F.jsx)(`span`,{className:`mt-1 block text-status-ok`,children:`当前:已设置`}):(0,F.jsx)(`span`,{className:`mt-1 block text-muted-foreground`,children:`当前:未设置`})]})]})}),(0,F.jsxs)(`div`,{className:`flex gap-2`,children:[(0,F.jsx)(d,{type:`password`,autoComplete:`new-password`,placeholder:`输入 ≥8 位访问密钥(建议随机长串)`,value:c,onChange:e=>l(e.target.value),onKeyDown:e=>{e.key===`Enter`&&E()},className:`flex-1`}),(0,F.jsx)(n,{variant:`outline`,onClick:()=>l(``),disabled:!c&&!o?.configured,children:`清除`}),(0,F.jsx)(n,{disabled:_===`akk`,onClick:()=>void E(),children:o?.configured?`更新密钥`:`设置密钥`})]})]})]})]})}function L(){let[t,o]=(0,P.useState)(null),[s,l]=(0,P.useState)(`auto`),[u,p]=(0,P.useState)([]),[m,g]=(0,P.useState)(``),[v,b]=(0,P.useState)(``),[x,S]=(0,P.useState)(!1),C=(0,P.useRef)(null),{busy:T,run:E}=A();(0,P.useEffect)(()=>{if(!x||!C.current)return;let e=window.setTimeout(()=>{let e=C.current;e&&e.scrollIntoView({block:`start`,behavior:`smooth`})},320);return()=>window.clearTimeout(e)},[x]);let I=(0,P.useCallback)(async()=>{let e=await f.registry().catch(()=>null);o(e)},[]);(0,P.useEffect)(()=>{I()},[I]),(0,P.useEffect)(()=>{t&&(l(t.mode||`auto`),p((t.candidates??[]).map(e=>e.origin)),g(t.manualOrigin||``))},[t]);let L=()=>{let e=v.trim();if(!/^https?:\/\//.test(e)){a.error(`请输入合法的镜像 URL`);return}if(u.includes(e)){a.info(`已在列表中`);return}p(t=>[...t,e]),b(``)};async function z(){let e={mode:s,origins:u};if(s===`manual`){if(!/^https?:\/\//.test(m.trim())){a.error(`手动模式需提供合法镜像 URL`);return}e.manualOrigin=m.trim()}await E(`reg`,()=>f.registrySet(e),{success:`已保存镜像配置`,refresh:!1,onDone:()=>void I()})}async function B(){await E(`regr`,()=>f.registryRefresh(),{success:`已探测镜像`,refresh:!1,onDone:()=>void I()})}let V=e=>{let n=(t?.probes??[]).find(t=>t.origin===e);return n&&n.ok?n.latencyMs:null},H=e=>{let n=(t?.registries??[]).find(t=>t.base===e);if(n&&!n.usable)return`形态非法:`+(n.violation||`未知`);let r=(t?.probes??[]).find(t=>t.origin===e);return r&&!r.ok?`不可达:`+(r.error||`未知`):`未探测`};return(0,F.jsxs)(N,{children:[(0,F.jsx)(j,{title:`镜像源`,subtitle:`npm 拉取 / 更新检测共用此源`}),(0,F.jsxs)(`div`,{className:`grid gap-3 px-5 py-4`,children:[(0,F.jsxs)(y,{value:s,onValueChange:e=>l(e),className:`flex gap-3`,children:[(0,F.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-1.5 text-sm`,children:[(0,F.jsx)(h,{value:`auto`,id:`reg-auto`}),(0,F.jsx)(`span`,{children:`自动(按延迟选最快)`})]}),(0,F.jsxs)(`label`,{className:`inline-flex cursor-pointer items-center gap-1.5 text-sm`,children:[(0,F.jsx)(h,{value:`manual`,id:`reg-manual`}),(0,F.jsx)(`span`,{children:`手动(固定指定)`})]})]}),s===`manual`?(0,F.jsx)(`div`,{className:`grid gap-1.5`,children:(0,F.jsxs)(`div`,{className:`flex gap-2`,children:[(0,F.jsx)(d,{placeholder:`https://registry.npmmirror.com`,value:m,onChange:e=>g(e.target.value),className:`flex-1`}),(0,F.jsx)(n,{variant:`outline`,onClick:()=>void R(m),children:`测试`})]})}):null,(0,F.jsxs)(e,{open:x,onOpenChange:S,className:`grid gap-1`,children:[(0,F.jsxs)(c,{ref:C,children:[(0,F.jsxs)(`span`,{className:`text-xs font-medium text-foreground`,children:[`候选镜像列表(`,u.length,`)`]}),x?(0,F.jsx)(_,{className:`size-3.5 text-muted-foreground`}):(0,F.jsx)(i,{className:`size-3.5 text-muted-foreground`})]}),x?null:(0,F.jsxs)(`div`,{className:`flex items-center justify-between gap-2 rounded-md border border-border/70 px-3 py-1.5`,children:[(0,F.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,F.jsx)(M,{tone:`ok`,children:`当前`}),(0,F.jsx)(`code`,{className:`truncate font-mono text-xs text-muted-foreground`,children:t?.origin||`未选择`})]}),t?.origin&&V(t.origin)!=null?(0,F.jsxs)(`span`,{className:`shrink-0 text-xs font-medium tabular-nums`,children:[V(t.origin),`ms`]}):null]}),(0,F.jsx)(w,{children:(0,F.jsx)(`div`,{className:`rounded-md border border-border/70`,children:u.map((e,r)=>(0,F.jsxs)(`div`,{className:`flex items-center justify-between gap-2 border-b border-border/50 px-3 py-1.5 last:border-b-0`,children:[(0,F.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[t?.origin===e?(0,F.jsx)(M,{tone:`ok`,children:`当前`}):null,(0,F.jsx)(`code`,{className:`truncate font-mono text-xs text-muted-foreground`,children:e})]}),(0,F.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[V(e)==null?(0,F.jsx)(`span`,{className:`text-xs text-muted-foreground/50`,title:H(e),children:`—`}):(0,F.jsxs)(`span`,{className:`text-xs font-medium tabular-nums`,title:`延迟毫秒数(自动探测)`,children:[V(e),(0,F.jsx)(`span`,{className:`text-muted-foreground/60`,children:`ms`})]}),(0,F.jsx)(n,{size:`chip`,variant:`ghost`,onClick:()=>p(t=>t.filter(t=>t!==e)),title:`移除该候选镜像`,children:(0,F.jsx)(O,{className:`size-3.5 text-destructive`})})]})]},r))})})]}),(0,F.jsxs)(`div`,{className:`flex gap-2`,children:[(0,F.jsx)(d,{placeholder:`https://… 添加自定义镜像`,value:v,onChange:e=>b(e.target.value),className:`flex-1`,onKeyDown:e=>{e.key===`Enter`&&L()}}),(0,F.jsxs)(n,{variant:`outline`,onClick:L,children:[(0,F.jsx)(k,{className:`size-4`}),`添加`]})]}),(0,F.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,F.jsxs)(n,{size:`sm`,disabled:T===`regr`,onClick:()=>void B(),variant:`outline`,children:[(0,F.jsx)(D,{className:r(`size-3.5`,T===`regr`&&`animate-spin`)}),`重新探测`]}),(0,F.jsx)(n,{disabled:T===`reg`,onClick:()=>void z(),children:`保存`})]})]})]})}async function R(e){if(!/^https?:\/\//.test(e)){a.error(`请输入合法镜像 URL`);return}a.info(`测试中…`);try{let t=await f.registryProbe(e.replace(/\/+$/,``));t&&t.ok===!0&&typeof t.latencyMs==`number`?a.success(`可达,延迟 `+t.latencyMs+` ms`):t&&typeof t.error==`string`&&t.error?a.error(`探测失败:`+t.error):a.error(`不可达`)}catch(e){a.error(`探测失败:`+(e instanceof Error?e.message:String(e)))}}var z=`lobox:kernel-update-request`,B=`lobox:kernel-update-result`,V=`lobox:kernel-update-progress`,H=12e5;function U(e){return new Promise(t=>{if(!W()){t({ok:!1,error:`内核更新由桌面壳执行:请在桌面壳面板中操作。`});return}let n=`kupd-`+Date.now()+`-`+Math.random().toString(36).slice(2,8),r=Date.now(),i=!1,a=null,o=setTimeout(s,H);function s(){l(a?{ok:!1,error:`桌面壳无响应(更新请求超时;最后一次进度:`+a+`)`}:{ok:!1,error:`桌面壳无响应(更新请求超时)`})}let c=e=>{clearTimeout(o),o=setTimeout(s,Math.max(0,e))},l=e=>{i||(i=!0,window.removeEventListener(`message`,u),clearTimeout(o),t(e))},u=t=>{let i=t.data;if(!(!i||typeof i!=`object`)&&t.source===window.parent&&i.v===2&&(i.type===B||i.type===V)&&i.requestId===n){if(i.type===V){let t=typeof i.status==`string`&&i.status?i.status:null;t&&(a=t),e?.({stage:typeof i.stage==`string`?i.stage:null,status:t,progress:typeof i.progress==`number`?i.progress:null});let n=typeof i.maxWaitMs==`number`?i.maxWaitMs:0;n>0&&c(n-(Date.now()-r));return}l({ok:i.ok===!0,stage:i.stage??null,version:i.version??null,restartUncertain:i.restartUncertain===!0,error:i.error??null})}};window.addEventListener(`message`,u);try{window.parent.postMessage({v:2,type:z,requestId:n},`*`)}catch(e){l({ok:!1,error:String(e)})}})}function W(){try{return window.parent!==window}catch{return!1}}var G=`DeepSeek Harness 管家`,K=`独立于 Harness 运行的系统级守卫:负责启动、存活监测与故障自动重启被监管目标,提供生命周期管理、智能路由、远程控制与多实例沙箱的运维面板。`,q=e=>e?String(e).replace(/^v/i,``):`—`;function J(){let[e,i]=(0,P.useState)(null),[o,c]=(0,P.useState)(null),[l,u]=(0,P.useState)(!1),[d,p]=(0,P.useState)(`dsh`),[m,h]=(0,P.useState)(``),[g,_]=(0,P.useState)(null),{busy:v,run:y}=A(),b=t(),x=(0,P.useCallback)(async e=>{p(e),h(``),u(!0);try{let t=e===`dsh`?await f.dshChangelog():await f.guardChangelog();h(t||`(无内容)`)}catch(e){h(`加载失败:`+String(e))}},[]),S=(0,P.useCallback)(async()=>{let[e,t]=await Promise.all([f.guardVersion().catch(()=>null),f.shellStatus().catch(()=>null)]);i(e||{}),c(t?{version:t.identity?.version||null,capable:t.identity?.selfUpdateCapable===!0,installKind:t.identity?.installKind}:{})},[]);(0,P.useEffect)(()=>{S()},[S]),(0,P.useEffect)(()=>{let e=!0;return(async()=>{let[t,n]=await Promise.all([f.selfUpdateStatus().catch(()=>null),f.shellCheckUpdate().catch(()=>null)]);e&&(t&&t.ok!==!1&&i(e=>({...e||{},...t})),n&&c(e=>({...e||{},latest:n.latest||null,updateAvailable:n.updateAvailable===!0,error:n.error||null})))})(),()=>{e=!1}},[]);let w=async()=>{await y(`chk`,async()=>{let e=`内核:状态未知`,t=await f.selfUpdateStatus().catch(()=>null);if(t&&t.ok!==!1)i(t||{}),e=t.updateAvailable&&t.latest?`内核有新版本 `+q(t.latest)+`(当前 `+q(t.installed)+`)`:`内核已是最新(`+q(t.installed)+`)`;else{let n=await f.guardVersion().catch(()=>null);if(n?.upstream===`git-repo`){let t=await f.guardVersionCheck().catch(()=>null);i({...n||{},...t||{}}),e=t?.updateAvailable?`内核源码仓库有上游更新(当前提交 `+(t.commit||n?.commit||`—`)+`)`:`内核源码仓库已是最新(提交 `+(n?.commit||t?.commit||`—`)+`)`}else e=`内核:`+(t&&t.error||`自更新未配置`)}let n=await f.shellCheckUpdate().catch(()=>null),r=`桌面壳:状态未知`;n&&n.ok!==!1?(c(e=>({...e||{},latest:n.latest||null,updateAvailable:n.updateAvailable===!0,error:null})),r=n.updateAvailable&&n.latest?`桌面壳有新版本 `+q(n.latest)+`(当前 `+q(n.installed)+`)`:`桌面壳已是最新(`+q(n.installed)+`)`):(c(e=>({...e||{},error:n&&n.error||`检测失败`})),r=`桌面壳:`+(n&&n.error||`检测失败`)),t?.updateAvailable&&t?.latest||n?.updateAvailable&&n?.latest?a.warning(e+`;`+r):a.success(e+`;`+r)},{refresh:!1})},O=async()=>{if(!W()){a.error(`内核更新由桌面壳执行:请在桌面壳面板中操作。`);return}await b({title:`发现内核新版本 `+q(e?.latest)+`,是否立即更新?`,description:`内核将由桌面壳安装,并自动重启守卫。`,confirmText:`更新`})&&await y(`upd`,async()=>{_({status:`已向桌面壳发出更新请求,等待响应…`});let t=await U(_);if(!t.ok){a.error(t.error||`更新失败`);return}let n=q(t.version||e?.latest);t.restartUncertain?a.warning(`内核已更新至 `+n+`,但守卫可能未自动重启,请手动确认。`):a.success(`内核已更新至 `+n+`,守卫已重启。`)},{refresh:!0,onDone:()=>_(null)})},k=async()=>{await b({title:`将重启桌面壳以应用更新 `+q(o?.latest)+`,是否继续?`,description:`桌面壳窗口会关闭并重新打开;内核与被管实例不受影响。`,confirmText:`重启桌面壳`})&&await y(`shupd`,async()=>{let e=await f.shellRestart();if(e?.ok===!1){a.error(e.error||`重启桌面壳失败`);return}a.success(`桌面壳正在重启,将在启动时自动更新至 `+q(o?.latest))},{refresh:!1})},I=!!(e?.updateAvailable&&e?.latest&&e.latest!==e?.installed),L=!!(o?.updateAvailable&&o?.latest&&o.latest!==o?.version),R=o?.capable===!1;return(0,F.jsxs)(N,{children:[(0,F.jsx)(j,{title:`关于`,subtitle:G,actions:(0,F.jsxs)(n,{size:`sm`,disabled:v===`chk`,onClick:()=>void w(),variant:`outline`,children:[(0,F.jsx)(D,{className:r(`size-3.5`,v===`chk`&&`animate-spin`)}),`检查更新`]})}),(0,F.jsxs)(`div`,{className:`grid gap-3 px-5 py-4`,children:[(0,F.jsxs)(`div`,{className:`grid grid-cols-[96px_minmax(0,1fr)] items-baseline gap-3`,children:[(0,F.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`桌面壳版本`}),(0,F.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2 text-sm font-medium text-foreground`,children:[q(o?.version),o?.installKind?(0,F.jsxs)(`span`,{className:`text-xs font-normal text-muted-foreground`,children:[`(`,o.installKind,`)`]}):null,L?(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(M,{tone:`warn`,children:[`可更新 `,q(o?.latest)]}),(0,F.jsxs)(n,{size:`chip`,disabled:v===`shupd`,onClick:()=>void k(),variant:`outline`,children:[(0,F.jsx)(D,{className:r(`size-3`,v===`shupd`&&`animate-spin`)}),`重启并更新`]})]}):null,R?(0,F.jsx)(M,{tone:`off`,children:`当前形态不支持自更新`}):null,o?.error?(0,F.jsx)(`span`,{className:`text-xs font-normal text-muted-foreground`,children:o.error}):null]})]}),(0,F.jsxs)(`div`,{className:`grid grid-cols-[96px_minmax(0,1fr)] items-baseline gap-3`,children:[(0,F.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`内核版本`}),(0,F.jsxs)(`span`,{className:`flex flex-wrap items-center gap-2 text-sm font-medium text-foreground`,children:[q(e?.installed||e?.version),I?(0,F.jsxs)(F.Fragment,{children:[(0,F.jsxs)(M,{tone:`warn`,children:[`可更新 `,q(e?.latest)]}),W()?(0,F.jsxs)(n,{size:`chip`,disabled:v===`upd`,onClick:()=>void O(),variant:`outline`,children:[(0,F.jsx)(D,{className:r(`size-3`,v===`upd`&&`animate-spin`)}),`更新`]}):(0,F.jsx)(M,{tone:`off`,children:`请在桌面壳中更新`})]}):null]})]}),g?(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-xs leading-relaxed text-muted-foreground`,children:[(0,F.jsx)(D,{className:`size-3 shrink-0 animate-spin`}),(0,F.jsx)(`span`,{className:`min-w-0 flex-1 break-words`,children:g.status||`桌面壳处理中…`}),typeof g.progress==`number`?(0,F.jsxs)(`span`,{className:`tabular-nums font-medium text-foreground`,children:[Math.round(g.progress*100),`%`]}):null]}):null,(0,F.jsx)(`p`,{className:`border-t border-border/60 pt-3 text-xs leading-relaxed text-muted-foreground`,children:K}),(0,F.jsxs)(`div`,{className:`flex items-center gap-2 border-t border-border/60 pt-3`,children:[(0,F.jsx)(n,{size:`chip`,variant:`outline`,onClick:()=>void x(`dsh`),children:`DSH 更新日志`}),(0,F.jsx)(n,{size:`chip`,variant:`outline`,onClick:()=>void x(`guard`),children:`管家更新日志`})]})]}),(0,F.jsx)(C,{open:l,onOpenChange:u,children:(0,F.jsxs)(E,{className:`max-w-[560px]`,children:[(0,F.jsx)(T,{children:(0,F.jsx)(s,{children:d===`dsh`?`DeepSeek Harness 更新日志`:`管家更新日志`})}),(0,F.jsx)(`pre`,{className:`max-h-[50vh] overflow-auto whitespace-pre-wrap break-words rounded-md border border-border/60 bg-muted/30 p-3 text-xs leading-relaxed text-foreground`,children:m||`加载中…`})]})})]})}function Y(){return(0,F.jsxs)(`div`,{className:`grid content-start gap-4`,children:[(0,F.jsx)(I,{}),(0,F.jsx)(L,{}),(0,F.jsx)(J,{})]})}export{Y as SettingsPage};
@@ -1,2 +1,2 @@
1
- import{I as e,L as t,O as n,R as r,U as i,V as a,a as o}from"./supervisor-Dfq_YAmt.js";import{t as s}from"./refresh-cw-CFZGPyP6.js";import{a as c,d as l,i as u,r as d}from"./supervisor-BZTzTZDT.js";import{o as f,t as p}from"./widgets-M2h3F-43.js";import{r as m}from"./format-QeaTKFhQ.js";var h=i(a(),1),g=r();function _(){let[r,i]=(0,h.useState)(null),[a,_]=(0,h.useState)(!1),[v,y]=(0,h.useState)(``);async function b(){try{let e=await o.tasks();i(e.tasks)}catch(e){n.error(String(e))}}(0,h.useEffect)(()=>{b()},[]);async function x(){_(!0);try{await b(),n.success(`任务中心已刷新`)}catch{}finally{_(!1)}}let S=[`native`,`instance`,`plugin`,`proxy-app`],C=(r??[]).filter(e=>!v||e.kind===v);return(0,g.jsxs)(`div`,{className:`grid content-start gap-4`,children:[(0,g.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,g.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:[(0,g.jsx)(e,{className:t(v?`text-muted-foreground hover:bg-muted hover:text-foreground`:`bg-primary/10 text-primary hover:bg-primary/15`),onClick:()=>y(``),size:`sm`,variant:`ghost`,children:`全部`}),S.map(n=>(0,g.jsx)(e,{className:t(v===n?`bg-primary/10 text-primary hover:bg-primary/15`:`text-muted-foreground hover:bg-muted hover:text-foreground`),onClick:()=>y(n),size:`sm`,variant:`ghost`,children:u[n]||n},n))]}),(0,g.jsxs)(e,{onClick:()=>void x(),variant:`outline`,children:[(0,g.jsx)(s,{className:t(`size-4`,a&&`animate-spin`)}),`刷新`]})]}),r?C.length?(0,g.jsx)(`div`,{className:`grid gap-3`,children:C.map(e=>{let n=c[e.state]||{label:e.state,tone:`off`},r=e.from&&e.to&&e.from!==e.to?e.from+` → `+e.to:e.to?`→ `+e.to:``,i=e.steps||[];return(0,g.jsxs)(p,{className:`p-4`,children:[(0,g.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,g.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,g.jsx)(`span`,{className:`text-sm font-semibold text-foreground`,children:u[e.kind]||e.kind}),(0,g.jsx)(f,{tone:`boot`,children:d[e.action]||e.action}),(0,g.jsx)(`strong`,{className:`truncate text-sm text-foreground`,children:e.target.name}),r?(0,g.jsx)(`span`,{className:`font-mono text-xs text-muted-foreground`,children:r}):null]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,g.jsx)(f,{tone:n.tone,children:n.label}),(0,g.jsxs)(`span`,{className:`whitespace-nowrap`,children:[m(e.startedAt),e.finishedAt?` ~ `+m(e.finishedAt):``]})]})]}),e.error?(0,g.jsx)(`p`,{className:`mt-2 truncate text-xs text-destructive`,title:e.error,children:e.error}):null,i.length?(0,g.jsx)(`div`,{className:`mt-3 flex flex-wrap items-center gap-1.5`,children:i.map((e,n)=>(0,g.jsxs)(`span`,{className:t(`inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-xs leading-tight`,e.state===`done`&&`bg-success-background text-success`,e.state===`running`&&`bg-primary/10 text-primary`,e.state===`failed`&&`bg-careful-background text-careful`,(!e.state||e.state===`pending`)&&`bg-muted text-muted-foreground`),children:[e.state===`running`?(0,g.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-primary`}):null,e.name]},n))}):null,e.logTail?.length?(0,g.jsxs)(`details`,{className:`mt-3`,children:[(0,g.jsxs)(`summary`,{className:`cursor-pointer text-xs text-muted-foreground hover:text-foreground`,children:[`日志(`,e.logTail.length,`)`]}),(0,g.jsx)(`pre`,{className:`mt-2 max-h-[180px] overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/70 p-3 font-mono text-xs leading-relaxed text-muted-foreground`,children:e.logTail.join(`
1
+ import{I as e,L as t,O as n,R as r,U as i,V as a,a as o}from"./supervisor-Dfq_YAmt.js";import{t as s}from"./refresh-cw-CFZGPyP6.js";import{a as c,d as l,i as u,r as d}from"./supervisor-BilTj6si.js";import{o as f,t as p}from"./widgets-M2h3F-43.js";import{r as m}from"./format-QeaTKFhQ.js";var h=i(a(),1),g=r();function _(){let[r,i]=(0,h.useState)(null),[a,_]=(0,h.useState)(!1),[v,y]=(0,h.useState)(``);async function b(){try{let e=await o.tasks();i(e.tasks)}catch(e){n.error(String(e))}}(0,h.useEffect)(()=>{b()},[]);async function x(){_(!0);try{await b(),n.success(`任务中心已刷新`)}catch{}finally{_(!1)}}let S=[`native`,`instance`,`plugin`,`proxy-app`],C=(r??[]).filter(e=>!v||e.kind===v);return(0,g.jsxs)(`div`,{className:`grid content-start gap-4`,children:[(0,g.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,g.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:[(0,g.jsx)(e,{className:t(v?`text-muted-foreground hover:bg-muted hover:text-foreground`:`bg-primary/10 text-primary hover:bg-primary/15`),onClick:()=>y(``),size:`sm`,variant:`ghost`,children:`全部`}),S.map(n=>(0,g.jsx)(e,{className:t(v===n?`bg-primary/10 text-primary hover:bg-primary/15`:`text-muted-foreground hover:bg-muted hover:text-foreground`),onClick:()=>y(n),size:`sm`,variant:`ghost`,children:u[n]||n},n))]}),(0,g.jsxs)(e,{onClick:()=>void x(),variant:`outline`,children:[(0,g.jsx)(s,{className:t(`size-4`,a&&`animate-spin`)}),`刷新`]})]}),r?C.length?(0,g.jsx)(`div`,{className:`grid gap-3`,children:C.map(e=>{let n=c[e.state]||{label:e.state,tone:`off`},r=e.from&&e.to&&e.from!==e.to?e.from+` → `+e.to:e.to?`→ `+e.to:``,i=e.steps||[];return(0,g.jsxs)(p,{className:`p-4`,children:[(0,g.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,g.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,g.jsx)(`span`,{className:`text-sm font-semibold text-foreground`,children:u[e.kind]||e.kind}),(0,g.jsx)(f,{tone:`boot`,children:d[e.action]||e.action}),(0,g.jsx)(`strong`,{className:`truncate text-sm text-foreground`,children:e.target.name}),r?(0,g.jsx)(`span`,{className:`font-mono text-xs text-muted-foreground`,children:r}):null]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,g.jsx)(f,{tone:n.tone,children:n.label}),(0,g.jsxs)(`span`,{className:`whitespace-nowrap`,children:[m(e.startedAt),e.finishedAt?` ~ `+m(e.finishedAt):``]})]})]}),e.error?(0,g.jsx)(`p`,{className:`mt-2 truncate text-xs text-destructive`,title:e.error,children:e.error}):null,i.length?(0,g.jsx)(`div`,{className:`mt-3 flex flex-wrap items-center gap-1.5`,children:i.map((e,n)=>(0,g.jsxs)(`span`,{className:t(`inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-xs leading-tight`,e.state===`done`&&`bg-success-background text-success`,e.state===`running`&&`bg-primary/10 text-primary`,e.state===`failed`&&`bg-careful-background text-careful`,(!e.state||e.state===`pending`)&&`bg-muted text-muted-foreground`),children:[e.state===`running`?(0,g.jsx)(`span`,{className:`size-1.5 animate-pulse rounded-full bg-primary`}):null,e.name]},n))}):null,e.logTail?.length?(0,g.jsxs)(`details`,{className:`mt-3`,children:[(0,g.jsxs)(`summary`,{className:`cursor-pointer text-xs text-muted-foreground hover:text-foreground`,children:[`日志(`,e.logTail.length,`)`]}),(0,g.jsx)(`pre`,{className:`mt-2 max-h-[180px] overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/70 p-3 font-mono text-xs leading-relaxed text-muted-foreground`,children:e.logTail.join(`
2
2
  `)})]}):null]},e.id)})}):(0,g.jsxs)(`div`,{className:`grid place-items-center rounded-lg border border-dashed border-border py-16 text-center`,children:[(0,g.jsx)(l,{className:`mx-auto mb-3 size-8 text-muted-foreground`}),(0,g.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`暂无任务记录。安装 / 升级 / 卸载 / 更新操作完成后会在此显示状态与历史。`})]}):(0,g.jsx)(`div`,{className:`grid place-items-center py-16 text-sm text-muted-foreground`,children:`加载中…`})]})}export{_ as TasksPage};