baxian 0.4.0 → 0.6.0

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.
@@ -0,0 +1,4 @@
1
+ var pt=Object.defineProperty;var bt=(t,s,r)=>s in t?pt(t,s,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[s]=r;var _=(t,s,r)=>bt(t,typeof s!="symbol"?s+"":s,r);import{r as a,j as e,c as gt}from"./react-BG4Iuztk.js";import{x as jt,a as wt}from"./xterm-D5X2JljJ.js";import{L as de,u as ye,a as Oe,b as vt,B as yt,N as Be,R as Nt,c as ce}from"./router-CApkciQz.js";(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))o(n);new MutationObserver(n=>{for(const i of n)if(i.type==="childList")for(const d of i.addedNodes)d.tagName==="LINK"&&d.rel==="modulepreload"&&o(d)}).observe(document,{childList:!0,subtree:!0});function r(n){const i={};return n.integrity&&(i.integrity=n.integrity),n.referrerPolicy&&(i.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?i.credentials="include":n.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(n){if(n.ep)return;n.ep=!0;const i=r(n);fetch(n.href,i)}})();const Ne="/api",Le="baxian.token",be="baxian:unauthorized";function _e(){try{return typeof localStorage<"u"?localStorage.getItem(Le):null}catch{return null}}function St(t){try{localStorage.setItem(Le,t)}catch(s){console.error("Failed to save auth token to localStorage",s)}}function kt(){try{localStorage.removeItem(Le)}catch(t){console.error("Failed to clear auth token from localStorage",t)}}function ue(t){const s=_e();return{...t??{},...s?{Authorization:`Bearer ${s}`}:{}}}class ge extends Error{constructor(s,r,o){super(r),this.status=s,this.details=o,this.name="ApiError"}}async function he(t){const s=await t.text();let r=s||`HTTP ${t.status}`,o;try{const n=JSON.parse(s);typeof n.error=="string"&&(r=n.error),Array.isArray(n.details)&&(o=n.details)}catch{}throw t.status===401&&typeof window<"u"&&window.dispatchEvent(new CustomEvent(be)),new ge(t.status,r,o)}async function ne(t){const s=await fetch(`${Ne}${t}`,{headers:ue()});return s.ok||await he(s),s.json()}async function Et(){const t=await fetch("/health");return t.ok||await he(t),t.json()}async function Z(t,s,r){const o=s!==void 0,n=await fetch(`${Ne}${t}`,{method:"POST",headers:o?ue({"Content-Type":"application/json"}):ue(),body:o?JSON.stringify(s):void 0,signal:r==null?void 0:r.signal});return n.ok||await he(n),n.json()}async function Rt(t,s,r){const o=await fetch(`${Ne}${t}`,{method:"PATCH",headers:ue({"Content-Type":"application/json"}),body:s?JSON.stringify(s):void 0,signal:r==null?void 0:r.signal});if(o.ok||await he(o),o.status===204)return;const n=await o.text();if(n)return JSON.parse(n)}async function Qe(t){const s=await fetch(`${Ne}${t}`,{method:"DELETE",headers:ue()});if(s.ok||await he(s),s.status===204)return;const r=await s.text();if(r)return JSON.parse(r)}const W=encodeURIComponent,$={agents:{list:()=>ne("/agents"),get:t=>ne(`/agents/${W(t)}`),stop:t=>Qe(`/agents/${W(t)}/session`),probe:(t,s,r)=>Z("/agents/probe",{mode:t,host:s},r)},tasks:{list:t=>ne(`/tasks${t?`?projectId=${W(t)}`:""}`),get:t=>ne(`/tasks/${W(t)}`),create:t=>Z("/tasks",t),update:(t,s)=>Rt(`/tasks/${W(t)}`,s),retry:t=>Z(`/tasks/${W(t)}/retry`),review:t=>Z(`/tasks/${W(t)}/review`)},projects:{list:()=>ne("/projects"),get:t=>ne(`/projects/${W(t)}`),create:t=>Z("/projects",t),addAgent:(t,s)=>Z(`/projects/${W(t)}/agents`,s),deleteAgent:(t,s)=>Qe(`/projects/${W(t)}/agents/${W(s)}`),resumeAgent:(t,s)=>Z(`/projects/${W(t)}/agents/${W(s)}/resume`),bootstrap:t=>Z(`/projects/${W(t)}/bootstrap`)},config:{get:()=>ne("/config")},health:{get:Et},server:{restart:()=>Z("/restart")}},rt=a.createContext(null),Ct={success:"border-[#bbf7d0] bg-[#f0fdf4] text-success",warn:"border-[#fde68a] bg-[#fef3c7] text-warn",error:"border-[#fecaca] bg-[#fef2f2] text-danger"},At={success:"✅",warn:"⚠️",error:"❌"};let Tt=1;function It({children:t}){const[s,r]=a.useState([]),o=a.useCallback(i=>{r(d=>d.filter(p=>p.id!==i))},[]),n=a.useCallback(i=>{const d=Tt++,p=i.durationMs??3e3;r(x=>[...x,{...i,id:d}]),setTimeout(()=>o(d),p)},[o]);return e.jsxs(rt.Provider,{value:{show:n},children:[t,e.jsx("div",{className:"pointer-events-none fixed right-4 top-4 z-[60] flex flex-col gap-2",children:s.map(i=>e.jsx("div",{className:`pointer-events-auto w-80 rounded-lg border px-4 py-3 shadow-toast ${Ct[i.kind]}`,role:"status",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{"aria-hidden":!0,className:"text-[14px]",children:At[i.kind]}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-[13px] font-semibold",children:i.title}),i.body&&e.jsx("div",{className:"mt-1 whitespace-pre-line text-[12px] text-og-700",children:i.body})]}),e.jsx("button",{type:"button",onClick:()=>o(i.id),className:"text-current opacity-50 transition-opacity hover:opacity-100","aria-label":"Dismiss",children:"✕"})]})},i.id))})]})}function fe(){const t=a.useContext(rt);if(!t)throw new Error("useToast must be inside <ToastProvider>");return t}const je="baxian.pendingRestart",Pt=500,$t=3e4,at=a.createContext(null);function Dt(){try{const t=localStorage.getItem(je);if(!t)return{count:0,baselineStartedAt:null};const s=JSON.parse(t);return{count:typeof s.count=="number"?s.count:0,baselineStartedAt:typeof s.baselineStartedAt=="string"?s.baselineStartedAt:null}}catch{return{count:0,baselineStartedAt:null}}}function Ot(t){try{t.count<=0?localStorage.removeItem(je):localStorage.setItem(je,JSON.stringify(t))}catch{}}function Lt({children:t}){const s=Dt(),[r,o]=a.useState(s.count),[n,i]=a.useState(s.baselineStartedAt),[d,p]=a.useState(s.count>0?"pending":"idle"),[x,b]=a.useState(),c=a.useRef(s.count),h=a.useRef(s.count>0?"pending":"idle"),f=a.useRef(0),m=a.useCallback(S=>{c.current=S,o(S)},[]),u=a.useCallback(S=>{o(R=>{const j=S(R);return c.current=j,j})},[]),N=a.useCallback(S=>{h.current=S,p(S)},[]);a.useEffect(()=>{Ot({count:r,baselineStartedAt:n})},[r,n]),a.useEffect(()=>{let S=!1;(async()=>{try{const j=await $.health.get();if(S)return;i(g=>g!==null&&j.startedAt!==g?(m(0),N("idle"),null):g)}catch{}})();const R=j=>{if(j.key===je){if(j.newValue===null){if(h.current==="restarting"&&f.current>0){m(f.current),i(null);return}m(0),i(null),h.current!=="restarting"&&N("idle");return}try{const g=JSON.parse(j.newValue);typeof g.count=="number"&&(h.current==="restarting"&&g.count>c.current&&(f.current+=g.count-c.current),m(g.count),h.current!=="restarting"&&N(g.count>0?"pending":"idle")),typeof g.baselineStartedAt=="string"?i(g.baselineStartedAt):g.baselineStartedAt===null&&i(null)}catch{}}};return window.addEventListener("storage",R),()=>{S=!0,window.removeEventListener("storage",R)}},[m,N]);const l=a.useRef(!1),C=a.useCallback(()=>{u(S=>S+1),h.current==="restarting"?f.current+=1:N("pending"),i(S=>(S!==null||l.current||(l.current=!0,(async()=>{try{const R=await $.health.get();i(j=>j??R.startedAt)}catch{}finally{l.current=!1}})()),S))},[N,u]),T=a.useCallback(async()=>{f.current=0,b(void 0),N("restarting");let S;try{S=(await $.health.get()).startedAt}catch(j){N("failed"),b(`获取重启前 startedAt 失败: ${j instanceof Error?j.message:String(j)}`);return}try{await $.server.restart()}catch(j){if(!(j instanceof ge&&j.status===409)){N("failed"),b(`触发重启失败: ${j instanceof Error?j.message:String(j)}`);return}}const R=Date.now();for(;Date.now()-R<$t;){await new Promise(j=>setTimeout(j,Pt));try{const j=await $.health.get();if(j.startedAt!==S){const g=f.current;f.current=0,i(g>0?j.startedAt:null),m(g),N(g>0?"pending":"idle");return}}catch{}}N("failed"),b("重启超时(30s 未恢复)。请检查日志或手动 baxian start -c <path>")},[m,N]);return e.jsx(at.Provider,{value:{phase:d,count:r,error:x,flagDirty:C,triggerRestart:T},children:t})}function Se(){const t=a.useContext(at);if(!t)throw new Error("usePendingRestart must be used inside PendingRestartProvider");return t}const _t=[500,1e3,2e3,4e3,8e3,15e3,3e4];class it{constructor(s){_(this,"attempts",0);_(this,"timer",null);_(this,"delaysMs");this.opts=s,this.delaysMs=s.delaysMs??_t}schedule(){if(this.timer||!this.shouldReconnect())return;const s=this.delaysMs[Math.min(this.attempts,this.delaysMs.length-1)];this.attempts+=1,this.timer=setTimeout(()=>{this.timer=null,this.shouldReconnect()&&this.opts.reconnect()},s)}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null)}reset(){this.attempts=0}shouldReconnect(){return this.opts.shouldReconnect?this.opts.shouldReconnect():!0}}let qe=0;function Ft(){qe++;const t=Math.random().toString(36).slice(2,8);return`sub-${Date.now().toString(36)}-${qe}-${t}`}function Mt(t){return Array.from(new TextEncoder().encode(t)).map(s=>s.toString(16).padStart(2,"0")).join("")}function zt(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/stream`}const Ut=(t,s)=>s&&s.length>0?new WebSocket(t,s):new WebSocket(t);class Bt{constructor(s={}){_(this,"wsUrl");_(this,"wsFactory");_(this,"tokenProvider");_(this,"ws",null);_(this,"subs",new Map);_(this,"snapshotPending",new Set);_(this,"preSubscribeQueue",new Map);_(this,"outbox",[]);_(this,"reconnectScheduler");_(this,"explicitlyClosed",!1);this.wsUrl=s.wsUrl??zt(),this.wsFactory=s.wsFactory??Ut,this.tokenProvider=s.tokenProvider??_e,this.reconnectScheduler=new it({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.subs.size>0})}subscribe(s){const r=Ft(),o={subscriberId:r,agentId:s.agentId,mode:s.mode,onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone};return this.subs.set(r,o),this.snapshotPending.add(r),this.preSubscribeQueue.set(r,[]),this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",subscriberId:r,agentId:s.agentId,mode:s.mode}),{subscriberId:r,unsubscribe:()=>this.unsubscribe(r)}}send(s,r){if(this.subs.has(s)){if(this.snapshotPending.has(s)){this.outbox.push({op:"input",subscriberId:s,data:r});return}this.wsSendOrQueue({op:"input",subscriberId:s,data:r})}}resize(s,r,o){const n=this.subs.get(s);n&&(n.lastSize={cols:r,rows:o},!this.snapshotPending.has(s)&&this.wsSendOrQueue({op:"resize",subscriberId:s,cols:r,rows:o}))}ping(){this.wsSendOrQueue({op:"ping"})}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.subs.clear(),this.snapshotPending.clear(),this.preSubscribeQueue.clear(),this.outbox=[]}unsubscribe(s){this.subs.has(s)&&(this.subs.delete(s),this.snapshotPending.delete(s),this.preSubscribeQueue.delete(s),this.wsSendOrQueue({op:"unsubscribe",subscriberId:s}),this.subs.size===0&&this.teardownSocket())}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const s=this.tokenProvider(),r=s?[`baxian.token.${Mt(s)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,r)}catch(n){console.warn("[pane-stream] WebSocket constructor threw:",n),this.scheduleReconnect();return}this.ws=o,o.onopen=()=>{if(o!==this.ws)return;this.reconnectScheduler.reset();for(const i of this.subs.values()){this.snapshotPending.add(i.subscriberId),this.preSubscribeQueue.set(i.subscriberId,[]),i.snapshotSeq=void 0;try{o.send(JSON.stringify({op:"subscribe",subscriberId:i.subscriberId,agentId:i.agentId,mode:i.mode}))}catch(d){console.warn("[pane-stream] resubscribe send failed:",d)}}const n=this.outbox;this.outbox=[];for(const i of n)if(i.op!=="subscribe"){if("subscriberId"in i&&i.subscriberId){if(!this.subs.has(i.subscriberId))continue;if(this.snapshotPending.has(i.subscriberId)&&i.op!=="unsubscribe"){this.outbox.push(i);continue}}try{o.send(JSON.stringify(i))}catch(d){console.warn("[pane-stream] outbox flush failed:",d)}}},o.onmessage=n=>{if(o!==this.ws)return;let i;try{const d=typeof n.data=="string"?n.data:String(n.data);i=JSON.parse(d)}catch{return}this.handleMessage(i)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&this.subs.size!==0&&this.scheduleReconnect())},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}wsSendOrQueue(s){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(s));return}catch(r){console.warn("[pane-stream] send failed, will queue:",r)}this.outbox.push(s)}handleMessage(s){var r,o;switch(s.type){case"snapshot":this.handleSnapshot(s);break;case"subscribed":this.handleSubscribed(s);break;case"data":this.dispatch(s);break;case"session_gone":for(const n of[...this.subs.values()])n.agentId===s.agentId&&((r=n.onSessionGone)==null||r.call(n));break;case"error":{if(s.subscriberId){const n=this.subs.get(s.subscriberId);(o=n==null?void 0:n.onError)==null||o.call(n,{code:s.code,message:s.message})}else console.warn("[pane-stream] connection-level error:",s.code,s.message);break}}}handleSnapshot(s){const r=this.subs.get(s.subscriberId);r&&r.onSnapshot({cols:s.cols,rows:s.rows,data:s.data})}handleSubscribed(s){const r=this.subs.get(s.subscriberId);if(!r)return;r.snapshotSeq=s.snapshotSeq,r.lastSize||(r.lastSize={cols:s.cols,rows:s.rows}),this.snapshotPending.delete(s.subscriberId);const o=this.preSubscribeQueue.get(s.subscriberId);if(this.preSubscribeQueue.delete(s.subscriberId),o)for(const n of o)n.seq>s.snapshotSeq&&r.onData(n.data);r.mode==="full"&&r.lastSize&&this.wsSendOrQueue({op:"resize",subscriberId:r.subscriberId,cols:r.lastSize.cols,rows:r.lastSize.rows}),this.flushOutboxForSub(s.subscriberId)}flushOutboxForSub(s){if(this.outbox.length===0||!this.ws||this.ws.readyState!==WebSocket.OPEN)return;const r=[];for(const o of this.outbox)if("subscriberId"in o&&o.subscriberId===s&&o.op!=="subscribe")try{this.ws.send(JSON.stringify(o))}catch(n){console.warn("[pane-stream] flushOutboxForSub send failed:",n)}else r.push(o);this.outbox=r}dispatch(s){for(const r of this.subs.values())if(r.agentId===s.agentId)if(this.snapshotPending.has(r.subscriberId)){const o=this.preSubscribeQueue.get(r.subscriberId);o&&o.push({seq:s.seq,data:s.data})}else r.onData(s.data)}}let Ee=null;function Re(){return Ee||(Ee=new Bt),Ee}function Qt(t){const{agentId:s,mode:r}=t,o=a.useRef(null),n=a.useRef({onSnapshot:t.onSnapshot,onData:t.onData,onError:t.onError,onSessionGone:t.onSessionGone});n.current={onSnapshot:t.onSnapshot,onData:t.onData,onError:t.onError,onSessionGone:t.onSessionGone},a.useEffect(()=>{const x=Re().subscribe({agentId:s,mode:r,onSnapshot:b=>n.current.onSnapshot(b),onData:b=>n.current.onData(b),onError:b=>{var c,h;return(h=(c=n.current).onError)==null?void 0:h.call(c,b)},onSessionGone:()=>{var b,c;return(c=(b=n.current).onSessionGone)==null?void 0:c.call(b)}});return o.current=x.subscriberId,()=>{o.current=null,x.unsubscribe()}},[s,r]);const i=a.useCallback(p=>{const x=o.current;x&&Re().send(x,p)},[]),d=a.useCallback((p,x)=>{const b=o.current;b&&Re().resize(b,p,x)},[]);return{send:i,resize:d}}const qt=18,Wt=250,Gt=256*1024,We="#fdfdfd",Ht='ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',Jt={background:We,foreground:"#474c55",cursor:"#1348dc",cursorAccent:We,selectionBackground:"#eaf0ff",black:"#0d0d0f",red:"#b91c1c",green:"#15803d",yellow:"#b45309",blue:"#1348dc",magenta:"#9333ea",cyan:"#0e7490",white:"#474c55",brightBlack:"#878e9b",brightRed:"#dc2626",brightGreen:"#16a34a",brightYellow:"#d97706",brightBlue:"#3080ff",brightMagenta:"#a855f7",brightCyan:"#0891b2",brightWhite:"#0d0d0f"},Vt=/\x1b\[(?:\?[\d;]*c|>[\d;]*c|\??\d+;\d+R|\d+n)/g;function Kt(t){return t.replace(Vt,"")}function Ie({agentId:t,mode:s,interactive:r=!1,maxLines:o,className:n,autoFocus:i=!0,deferFullUntilFocus:d=!1}){const p=a.useRef(null),x=a.useRef(null),b=a.useRef(null),c=a.useRef(!1),h=a.useRef(""),f=a.useRef([]),m=a.useRef(0),u=a.useRef(null),N=a.useRef(null),l=a.useRef(Promise.resolve()),C=a.useRef(0),[T,S]=a.useState(null),[R,j]=a.useState(!1),g=`${t}\0${s}\0${d?"1":"0"}`,[E,I]=a.useState({key:g,active:!1}),D=E.key===g&&E.active,O=s==="full"&&d,F=O&&!D?"preview":s,P=r&&F==="full",z=(w,L)=>L.length===0?Promise.resolve():new Promise(A=>{try{w.write(L,()=>A())}catch(v){console.warn("[pane-terminal] write failed:",v),A()}}),B=(w,L)=>{l.current=l.current.then(async()=>{const A=x.current;if(!(!A||L!==C.current))try{await w(A)}catch(v){console.warn("[pane-terminal] terminal task failed:",v)}}).catch(A=>{console.warn("[pane-terminal] write chain failed:",A)})},Q=(w,L)=>{B(A=>z(A,w),L)},J=()=>{u.current!==null&&(cancelAnimationFrame(u.current),u.current=null),N.current!==null&&(clearTimeout(N.current),N.current=null)},Y=()=>{J(),f.current=[],m.current=0},H=()=>{J();const w=f.current;w.length!==0&&(f.current=[],m.current=0,Q(w.join(""),C.current))},V=w=>{if(w.length!==0){if(f.current.push(w),m.current+=w.length,m.current>=Gt){H();return}u.current===null&&(u.current=requestAnimationFrame(H)),N.current===null&&(N.current=setTimeout(H,Wt))}},{send:K,resize:se}=Qt({agentId:t,mode:F,onSnapshot:({cols:w,rows:L,data:A})=>{if(x.current)try{const y=C.current+1;C.current=y,Y(),B(async q=>{q.reset(),w>0&&L>0&&q.resize(w,L),await z(q,A)},y)}catch(y){console.warn("[pane-terminal] snapshot write failed:",y)}},onData:w=>{V(w)},onError:w=>S(`${w.code}: ${w.message}`),onSessionGone:()=>j(!0)});a.useEffect(()=>{S(null),j(!1)},[t,F]),a.useEffect(()=>{h.current=""},[g]),a.useEffect(()=>{if(F!=="full")return;const w=h.current;w.length!==0&&(h.current="",K(w))},[K,F]);const G=a.useCallback(()=>{!r||!O||D||(c.current=!0,I({key:g,active:!0}))},[g,D,r,O]);a.useEffect(()=>{const w=p.current;if(!w)return;let L=!1;const A=new jt.Terminal({cursorBlink:r,disableStdin:!r,theme:Jt,fontFamily:Ht,fontSize:13,lineHeight:1.4,scrollback:F==="full"?5e3:1e3}),v=new wt.FitAddon;if(A.loadAddon(v),A.open(w),x.current=A,b.current=v,r&&(i||c.current)){c.current=!1;try{A.focus()}catch{}}r&&A.onData(ie=>{const oe=Kt(ie);if(oe.length!==0){if(O&&!D){h.current+=oe,G();return}K(oe)}});const y=()=>w.clientWidth>0&&w.clientHeight>0,q=(ie=!1)=>{if(!y())return!1;const oe=A.cols,mt=A.rows;try{v.fit()}catch{return!1}return A.cols>0&&A.rows>0&&(ie||A.cols!==oe||A.rows!==mt)&&se(A.cols,A.rows),!0};let U=null,ee=null,xe=null,xt=0;const ze=()=>{U||(U=new ResizeObserver(()=>{ee&&clearTimeout(ee),ee=setTimeout(()=>{ee=null,q()},100)}),U.observe(w))},Ue=()=>{xe=requestAnimationFrame(()=>{if(xe=null,!(L||!P)){if(q(!0)){ze();return}if(xt++<5){Ue();return}ze()}})};return Ue(),()=>{L=!0,xe!==null&&cancelAnimationFrame(xe),u.current!==null&&(cancelAnimationFrame(u.current),u.current=null),N.current!==null&&(clearTimeout(N.current),N.current=null),C.current++,f.current=[],m.current=0,l.current=Promise.resolve(),ee&&clearTimeout(ee),U==null||U.disconnect(),x.current=null,b.current=null;try{A.dispose()}catch(ie){console.warn("[pane-terminal] dispose failed:",ie)}}},[G,t,i,P,D,r,K,O,F,se]);const k=()=>{var w;if(r){G();try{(w=x.current)==null||w.focus()}catch{}}},M=o&&o>0?{maxHeight:`${o*qt}px`}:void 0;return e.jsxs("div",{className:n??"flex flex-col h-full w-full min-h-0 bg-[#fdfdfd]",children:[(T||R)&&e.jsx("div",{className:"border-b border-[#fecaca] bg-[#fef2f2] px-3 py-1 font-mono text-[11px] text-danger",children:R?"session ended":T}),e.jsx("div",{ref:p,className:"flex-1 min-h-0 overflow-hidden px-2 py-1.5",style:M,onMouseDown:k})]})}const Yt={unknown:{label:"Unknown",cls:"pill pill-idle"},idle:{label:"Idle",cls:"pill pill-idle"},pending:{label:"Pending user",cls:"pill pill-warn"},working:{label:"Working",cls:"pill pill-live"},waiting:{label:"Waiting",cls:"pill pill-review"},error:{label:"Error",cls:"pill pill-warn"}},Zt={present:{label:"Session present",modifier:"status-dot--healthy"},absent:{label:"No session",modifier:"status-dot--warn"},unreachable:{label:"Host unreachable",modifier:"status-dot--danger"},unknown:{label:"Session unknown",modifier:"status-dot--warn"},starting:{label:"Starting session",modifier:"status-dot--info"}};function Xt({state:t}){const{label:s,modifier:r}=Zt[t];return e.jsx("span",{role:"img","aria-label":s,title:s,className:`status-dot ${r}`})}function es({agent:t,projectId:s,role:r,onDeleted:o,pendingRestart:n=!1,terminalLoading:i=!1,showTaskBinding:d=!0,terminalMode:p="activity-preview"}){var G,k,M,w,L,A,v;const[x,b]=a.useState(!1),[c,h]=a.useState(null),{show:f}=fe(),{flagDirty:m}=Se(),[u,N]=a.useState(!1),[l,C]=a.useState(null),[T,S]=a.useState(!1),[R,j]=a.useState(!1),[g,E]=a.useState(!1),I=(G=t.binding)==null?void 0:G.taskId,D=((k=t.binding)==null?void 0:k.status)==="awaiting_human",O=!!((M=t.binding)!=null&&M.creationToken)&&!((w=t.binding)!=null&&w.paneId)&&!D&&t.reason!=="PENDING_HUMAN",F=O?{label:"Starting",cls:"pill pill-review"}:Yt[t.runtimeStatus],P=O?"starting":t.tmuxSessionStatus,z=p==="activity-preview"&&!O&&(t.runtimeStatus==="working"||t.runtimeStatus==="pending"),B=p==="embedded-full",Q=i||n||O,J=i?"Agent 状态加载中":n?"重启 baxian server 后可用":"Agent 正在启动",Y=async()=>{b(!0),h(null);try{await $.agents.stop(t.id)}catch(y){h(y instanceof Error?y.message:String(y))}finally{b(!1)}},H=async()=>{if(I&&window.confirm(`请 QA 对 task ${I} 重审?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`)){S(!0);try{const y=await $.tasks.review(I);f({kind:"success",title:`已派 QA 重审 (round ${y.reviewRound})`})}catch(y){f({kind:"error",title:"Review 派发失败",body:y instanceof Error?y.message:String(y)})}finally{S(!1)}}},V=async()=>{E(!0);try{(await $.projects.bootstrap(s)).ok?f({kind:"success",title:"Bootstrap retry 完成",body:"agent 状态将在下一次刷新生效。"}):f({kind:"warn",title:"Bootstrap retry 仍失败",body:"看一下红色错误卡的最新原因,按提示修复后再试。"})}catch(y){f({kind:"error",title:"Bootstrap retry 失败",body:y instanceof Error?y.message:String(y)})}finally{E(!1)}},K=async()=>{if(window.confirm(`确认 Resume Agent ${t.id}?baxian 会清除 awaiting_human 状态,agent 重新可派遣。`)){j(!0);try{const y=await $.projects.resumeAgent(s,t.id);f({kind:"success",title:`Agent ${t.id} 已 Resume`,body:y.releasedBinding?"原任务已释放,agent 可接新任务。":"保留绑定(原任务仍 active)。"})}catch(y){f({kind:"error",title:"Resume 失败",body:y instanceof Error?y.message:String(y)})}finally{j(!1)}}},se=async()=>{if(window.confirm(`确认删除 Agent ${t.id}?此操作不可撤销`)){N(!0),C(null);try{const y=await $.projects.deleteAgent(s,t.id);y!=null&&y.restartRequired&&m();const q=(y==null?void 0:y.removed)??[t.id];if(q.length>1){const U=q.filter(ee=>ee!==t.id).join(", ");f({kind:"warn",title:`已删除 Agent ${t.id}`,body:`配对的 QA Agent ${U} 也被一并移除。`})}else f({kind:"success",title:`Agent ${t.id} 已删除`});o==null||o()}catch(y){C(y instanceof Error?y.message:String(y))}finally{N(!1)}}};return e.jsxs("div",{className:"card flex h-full min-w-0 flex-col p-4",children:[e.jsxs("div",{className:"mb-3 flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx("span",{className:"shrink-0 font-mono text-[11px] font-medium uppercase tracking-[0.05em] text-og-500",children:r}),e.jsx("span",{className:"min-w-0 truncate whitespace-nowrap font-display text-[14px] font-semibold text-og-1000",title:t.id,children:t.id})]}),e.jsxs("div",{className:"flex flex-wrap items-center justify-end gap-1",children:[D&&e.jsx("span",{className:"pill pill-warn",title:((L=t.binding)==null?void 0:L.awaitingReason)??"需人工处理",children:"Held"}),e.jsx("span",{className:F.cls,children:F.label}),t.stale&&e.jsx("span",{className:"pill pill-warn",title:t.observedAt?`Last observed at ${t.observedAt}`:void 0,children:"Stale"}),e.jsx(Xt,{state:P})]})]}),O&&e.jsx("div",{className:"mb-2 rounded-md border border-accent-soft bg-accent-soft/40 px-2.5 py-2 text-[12px] text-accent",children:"Agent 正在启动,终端可用后会自动刷新。"}),D&&e.jsxs("div",{className:"mb-2 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-2.5 py-2 text-[12px] text-warn",children:[e.jsx("span",{className:"font-mono",children:(A=t.binding)==null?void 0:A.awaitingPhase}),((v=t.binding)==null?void 0:v.awaitingReason)&&e.jsxs("span",{children:[" · ",t.binding.awaitingReason]})]}),!O&&t.runtimeStatus==="pending"&&e.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-2.5 py-2 text-[12px] text-warn",children:[e.jsx("div",{className:"font-medium",children:"等待人工介入"}),e.jsxs("div",{children:["Agent 正在等待人工输入。请打开 ",e.jsx(de,{to:`/terminal/${t.id}`,className:"text-accent hover:text-accent-hover underline",children:"Terminal"})," 处理; 处理完后状态会随下一次观测刷新。"]})]}),t.latestError&&e.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-[#fecaca] bg-[#fef2f2] px-2.5 py-2 text-[12px] text-danger",children:[e.jsx("div",{className:"break-words font-medium",children:t.latestError.message}),e.jsxs("div",{className:"font-mono text-[11px] opacity-80",children:[t.latestError.reason," · ",t.latestError.occurredAt]})]}),t.latestBootstrapError&&e.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-[#fecaca] bg-[#fef2f2] px-2.5 py-2 text-[12px] text-danger",children:[e.jsx("div",{className:"break-words font-medium",children:t.latestBootstrapError.message}),t.latestBootstrapError.recommendation&&e.jsx("div",{className:"break-words",children:t.latestBootstrapError.recommendation}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"truncate font-mono text-[11px] opacity-80",children:[t.latestBootstrapError.reason," · ",t.latestBootstrapError.occurredAt]}),e.jsx("button",{type:"button",onClick:V,disabled:g,className:"btn-secondary shrink-0 !border-[#fecaca] !text-danger hover:!bg-[#fef2f2] hover:!border-danger hover:!text-danger",children:g?"Retrying…":"Retry bootstrap"})]})]}),d&&I&&e.jsxs("div",{className:"mb-2 text-[12px] text-og-500",children:["Task: ",e.jsx("span",{className:"font-mono text-og-700",children:I})]}),z&&e.jsx("div",{className:"mb-2 overflow-hidden rounded-md border border-hairline bg-surface",children:e.jsx(Ie,{agentId:t.id,mode:"preview",maxLines:6,interactive:!1})}),B&&e.jsx("div",{className:"mb-2 mt-3 h-80 min-h-0 overflow-hidden rounded-md border border-hairline bg-surface",children:Q?e.jsx("div",{className:"flex h-full items-center justify-center px-3 text-[13px] text-og-500",children:J}):e.jsx(Ie,{agentId:t.id,mode:"full",interactive:!0,autoFocus:!1,deferFullUntilFocus:!0})}),n&&e.jsx("div",{className:"mb-2 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-2.5 py-1.5 text-[12px] text-warn",children:"⚠️ 重启 baxian server 后生效"}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[Q?e.jsx("span",{className:"cursor-not-allowed text-[13px] text-og-400",title:J,children:"Terminal"}):e.jsx(de,{to:`/terminal/${t.id}`,className:"btn-secondary",children:"Terminal"}),!n&&t.runtimeStatus==="working"&&e.jsx("button",{onClick:Y,disabled:x,className:"btn-ghost !text-danger hover:!bg-[#fef2f2]",children:x?"Stopping…":"Stop"}),c&&e.jsx("span",{className:"text-[12px] text-danger",children:c}),D&&e.jsx("button",{type:"button",onClick:K,disabled:R,title:"清除 awaiting_human 状态,让 agent 重新可派遣",className:"btn-ghost !text-warn hover:!bg-[#fef3c7]/60",children:R?"Resuming…":"Resume"}),!n&&I&&r==="dev"&&e.jsx("button",{type:"button",onClick:H,disabled:T,title:`让 QA 立即对 task ${I} 跑一轮 review(需要该 task 已有 PR)`,className:"btn-ghost !text-accent hover:!bg-accent-soft",children:T?"Dispatching…":"Request QA review"}),e.jsx("button",{type:"button",onClick:se,disabled:u,className:"btn-ghost ml-auto !text-danger hover:!bg-[#fef2f2]","aria-label":`Delete agent ${t.id}`,children:u?"删除中…":"🗑"}),l&&e.jsx("span",{className:"text-[12px] text-danger",children:l})]})]})}const ts=new Set(["in_progress","review","fixing","approved"]);function ot({group:t,projectId:s,agentsById:r,agentsLoaded:o,agentsError:n=!1,tasks:i,onDeleted:d,terminalMode:p="activity-preview"}){const x=t.find(m=>m.role==="dev")??t[0],b=t.find(m=>m.role==="qa"),c=i.filter(m=>ss(m,x==null?void 0:x.id,b==null?void 0:b.id)),h=`Agent group ${t.map(m=>m.id).join(" / ")}`,f=p==="embedded-full"?t.length<=1?"lg:grid-cols-1":t.length===2?"lg:grid-cols-2":t.length===3?"lg:grid-cols-3":"lg:grid-cols-4":"sm:grid-cols-2";return e.jsxs("div",{role:"group","aria-label":h,className:"min-w-0",children:[c.length>0?e.jsx("div",{className:"card mb-2 max-h-28 overflow-y-auto divide-y divide-hairline",children:c.map(m=>{const u=m.phase==="spec"?m.specReviewRound??0:m.reviewRound;return e.jsxs(de,{to:`/task/${m.id}`,className:"flex items-center gap-3 px-3 py-2 text-[13px] transition-colors hover:bg-og-50/60",children:[e.jsxs("div",{className:"min-w-0 flex-1 flex items-center gap-2",children:[e.jsx("span",{className:"shrink-0 font-mono text-[11px] text-og-500",children:m.id}),e.jsx("span",{className:"truncate text-og-1000",children:m.title})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[e.jsx("span",{className:"pill",children:m.status}),e.jsxs("span",{"aria-label":`Round ${u}`,className:"pill pill-review",children:["Round ",u]})]})]},m.id)})}):e.jsx("div",{className:"mb-2 rounded-lg border border-hairline bg-surface px-3 py-2 text-[13px] text-og-400","aria-label":`${h} no active task`,children:"暂无任务"}),e.jsx("div",{className:`grid grid-cols-1 ${f} gap-4`,children:t.map(m=>{const u=r.get(m.id),N=u??{id:m.id,projectId:s,runtimeStatus:"unknown",tmuxSessionStatus:"unknown",stale:!0};return e.jsx(es,{agent:N,projectId:s,role:m.role,pendingRestart:o&&!u,terminalLoading:!o&&!u&&!n,onDeleted:d,showTaskBinding:!1,terminalMode:p},m.id)})})]})}function ss(t,s,r){return!(!s||!ts.has(t.status)||!(t.agentId===s||t.preferredAgentId===s)||r&&t.qaAgentId&&t.qaAgentId!==r)}const ns={sm:"max-w-md",md:"max-w-lg",lg:"max-w-2xl"},Ge='input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])';function ke({open:t,onClose:s,title:r,children:o,size:n="md"}){const i=a.useRef(null),d=a.useRef(null),p=a.useRef(s);return a.useEffect(()=>{p.current=s},[s]),a.useEffect(()=>{if(!t)return;d.current=document.activeElement;const x=h=>{if(h.key==="Escape"){p.current();return}if(h.key!=="Tab")return;const f=i.current;if(!f)return;const m=Array.from(f.querySelectorAll(Ge)).filter(C=>C.offsetParent!==null||C===document.activeElement);if(m.length===0){h.preventDefault();return}const u=m[0],N=m[m.length-1],l=document.activeElement;h.shiftKey&&(l===u||!f.contains(l))?(h.preventDefault(),N.focus()):!h.shiftKey&&(l===N||!f.contains(l))&&(h.preventDefault(),u.focus())};document.addEventListener("keydown",x);const b=document.body.style.overflow;document.body.style.overflow="hidden";const c=i.current;if(c){const h=c.querySelector(Ge);h==null||h.focus()}return()=>{var h,f;document.removeEventListener("keydown",x),document.body.style.overflow=b,(f=(h=d.current)==null?void 0:h.focus)==null||f.call(h)}},[t]),t?e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-og-1000/45 px-3 sm:px-4",onClick:()=>p.current(),role:"presentation",children:e.jsxs("div",{ref:i,className:`w-full ${ns[n]} max-h-[90vh] overflow-auto rounded-lg border border-og-100 bg-surface shadow-modal`,onClick:x=>x.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":r,children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-hairline px-6 py-4",children:[e.jsx("h2",{className:"font-display text-[16px] font-semibold tracking-tight text-og-1000",children:r}),e.jsx("button",{type:"button",onClick:()=>p.current(),className:"text-og-400 transition-colors hover:text-og-800","aria-label":"Close",children:"✕"})]}),e.jsx("div",{className:"px-6 py-5",children:o})]})}):null}const rs=/^[a-z][a-z0-9-]{1,31}$/,as=/^[A-Za-z0-9_-][A-Za-z0-9._-]*\/[A-Za-z0-9_-][A-Za-z0-9._-]*$/,He="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",Ce="mb-1.5 block text-[12px] font-medium text-og-700",Je="mt-1 text-[12px] text-danger";function is({open:t,onClose:s,onCreated:r}){const[o,n]=a.useState(""),[i,d]=a.useState(""),[p,x]=a.useState(null),[b,c]=a.useState(!1),[h,f]=a.useState(null),[m,u]=a.useState({}),[N,l]=a.useState(new Set),C=a.useRef(0),{show:T}=fe(),{flagDirty:S}=Se();a.useEffect(()=>{if(!t)return;C.current+=1;const E=C.current;n(""),d(""),x(null),f(null),u({}),l(new Set),$.config.get().then(I=>{E===C.current&&l(new Set(I.project.map(D=>D.id)))}).catch(()=>{})},[t]);const R=()=>{b||s()},j=()=>{const E={};return o?rs.test(o)?N.has(o)&&(E.id="该 id 已被占用"):E.id="小写字母开头,只含 a-z 0-9 -,长度 2-32":E.id="必填",i?as.test(i)||(E.repo="需为 owner/repo 形式"):E.repo="必填",u(E),Object.keys(E).length===0},g=async E=>{if(E.preventDefault(),!!j()){c(!0),f(null);try{const I=await $.projects.create({id:o,repo:i,merge:p});I.restartRequired&&S(),T({kind:"success",title:`项目 ${I.project.id} 已创建`}),r(I.project.id)}catch(I){f(I instanceof Error?I.message:String(I))}finally{c(!1)}}};return e.jsx(ke,{open:t,onClose:R,title:"新建项目",size:"md",children:e.jsxs("form",{onSubmit:g,className:"space-y-4",children:[h&&e.jsx("div",{className:"rounded-md border border-[#fecaca] bg-[#fef2f2] px-3 py-2 text-[13px] text-danger",children:h}),e.jsxs("div",{children:[e.jsx("label",{className:Ce,htmlFor:"proj-id",children:"项目 ID"}),e.jsx("input",{id:"proj-id",type:"text",value:o,onChange:E=>n(E.target.value),className:He,placeholder:"kongkong",disabled:b}),m.id&&e.jsx("div",{className:Je,children:m.id})]}),e.jsxs("div",{children:[e.jsx("label",{className:Ce,htmlFor:"proj-repo",children:"GitHub 仓库"}),e.jsx("input",{id:"proj-repo",type:"text",value:i,onChange:E=>d(E.target.value),className:He,placeholder:"rockdai/baxian",disabled:b}),m.repo&&e.jsx("div",{className:Je,children:m.repo})]}),e.jsxs("div",{children:[e.jsx("span",{className:Ce,children:"合并策略"}),e.jsxs("label",{className:"mb-1 flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"merge",checked:p===null,onChange:()=>x(null),disabled:b,className:"h-3.5 w-3.5 accent-[#1348dc]"}),e.jsx("span",{className:"text-[13px] text-og-800",children:"人类合并(默认)"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"merge",checked:p==="auto",onChange:()=>x("auto"),disabled:b,className:"h-3.5 w-3.5 accent-[#1348dc]"}),e.jsx("span",{className:"text-[13px] text-og-800",children:"QA Approve 后自动合并"})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-hairline pt-4",children:[e.jsx("button",{type:"button",onClick:R,disabled:b,className:"btn-secondary",children:"取消"}),e.jsx("button",{type:"submit",disabled:b,className:"btn-primary",children:b?"创建中…":"创建"})]})]})})}const Ve=/^[a-z][a-z0-9-]{1,31}$/,os=500,re="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",X="mb-1.5 block text-[12px] font-medium text-og-700",Ke="mt-1 text-[12px] text-danger",Ae="mt-1 text-[12px] text-og-500",ae="h-3.5 w-3.5 accent-[#1348dc]",Ye={id:"",role:"dev",pairWith:"",mode:"local",hostname:"",user:"",runtime:"",workdir:"",yolo:!0,model:"",addDirs:""};function ct({open:t,onClose:s,projectId:r,onCreated:o}){var G;const[n,i]=a.useState(Ye),[d,p]=a.useState(null),[x,b]=a.useState(new Set),[c,h]=a.useState(null),[f,m]=a.useState(!1),[u,N]=a.useState(!1),[l,C]=a.useState(null),T=a.useRef(null),S=a.useRef(null),R=a.useRef(0),{show:j}=fe(),{flagDirty:g}=Se();a.useEffect(()=>{if(!t)return;R.current+=1;const k=R.current;i(Ye),p(null),b(new Set),h(null),m(!1),C(null),$.config.get().then(M=>{if(k!==R.current)return;const w=M.project.find(A=>A.id===r)??null;p(w);const L=new Set;M.project.forEach(A=>A.agent.forEach(v=>v.forEach(y=>L.add(y.id)))),b(L)}).catch(()=>{})},[t,r]);const E=()=>{u||s()},I=a.useCallback(()=>{T.current&&T.current.abort();const k=new AbortController;T.current=k,m(!0),C(null);const M=n.mode==="remote"?{hostname:n.hostname,user:n.user||void 0}:void 0;$.agents.probe(n.mode,M,{signal:k.signal}).then(w=>{k.signal.aborted||(h(w),C(null))}).catch(w=>{k.signal.aborted||(h(null),C(w instanceof Error?w.message:String(w)))}).finally(()=>{T.current===k&&m(!1)})},[n.mode,n.hostname,n.user]);a.useEffect(()=>{if(t&&(h(null),T.current&&T.current.abort(),!(n.mode==="remote"&&!n.hostname)))return S.current&&clearTimeout(S.current),S.current=setTimeout(I,os),()=>{S.current&&clearTimeout(S.current)}},[t,n.mode,n.hostname,n.user,I]),a.useEffect(()=>{t||T.current&&T.current.abort()},[t]),a.useEffect(()=>()=>{T.current&&T.current.abort(),S.current&&clearTimeout(S.current)},[]);const D=(d==null?void 0:d.agent.filter(k=>k.length===1&&k[0].role==="dev").map(k=>k[0]))??[],O=D.length>0,F=Ve.test(n.id)&&!x.has(n.id),P=n.mode==="local"||n.mode==="remote"&&n.hostname.length>0,z=n.runtime!==""&&(n.runtime==="claude-code"?!!(c!=null&&c.runtimes["claude-code"].ok):!!(c!=null&&c.runtimes.codex.ok)),B=!!(c!=null&&c.tmux.ok),Q=n.mode==="local"||!!((G=c==null?void 0:c.ssh)!=null&&G.ok),J=n.role==="dev"||n.role==="qa"&&n.pairWith!=="",Y=!u&&F&&P&&J&&z&&B&&Q,H=async k=>{if(k.preventDefault(),!!Y){N(!0),C(null);try{const M=n.addDirs.split(`
2
+ `).map(A=>A.trim()).filter(A=>A.length>0),w={id:n.id,role:n.role,runtime:n.runtime,mode:n.mode,...n.mode==="remote"?{host:{hostname:n.hostname,...n.user?{user:n.user}:{}}}:{},...n.workdir?{workdir:n.workdir}:{},yolo:n.yolo,...n.model.trim()?{model:n.model.trim()}:{},...M.length>0?{addDirs:M}:{},...n.role==="qa"?{pairWith:n.pairWith}:{}},L=await $.projects.addAgent(r,w);L.restartRequired&&g(),j({kind:"success",title:`Agent ${L.agent.id} 已添加到 ${r}`}),o(),s()}catch(M){C(M instanceof Error?M.message:String(M))}finally{N(!1)}}},V=({rt:k})=>{if(n.mode==="remote"&&!n.hostname)return e.jsx("span",{className:"ml-2 text-[12px] text-og-400",children:"(请先填写 hostname)"});if(f)return e.jsx("span",{className:"ml-2 text-[12px] text-og-400",children:"…探测中"});if(!c)return e.jsx("span",{className:"ml-2 text-[12px] text-og-400",children:"?"});const w=c.runtimes[k];return w.ok?e.jsxs("span",{className:"ml-2 text-[12px] text-success",children:["✓ ",w.path??""]}):e.jsxs("span",{className:"ml-2 text-[12px] text-danger",title:w.message,children:["⨯ ",w.message]})},K=()=>n.mode==="remote"&&!n.hostname?null:f?e.jsx("div",{className:"text-[12px] text-og-400",children:"tmux: …探测中"}):c?c.tmux.ok?e.jsxs("div",{className:"text-[12px] text-success",children:["tmux: ✓ ",c.tmux.path??""]}):e.jsxs("div",{className:"text-[12px] text-danger",children:["tmux: ⨯ ",c.tmux.message]}):null,se=()=>n.mode!=="remote"||!n.hostname||!(c!=null&&c.ssh)?null:c.ssh.ok?e.jsxs("div",{className:"text-[12px] text-success",children:["SSH: ✓ ",c.ssh.message]}):e.jsxs("div",{className:"text-[12px] text-danger",children:["SSH: ⨯ ",c.ssh.message]});return e.jsx(ke,{open:t,onClose:E,title:`添加 Agent 到 ${r}`,size:"lg",children:e.jsxs("form",{onSubmit:H,className:"space-y-4",children:[l&&e.jsx("div",{className:"rounded-md border border-[#fecaca] bg-[#fef2f2] px-3 py-2 text-[13px] text-danger",children:l}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"agent-id",children:"Agent ID"}),e.jsx("input",{id:"agent-id",type:"text",value:n.id,onChange:k=>i({...n,id:k.target.value}),className:re,placeholder:"kk-cc",disabled:u}),n.id&&!Ve.test(n.id)&&e.jsx("div",{className:Ke,children:"小写字母开头,只含 a-z 0-9 -,长度 2-32"}),n.id&&x.has(n.id)&&e.jsx("div",{className:Ke,children:"该 id 已被占用(全局唯一)"})]}),e.jsxs("div",{children:[e.jsx("span",{className:X,children:"角色"}),e.jsxs("label",{className:"mr-4 inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"role",checked:n.role==="dev",className:ae,onChange:()=>i({...n,role:"dev",pairWith:""}),disabled:u}),e.jsx("span",{className:"text-[13px] text-og-800",children:"Dev"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",title:O?"":"请先创建一个 Dev Agent",children:[e.jsx("input",{type:"radio",name:"role",checked:n.role==="qa",className:ae,onChange:()=>i({...n,role:"qa"}),disabled:u||!O}),e.jsx("span",{className:`text-[13px] ${O?"text-og-800":"text-og-400"}`,children:"QA"})]})]}),n.role==="qa"&&e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"pair-with",children:"配对 Dev Agent"}),e.jsxs("select",{id:"pair-with",value:n.pairWith,onChange:k=>i({...n,pairWith:k.target.value}),className:re,disabled:u,children:[e.jsx("option",{value:"",children:"请选择"}),D.map(k=>e.jsxs("option",{value:k.id,children:[k.id," (dev, ",k.mode,")"]},k.id))]})]}),e.jsxs("div",{children:[e.jsx("span",{className:X,children:"运行模式"}),e.jsxs("label",{className:"mr-4 inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"mode",checked:n.mode==="local",className:ae,onChange:()=>i({...n,mode:"local",hostname:"",user:""}),disabled:u}),e.jsx("span",{className:"text-[13px] text-og-800",children:"本机"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"mode",checked:n.mode==="remote",className:ae,onChange:()=>i({...n,mode:"remote"}),disabled:u}),e.jsx("span",{className:"text-[13px] text-og-800",children:"远程 (SSH)"})]})]}),n.mode==="remote"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"hostname",children:"Hostname"}),e.jsx("input",{id:"hostname",type:"text",value:n.hostname,onChange:k=>i({...n,hostname:k.target.value}),className:re,placeholder:"macmini-2026",disabled:u}),e.jsx("div",{className:Ae,children:"端口/私钥/跳板机请配 ~/.ssh/config"})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"user",children:"User(可选)"}),e.jsx("input",{id:"user",type:"text",value:n.user,onChange:k=>i({...n,user:k.target.value}),className:re,placeholder:"留空则读 ~/.ssh/config 的 User",disabled:u})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-1.5 flex items-center justify-between",children:[e.jsx("span",{className:"text-[12px] font-medium text-og-700",children:"运行时"}),e.jsx("button",{type:"button",onClick:I,className:"text-[12px] text-accent transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",disabled:u||f||n.mode==="remote"&&!n.hostname,children:"↻ 重新探测"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"runtime",checked:n.runtime==="claude-code",className:ae,onChange:()=>i({...n,runtime:"claude-code"}),disabled:u||(c?!c.runtimes["claude-code"].ok:!1)}),e.jsx("span",{className:"text-[13px] text-og-800",children:"Claude Code"}),e.jsx(V,{rt:"claude-code"})]}),e.jsxs("label",{className:"mt-1 flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"runtime",checked:n.runtime==="codex",className:ae,onChange:()=>i({...n,runtime:"codex"}),disabled:u||(c?!c.runtimes.codex.ok:!1)}),e.jsx("span",{className:"text-[13px] text-og-800",children:"Codex"}),e.jsx(V,{rt:"codex"})]}),e.jsx("div",{className:"mt-2",children:e.jsx(K,{})}),e.jsx("div",{children:e.jsx(se,{})})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"workdir",children:"Workdir(可选)"}),e.jsx("input",{id:"workdir",type:"text",value:n.workdir,onChange:k=>i({...n,workdir:k.target.value}),className:re,placeholder:"留空时自动 clone 到 ~/.baxian/repos/<owner>/<repo>",disabled:u})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"model",children:"Model(可选)"}),e.jsx("input",{id:"model",type:"text",value:n.model,onChange:k=>i({...n,model:k.target.value}),className:re,placeholder:n.runtime==="codex"?"例: o3 / gpt-4o(留空走 default)":"例: sonnet / opus / claude-sonnet-4-6(留空走 default)",disabled:u}),e.jsx("div",{className:Ae,children:"透传到 launch 命令的 --model 参数;留空跟随 CLI 默认。"})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"addDirs",children:"Additional Dirs(可选)"}),e.jsx("textarea",{id:"addDirs",value:n.addDirs,onChange:k=>i({...n,addDirs:k.target.value}),className:`${re} font-mono text-[12px]`,rows:3,placeholder:`每行一个绝对路径,例:
3
+ /Users/me/shared-libs
4
+ /Users/me/extra-repo`,disabled:u}),e.jsx("div",{className:Ae,children:"透传到 --add-dir。当前 YOLO 模式下不影响权限拦截,主要用于让 CLI 把额外目录纳入工作根。"})]}),e.jsx("div",{className:"rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-3 py-2.5",children:e.jsxs("label",{className:"flex cursor-pointer items-start gap-2",children:[e.jsx("input",{type:"checkbox",className:"mt-1 h-3.5 w-3.5 accent-[#1348dc]",checked:n.yolo,onChange:k=>i({...n,yolo:k.target.checked}),disabled:u}),e.jsxs("div",{className:"text-[13px] text-og-800",children:[e.jsx("div",{className:"font-medium",children:"YOLO 模式(推荐开启)"}),e.jsxs("div",{className:"mt-1 text-[12px] text-warn",children:["Agent 自主执行所有命令、文件改动,无需逐条确认。开启后体验更顺滑, 但",e.jsx("strong",{className:"font-semibold",children:"请确认在受控环境(容器、隔离 worktree)中运行"}),"。"]})]})]})}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-hairline pt-4",children:[e.jsx("button",{type:"button",onClick:E,disabled:u,className:"btn-secondary",children:"取消"}),e.jsx("button",{type:"submit",disabled:!Y,className:"btn-primary",children:u?"添加中…":"添加 Agent"})]})]})})}const Ze=200,Xe=16e3,me="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",pe="mb-1.5 block text-[12px] font-medium text-og-700",et="mt-1 text-right text-[12px] text-og-400";function Fe(t){const s=t.mode==="edit",r=ye(),{show:o}=fe(),n=s?t.task.projectId:t.projectId,i=s?t.task.title:"",d=s?t.task.description:"",p=s?t.task.preferredAgentId:"",[x,b]=a.useState([]),[c,h]=a.useState([]),[f,m]=a.useState(n??""),[u,N]=a.useState(p),[l,C]=a.useState(i),[T,S]=a.useState(d),[R,j]=a.useState(!1),[g,E]=a.useState(null),I=a.useRef(0);a.useEffect(()=>{if(!t.open)return;I.current+=1;const v=I.current;b([]),h([]),m(n??""),N(p),C(i),S(d),E(null),j(!1),Promise.all([$.projects.list(),$.agents.list()]).then(([y,q])=>{v===I.current&&(b(y),h(q))}).catch(y=>{v===I.current&&E(y instanceof Error?y.message:String(y))})},[t.open,n,i,d,p]);const D=a.useMemo(()=>x.find(v=>v.id===f)??null,[x,f]),O=a.useMemo(()=>D?D.agent.flat().filter(v=>v.role==="dev"):[],[D]),F=a.useMemo(()=>new Set(c.map(v=>v.id)),[c]),P=a.useMemo(()=>O.filter(v=>F.has(v.id)),[O,F]),z=a.useMemo(()=>O.filter(v=>!F.has(v.id)),[O,F]);a.useEffect(()=>{if(!s){if(P.length===0){u!==""&&N("");return}P.find(v=>v.id===u)||N(P[0].id)}},[P,u,s]);const B=!s||P.find(v=>v.id===u),Q=s&&!B&&!!u,J=Q&&z.some(v=>v.id===u),Y=J?`当前 dev "${u}" 在 baxian.json 中存在但 runtime 未加载,可能是手动编辑过配置文件;重启 server 可拉起`:Q?`当前 dev "${u}" 不在 runtime(可能已从 project 配置移除);保存可能失败,请确认或选择新 dev`:!f||P.length>0?null:z.length>0?"baxian.json 里有 dev agent 但 runtime 未加载(可能是手动编辑过配置);重启 server 后生效":"请先为项目添加 dev agent",H=l.trim(),V=T.trim(),K=P.length>0||Q,G=!!f&&K&&!!u&&H.length>0&&V.length>0&&!R,k=()=>{R||t.onClose()},M=async v=>{var y,q;if(v.preventDefault(),!!G){j(!0),E(null);try{if(t.mode==="edit"){const U=await $.tasks.update(t.task.id,{title:H,description:V,preferredAgentId:u});o({kind:"success",title:"任务已更新"}),(y=t.onUpdated)==null||y.call(t,U),t.onClose()}else{const U=await $.tasks.create({projectId:f,title:H,description:V,preferredAgentId:u});o({kind:"success",title:"任务已创建"}),(q=t.onCreated)==null||q.call(t,U),t.onClose(),r(`/task/${U.id}`)}}catch(U){E(U instanceof Error?U.message:String(U))}finally{j(!1)}}},w=s?"编辑 Task":"新建 Task",L=s?R?"保存中…":"保存":R?"创建中…":"创建",A=!s&&!n;return e.jsx(ke,{open:t.open,onClose:k,title:w,size:"md",children:e.jsxs("form",{onSubmit:M,className:"space-y-4",children:[g&&e.jsx("div",{className:"rounded-md border border-[#fecaca] bg-[#fef2f2] px-3 py-2 text-[13px] text-danger",children:g}),A&&e.jsxs("div",{children:[e.jsx("label",{className:pe,htmlFor:"task-project",children:"Project"}),e.jsxs("select",{id:"task-project",value:f,onChange:v=>m(v.target.value),className:me,disabled:R,required:!0,children:[e.jsx("option",{value:"",disabled:!0,children:"选择项目"}),x.map(v=>e.jsx("option",{value:v.id,children:v.id},v.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:pe,htmlFor:"task-dev",children:"Dev Agent"}),e.jsxs("select",{id:"task-dev",value:u,onChange:v=>N(v.target.value),className:me,disabled:R||P.length===0&&!Q||P.length===1&&P[0].id===u&&!Q,required:!0,children:[P.length===0&&!Q&&e.jsx("option",{value:"",disabled:!0,children:"无可用 dev"}),Q&&e.jsxs("option",{value:u,children:[u," ",J?"(待重启)":"(不在 runtime)"]}),P.map(v=>e.jsx("option",{value:v.id,children:v.id},v.id))]}),Y&&e.jsx("div",{className:"mt-1 text-[12px] text-warn",children:Y})]}),e.jsxs("div",{children:[e.jsx("label",{className:pe,htmlFor:"task-title",children:"Title"}),e.jsx("input",{id:"task-title",type:"text",value:l,onChange:v=>C(v.target.value),maxLength:Ze,className:me,placeholder:"一句话描述要做什么",disabled:R,required:!0}),e.jsxs("div",{className:et,children:[l.length," / ",Ze]})]}),e.jsxs("div",{children:[e.jsx("label",{className:pe,htmlFor:"task-description",children:"Description"}),e.jsx("textarea",{id:"task-description",value:T,onChange:v=>S(v.target.value),maxLength:Xe,rows:8,className:`${me} font-mono text-[12px]`,placeholder:"详细描述任务,支持 markdown",disabled:R,required:!0}),e.jsxs("div",{className:et,children:[T.length," / ",Xe]})]}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-hairline pt-4",children:[e.jsx("button",{type:"button",onClick:k,disabled:R,className:"btn-secondary",children:"取消"}),e.jsx("button",{type:"submit",disabled:!G,className:"btn-primary",children:L})]})]})})}function cs(t){return Array.from(new TextEncoder().encode(t)).map(s=>s.toString(16).padStart(2,"0")).join("")}function ls(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/realtime`}const ds=(t,s)=>s&&s.length>0?new WebSocket(t,s):new WebSocket(t);class us{constructor(s={}){_(this,"wsUrl");_(this,"wsFactory");_(this,"tokenProvider");_(this,"ws",null);_(this,"topics",new Map);_(this,"cache",new Map);_(this,"outbox",[]);_(this,"reconnectScheduler");_(this,"explicitlyClosed",!1);this.wsUrl=s.wsUrl??ls(),this.wsFactory=s.wsFactory??ds,this.tokenProvider=s.tokenProvider??_e,this.reconnectScheduler=new it({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.topics.size>0})}subscribe(s,r,o){let n=this.topics.get(s);const i=!n;return n||(n={data:new Set,error:new Set},this.topics.set(s,n)),n.data.add(r),o&&n.error.add(o),i?(this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",topic:s})):this.cache.has(s)&&queueMicrotask(()=>{var d;(d=this.topics.get(s))!=null&&d.data.has(r)&&this.cache.has(s)&&r(this.cache.get(s))}),()=>this.unsubscribe(s,r,o)}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.topics.clear(),this.cache.clear(),this.outbox=[]}unsubscribe(s,r,o){const n=this.topics.get(s);n&&(n.data.delete(r),o&&n.error.delete(o),n.data.size===0&&n.error.size===0&&(this.topics.delete(s),this.cache.delete(s),this.wsSendOrQueue({op:"unsubscribe",topic:s}),this.topics.size===0&&this.teardownSocket()))}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const s=this.tokenProvider(),r=s?[`baxian.token.${cs(s)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,r)}catch(i){console.warn("[events-client] WebSocket constructor threw:",i),this.broadcastConnectionError({code:"connection_failed",message:i instanceof Error?i.message:"WebSocket constructor threw"}),this.scheduleReconnect();return}this.ws=o;let n=!1;o.onopen=()=>{if(o!==this.ws)return;n=!0,this.reconnectScheduler.reset();for(const d of this.topics.keys())try{o.send(JSON.stringify({op:"subscribe",topic:d}))}catch(p){console.warn("[events-client] resubscribe send failed:",p)}const i=this.outbox;this.outbox=[];for(const d of i)if(!(d.op==="subscribe"||d.op==="unsubscribe"))try{o.send(JSON.stringify(d))}catch(p){console.warn("[events-client] outbox flush failed:",p)}},o.onmessage=i=>{if(o!==this.ws)return;let d;try{const p=typeof i.data=="string"?i.data:String(i.data);d=JSON.parse(p)}catch{return}this.handleMessage(d)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&(n||this.broadcastConnectionError({code:"connection_failed",message:"WebSocket failed to connect (auth, network, or proxy issue)"}),this.topics.size!==0&&this.scheduleReconnect()))},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}broadcastConnectionError(s){for(const r of this.topics.values())for(const o of[...r.error])try{o(s)}catch(n){console.error("[events-client] error handler threw on connection error:",n)}}wsSendOrQueue(s){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(s));return}catch(r){console.warn("[events-client] send failed, will queue:",r)}this.outbox.push(s)}handleMessage(s){switch(s.type){case"data":{const r=this.topics.get(s.topic);if(this.cache.set(s.topic,s.data),!r)return;for(const o of[...r.data])try{o(s.data)}catch(n){console.error(`[events-client] handler threw on ${s.topic}:`,n)}break}case"error":{const r={code:s.code,message:s.message};if(s.topic){const o=this.topics.get(s.topic);if(o)for(const n of[...o.error])try{n(r)}catch(i){console.error(`[events-client] error handler threw on ${s.topic}:`,i)}}else console.warn("[events-client] connection-level error:",s.code,s.message);break}}}}let Te=null;function Me(){return Te||(Te=new us),Te}function lt(){const[t,s]=a.useState(null),[r,o]=a.useState(!1),[n,i]=a.useState(null);return a.useEffect(()=>Me().subscribe("agents",p=>{i(null),s(p),o(!0)},p=>i(p)),[]),{data:t,loaded:r,error:n}}function hs(t){const[s,r]=a.useState(null),[o,n]=a.useState(!1),[i,d]=a.useState(null);return a.useEffect(()=>(r(null),n(!1),d(null),Me().subscribe(`task:${t}`,x=>{d(null),r(x),n(!0)},x=>d(x))),[t]),{data:s,loaded:o,error:i}}function fs(t){const[s,r]=a.useState(null),[o,n]=a.useState(!1),[i,d]=a.useState(null);return a.useEffect(()=>{if(!t){r(null),n(!1),d(null);return}r(null),n(!1),d(null);let p=!1,x=!1,b=!1;const c=Me().subscribe(`project-tasks:${t}`,h=>{p||(x=!0,d(null),r(h),n(!0))},h=>{p||(d(h),!(x||b)&&(b=!0,$.tasks.list(t).then(f=>{p||x||(r(f),n(!0))},f=>{console.warn(`[useProjectTasks] REST fallback failed for ${t}:`,f)})))});return()=>{p=!0,c()}},[t]),{data:s,loaded:o,error:i}}let we=null,te=null,ve=null,le=0;const Pe=new Set;function dt(){Pe.forEach(t=>t())}async function xs(){const t=le;try{const s=await $.projects.list();if(t!==le)return;we=s,ve=null}catch(s){if(t!==le)return;ve=s instanceof Error?s.message:String(s)}finally{t===le&&(te=null,dt())}}function $e(){return te||(te=xs(),te)}function ms(){le+=1,we=null,te=null,ve=null,dt()}typeof window<"u"&&window.addEventListener(be,ms);async function ps(){const t=te!==null;await $e(),t&&await $e()}function ut(){const[,t]=a.useState(0);return a.useEffect(()=>{const s=()=>t(r=>r+1);return Pe.add(s),we===null&&!te&&$e(),()=>{Pe.delete(s)}},[]),{projects:we,error:ve,refresh:ps}}function bs(){const{projects:t,error:s,refresh:r}=ut(),o=t??[],n=t!==null,[i,d]=a.useState([]),[p,x]=a.useState(null),[b,c]=a.useState(!1),[h,f]=a.useState(!1),[m,u]=a.useState({kind:"closed"}),{data:N,loaded:l,error:C}=lt(),T=(C==null?void 0:C.message)??null,S=new Map((N??[]).map(g=>[g.id,g])),R=s??T??p,j=async()=>{try{const g=await $.tasks.list();d(g),x(null)}catch(g){x(g instanceof Error?g.message:String(g))}};return a.useEffect(()=>{j()},[]),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-6 flex flex-wrap items-end justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"font-display text-2xl font-semibold tracking-tight text-og-1000",children:"Dashboard"}),e.jsx("p",{className:"mt-0.5 text-[13px] text-og-500",children:"Active agent workspaces across all configured repos."})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("button",{onClick:()=>c(!0),className:"btn-primary",children:"+ 新建项目"}),e.jsx("button",{onClick:()=>f(!0),disabled:o.length===0,"aria-describedby":o.length===0?"create-task-hint":void 0,className:"btn-secondary",children:"+ 新建 Task"}),o.length===0&&e.jsx("span",{id:"create-task-hint",className:"self-center text-[12px] text-og-500",children:"请先创建项目"})]})]}),R&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",R]}),n&&o.length===0&&!s&&e.jsx("div",{className:"rounded-lg border border-hairline bg-surface py-12 text-center text-[13px] text-og-500",children:'还没有项目。点击右上角"+ 新建项目"开始。'}),o.map(g=>e.jsxs("div",{className:"mb-10",children:[e.jsxs("div",{className:"mb-3 flex flex-wrap items-baseline gap-x-3 gap-y-1",children:[e.jsx("h2",{className:"font-display text-[17px] font-semibold tracking-tight text-og-1000",children:g.id}),e.jsx("span",{className:"min-w-0 break-words font-mono text-[12px] text-og-500",children:g.repo}),e.jsx(de,{to:`/project/${g.id}`,className:"ml-auto text-[13px] text-accent hover:text-accent-hover",children:"Details →"})]}),g.agent.flat().length===0?e.jsx("div",{className:"rounded-lg border border-hairline bg-surface py-6 text-center text-[13px] text-og-500",children:"还没有 Agent。进入 Details 添加。"}):e.jsx("div",{className:"grid grid-cols-1 gap-3 xl:grid-cols-2",children:g.agent.map((E,I)=>e.jsx(ot,{group:E,projectId:g.id,agentsById:S,agentsLoaded:l,agentsError:!!C,tasks:i.filter(D=>D.projectId===g.id),onDeleted:()=>{r(),j()}},E.map(D=>D.id).join(":")||I))})]},g.id)),e.jsx(is,{open:b,onClose:()=>c(!1),onCreated:g=>{c(!1),r(),u({kind:"asking",projectId:g})}}),e.jsx(ke,{open:m.kind==="asking",onClose:()=>u({kind:"closed"}),title:"项目已创建",size:"sm",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-[13px] text-og-700",children:"现在添加第一个 Agent,还是稍后再加?"}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:()=>u({kind:"closed"}),className:"btn-secondary",children:"稍后再加"}),e.jsx("button",{type:"button",onClick:()=>{m.kind==="asking"&&u({kind:"addingAgent",projectId:m.projectId})},className:"btn-primary",children:"继续添加 Agent"})]})]})}),m.kind==="addingAgent"&&e.jsx(ct,{open:!0,projectId:m.projectId,onClose:()=>u({kind:"closed"}),onCreated:()=>{r()}}),e.jsx(Fe,{open:h,onClose:()=>f(!1),onCreated:()=>{j()}})]})}function ht({tasks:t}){const s=ye();return t.length===0?e.jsx("div",{className:"rounded-lg border border-hairline bg-surface px-4 py-8 text-center text-[13px] text-og-400",children:"No tasks"}):e.jsx("div",{className:"overflow-hidden rounded-lg border border-hairline bg-surface",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-[13px]",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-hairline bg-og-50/40 text-left font-mono text-[11px] uppercase tracking-[0.05em] text-og-500",children:[e.jsx("th",{className:"px-4 py-2 font-medium",children:"ID"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Title"}),e.jsx("th",{className:"hidden px-4 py-2 font-medium sm:table-cell",children:"Agent"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Status"}),e.jsx("th",{className:"hidden px-4 py-2 font-medium sm:table-cell",children:"Round"})]})}),e.jsx("tbody",{children:t.map(r=>e.jsxs("tr",{className:"cursor-pointer border-t border-hairline transition-colors hover:bg-og-50/40",onClick:()=>s(`/task/${r.id}`),children:[e.jsx("td",{className:"whitespace-nowrap px-4 py-2.5 font-mono text-[12px]",children:e.jsx(de,{to:`/task/${r.id}`,className:"text-accent hover:text-accent-hover",onClick:o=>o.stopPropagation(),children:r.id})}),e.jsx("td",{className:"px-4 py-2.5 break-words text-og-1000",children:r.title}),e.jsx("td",{className:"hidden whitespace-nowrap px-4 py-2.5 font-mono text-[12px] sm:table-cell",children:r.agentId?e.jsx("span",{className:"text-og-700",children:r.agentId}):r.preferredAgentId?e.jsx("span",{className:"italic text-og-500",children:r.preferredAgentId}):e.jsx("span",{className:"text-og-400",children:"—"})}),e.jsxs("td",{className:"whitespace-nowrap px-4 py-2.5",children:[e.jsx("span",{className:"pill",children:r.status}),r.phase==="spec"&&e.jsx("span",{className:"ml-1 pill pill-review",children:"spec"})]}),e.jsx("td",{className:"hidden whitespace-nowrap px-4 py-2.5 text-[12px] text-og-500 sm:table-cell",children:r.phase==="spec"?r.specReviewRound??0:r.reviewRound})]},r.id))})]})})})}function gs(){const{id:t}=Oe(),[s,r]=a.useState(null),[o,n]=a.useState(null),[i,d]=a.useState(!1),[p,x]=a.useState(!1),b=a.useRef(0),{data:c,loaded:h,error:f}=lt(),{data:m,error:u}=fs(t),N=(f==null?void 0:f.message)??null,l=(u==null?void 0:u.message)??null,C=m??[],T=new Map((c??[]).map(j=>[j.id,j])),S=o??N??l,R=a.useCallback(async j=>{const g=++b.current;try{const E=await $.projects.get(j);if(g!==b.current)return;r(E),n(null)}catch(E){if(g!==b.current)return;n(E instanceof Error?E.message:String(E))}},[]);return a.useEffect(()=>{t&&(r(null),n(null),R(t))},[t,R]),s?e.jsxs("div",{children:[S&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",S]}),e.jsxs("div",{className:"mb-3 flex flex-wrap items-baseline justify-between gap-2",children:[e.jsx("h2",{className:"font-display text-[12px] font-semibold uppercase tracking-[0.06em] text-og-500",children:"Agents"}),e.jsx("button",{onClick:()=>d(!0),className:"btn-ghost",children:"+ 添加 Agent"})]}),s.agent.flat().length===0?e.jsx("div",{className:"mb-8 rounded-lg border border-hairline bg-surface py-6 text-center text-[13px] text-og-500",children:"还没有 Agent,点击右上角添加。"}):e.jsx("div",{className:"mb-8 space-y-5",children:s.agent.map((j,g)=>e.jsx(ot,{group:j,projectId:s.id,agentsById:T,agentsLoaded:h,agentsError:!!f,tasks:C,onDeleted:()=>{R(s.id)},terminalMode:"embedded-full"},j.map(E=>E.id).join(":")||g))}),e.jsxs("div",{className:"mb-3 flex flex-wrap items-baseline justify-between gap-2 border-t border-hairline pt-6",children:[e.jsx("h2",{className:"font-display text-[12px] font-semibold uppercase tracking-[0.06em] text-og-500",children:"Tasks"}),e.jsx("button",{onClick:()=>x(!0),className:"btn-ghost",children:"+ 新建 Task"})]}),e.jsx(ht,{tasks:C}),e.jsx(ct,{open:i,projectId:s.id,onClose:()=>d(!1),onCreated:()=>{R(s.id)}}),e.jsx(Fe,{open:p,projectId:s.id,onClose:()=>x(!1)})]}):o?e.jsxs("div",{className:"text-[13px] text-danger",children:["Error: ",o]}):e.jsx("div",{className:"text-[13px] text-og-500",children:"Loading…"})}function js(){const{agentId:t}=Oe();return t?e.jsxs("div",{className:"flex min-h-0 flex-1 flex-col overflow-hidden rounded-lg border border-hairline bg-surface",children:[e.jsxs("div",{className:"flex h-8 flex-none select-none items-center gap-3 border-b border-hairline bg-page px-3 font-mono text-[11px] text-og-500",children:[e.jsx("span",{"aria-hidden":!0,className:"block h-1.5 w-1.5 rounded-full bg-success"}),e.jsx("span",{className:"text-og-700",children:t})]}),e.jsx("div",{className:"min-h-0 flex-1",children:e.jsx(Ie,{agentId:t,mode:"full",interactive:!0})})]}):e.jsx("div",{className:"text-[13px] text-danger",children:"No agent specified"})}function ws(){const[t,s]=a.useState([]),[r,o]=a.useState(null);return a.useEffect(()=>{let n=!1;return(async()=>{try{const i=await $.tasks.list();n||s(i)}catch(i){n||o(i instanceof Error?i.message:String(i))}})(),()=>{n=!0}},[]),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-6",children:[e.jsx("h1",{className:"font-display text-2xl font-semibold tracking-tight text-og-1000",children:"Tasks"}),e.jsx("p",{className:"mt-0.5 text-[13px] text-og-500",children:"Every task across all projects."})]}),r&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",r]}),e.jsx(ht,{tasks:t})]})}const ft=new Set(["merged","failed","max_rounds","cancelled"]),tt=ft,vs={pending:"pill",in_progress:"pill pill-live",review:"pill pill-review",fixing:"pill pill-warn",approved:"pill pill-live",merged:"pill pill-live",failed:"pill pill-warn",max_rounds:"pill pill-warn",cancelled:"pill"};function ys(){const{id:t}=Oe(),s=ye(),{show:r}=fe(),[o,n]=a.useState(!1),[i,d]=a.useState(!1),[p,x]=a.useState(!1),[b,c]=a.useState(!1),[h,f]=a.useState(null),{data:m,loaded:u,error:N}=hs(t??""),l=h??m,C=(N==null?void 0:N.message)??null;a.useEffect(()=>{f(null)},[t]),a.useEffect(()=>{h&&m&&m.updatedAt>=h.updatedAt&&f(null)},[h,m]);const T=P=>{f(P)};if(!t)return e.jsx("div",{className:"text-[13px] text-danger",children:"Task ID required"});if(C&&!l)return e.jsxs("div",{className:"text-[13px] text-danger",children:["Error: ",C]});if(u&&!l)return e.jsxs("div",{className:"text-[13px] text-danger",children:["Task not found: ",t]});if(!l)return e.jsx("div",{className:"text-[13px] text-og-500",children:"Loading…"});const S=l.status==="pending",R=l.status==="pending"||l.status==="in_progress",j=tt.has(l.status)&&!!l.preferredAgentId,g=!!l.prNumber,E=l.preferredAgentId==="",I=l.status==="approved"&&l.prNumber!==void 0,D=async()=>{if(confirm(`确定取消 task ${l.id}?`)){d(!0);try{const P=await $.tasks.update(l.id,{status:"cancelled"});T(P),r({kind:"success",title:"任务已取消"})}catch(P){r({kind:"error",title:"取消失败",body:P instanceof Error?P.message:String(P)})}finally{d(!1)}}},O=async()=>{const z=ft.has(l.status)?`task ${l.id} 已是 ${l.status} 状态。手动请 QA 重审会再跑一轮 review,但状态机不会把 QA 结果带回主流程。继续?`:`请 QA 重审 task ${l.id}?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`;if(confirm(z)){c(!0);try{const B=await $.tasks.review(l.id);T(B),r({kind:"success",title:`已派 QA 重审 (round ${B.reviewRound})`})}catch(B){r({kind:"error",title:"Review 派发失败",body:B instanceof Error?B.message:String(B)})}finally{c(!1)}}},F=async()=>{const P=l.status==="merged"?`task ${l.id} 已 merged。Retry 会用同样的标题/描述新建一个 task 从头跑,确定继续?`:`Retry task ${l.id}?这会新建一个 task 从头开始,旧 task 保留为历史。`;if(confirm(P)){x(!0);try{const z=await $.tasks.retry(l.id);r({kind:"success",title:`已新建 task ${z.id}`}),s(`/task/${z.id}`)}catch(z){r({kind:"error",title:"Retry 失败",body:z instanceof Error?z.message:String(z)})}finally{x(!1)}}};return e.jsxs("div",{className:"mx-auto max-w-4xl",children:[C&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",C]}),E&&e.jsx("div",{className:"mb-4 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-3 py-2.5 text-[12px] text-warn",children:l.status==="pending"?e.jsxs(e.Fragment,{children:["This task has no preferred dev (legacy). Click ",e.jsx("b",{className:"font-semibold",children:"Edit"})," to assign one."]}):e.jsxs(e.Fragment,{children:["This is a legacy task with no preferred dev (read-only in status ",e.jsx("b",{className:"font-semibold",children:l.status}),")."]})}),e.jsxs("div",{className:"mb-2 flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:"font-mono text-[13px] text-og-500",children:l.id}),e.jsx("span",{className:vs[l.status],children:l.status}),l.phase==="spec"&&e.jsx("span",{className:"pill pill-review",children:"spec phase"}),e.jsxs("span",{className:"text-[12px] text-og-500",children:["created ",l.createdAt]}),e.jsxs("span",{className:"text-[12px] text-og-500",children:["updated ",l.updatedAt]})]}),e.jsx("h1",{className:"mb-5 break-words font-display text-2xl font-semibold tracking-tight text-og-1000",children:l.title}),I&&e.jsxs("div",{className:"mb-5 rounded-lg border border-[#bbf7d0] bg-[#f0fdf4] p-4 text-[13px] text-success",children:[e.jsx("div",{className:"font-semibold",children:"QA approved · awaiting PR merge"}),e.jsx("div",{className:"mt-1 text-og-700",children:"Dev keeps the task reserved while it checks whether all human or agent feedback has been handled."}),l.prUrl&&e.jsxs("a",{href:l.prUrl,target:"_blank",rel:"noopener noreferrer",className:"btn-secondary mt-3 !border-[#bbf7d0] !text-success hover:!bg-[#dcfce7] hover:!border-success",children:["Open PR #",l.prNumber]})]}),e.jsx("pre",{className:"card mb-6 whitespace-pre-wrap p-4 text-[13px] text-og-800",children:l.description}),e.jsxs("div",{className:"card mb-6 grid grid-cols-1 gap-x-6 gap-y-2 p-4 text-[13px] md:grid-cols-2",children:[e.jsxs("div",{className:"text-og-500",children:["Project: ",e.jsx("span",{className:"font-mono text-og-800",children:l.projectId})]}),e.jsxs("div",{className:"text-og-500",children:["Dev: ",e.jsx("span",{className:"font-mono text-og-800",children:l.agentId||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["Preferred: ",e.jsx("span",{className:"font-mono text-og-800",children:l.preferredAgentId||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["QA: ",e.jsx("span",{className:"font-mono text-og-800",children:l.qaAgentId||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["PR:"," ",l.prNumber?l.prUrl?e.jsxs("a",{href:l.prUrl,target:"_blank",rel:"noopener noreferrer",className:"text-accent hover:text-accent-hover",children:["#",l.prNumber]}):e.jsxs("span",{className:"font-mono text-og-800",children:["#",l.prNumber]}):e.jsx("span",{className:"text-og-400",children:"—"})]}),e.jsxs("div",{className:"text-og-500",children:["Branch: ",e.jsx("span",{className:"font-mono text-og-800",children:l.branch||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["Round: ",e.jsx("span",{className:"font-mono text-og-800",children:l.reviewRound}),l.specReviewRound!==void 0&&l.specReviewRound>0&&e.jsxs("span",{className:"ml-2 text-[12px] text-accent",children:["spec: ",l.specReviewRound]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",disabled:!S,onClick:()=>n(!0),className:"btn-secondary",children:"Edit"}),e.jsx("button",{type:"button",disabled:!R||i,onClick:D,className:"btn-secondary !border-[#fecaca] !text-danger hover:!bg-[#fef2f2] hover:!border-danger",children:i?"Cancelling…":"Cancel"}),e.jsx("button",{type:"button",disabled:!j||p,onClick:F,title:tt.has(l.status)?E?"Legacy task has no preferred dev to retry against":"新建一个 task 从头跑,丢弃当前 worktree/branch":`Cannot retry in status ${l.status}`,className:"btn-secondary",children:p?"Retrying…":"Retry"}),e.jsx("button",{type:"button",disabled:!g||b,onClick:O,title:l.prNumber?"让 QA agent 立即开始新一轮 review(reviewRound +1)":"该 task 还没有 PR,无法派 review",className:"btn-secondary !border-accent-soft !text-accent hover:!bg-accent-soft hover:!border-accent",children:b?"Dispatching…":"Request QA review"})]}),e.jsx(Fe,{mode:"edit",open:o,onClose:()=>n(!1),task:l,onUpdated:T})]})}function Ns(){const[t,s]=a.useState(!1);return e.jsx("button",{type:"button",onClick:()=>s(r=>!r),"aria-label":t?"切换为 logo 图片":"切换为文字 baxian",className:"flex h-7 min-w-[88px] shrink-0 items-center justify-start font-display text-[15px] font-semibold tracking-tight text-og-1000",children:t?e.jsx("span",{children:"baxian"}):e.jsx("img",{src:"/baxian-logo.png",alt:"baxian",width:24,height:24,className:"block h-6 w-6"})})}function Ss(t){const s=t.match(/^\/project\/([^/?#]+)/);if(!s)return null;try{return decodeURIComponent(s[1])}catch{return null}}function ks(){const{projects:t,error:s}=ut(),r=ye(),{pathname:o}=vt(),[n,i]=a.useState(!1),d=a.useRef(null),p=Ss(o),x=p&&t?t.find(c=>c.id===p)??null:null;a.useEffect(()=>{if(!n)return;const c=f=>{d.current&&!d.current.contains(f.target)&&i(!1)},h=f=>{f.key==="Escape"&&i(!1)};return document.addEventListener("mousedown",c),document.addEventListener("keydown",h),()=>{document.removeEventListener("mousedown",c),document.removeEventListener("keydown",h)}},[n]);const b=c=>{i(!1),r(`/project/${encodeURIComponent(c)}`)};return e.jsxs("div",{ref:d,className:"relative flex min-w-0 flex-1 items-center",children:[e.jsxs("button",{type:"button",onClick:()=>i(c=>!c),"aria-expanded":n,"aria-label":x?`当前 Project:${x.id}`:"Select Project",className:"flex h-7 min-w-0 max-w-full items-center gap-2 rounded-md border border-og-100 bg-surface px-2.5 text-[13px] text-og-800 transition-colors hover:border-accent hover:text-accent",children:[x?e.jsx(st,{project:x}):e.jsx("span",{className:"truncate text-og-400",children:"Select Project"}),e.jsx(Es,{})]}),n&&e.jsxs("div",{"data-testid":"project-switcher-popover",className:"absolute left-0 top-full z-20 mt-1 min-w-full max-w-[320px] overflow-hidden rounded-md border border-hairline bg-surface shadow-modal",children:[s&&e.jsx("div",{className:"px-3 py-2 text-[12px] text-danger",children:s}),!s&&t&&t.length===0&&e.jsx("div",{className:"px-3 py-2 text-[13px] text-og-400",children:"还没有项目"}),!s&&!t&&e.jsx("div",{className:"px-3 py-2 text-[13px] text-og-400",children:"加载中…"}),t==null?void 0:t.map(c=>{const h=(x==null?void 0:x.id)===c.id;return e.jsx("button",{type:"button","aria-current":h?"page":void 0,onClick:()=>b(c.id),className:["flex w-full items-center gap-2 border-l-2 px-3 py-2 text-left text-[13px] transition-colors",h?"border-accent bg-accent-soft text-accent":"border-transparent hover:bg-og-50/60"].join(" "),children:e.jsx(st,{project:c})},c.id)})]})]})}function st({project:t}){return e.jsxs("span",{className:"flex min-w-0 flex-1 items-baseline gap-2",children:[e.jsx("span",{className:"truncate font-medium text-og-1000",title:t.id,children:t.id}),e.jsx("span",{className:"hidden truncate font-mono text-[12px] text-og-500 sm:inline",title:t.repo,children:t.repo})]})}function Es(){return e.jsx("svg",{"aria-hidden":!0,viewBox:"0 0 24 24",width:"12",height:"12",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"shrink-0",children:e.jsx("path",{d:"m6 9 6 6 6-6"})})}function Rs(){const{phase:t,count:s,error:r,triggerRestart:o}=Se();return t==="idle"?null:t==="failed"?e.jsxs("div",{className:"flex items-center justify-between border-b border-[#fecaca] bg-[#fef2f2] px-4 py-2",children:[e.jsxs("div",{className:"text-[13px] text-danger",children:["❌ 重启失败:",r]}),e.jsx("button",{onClick:()=>{o()},className:"btn-ghost !text-danger hover:!bg-[#fef2f2]",children:"重试"})]}):t==="restarting"?e.jsx("div",{className:"border-b border-accent-soft bg-accent-soft/40 px-4 py-2 text-[13px] text-accent",children:"🔄 重启中…"}):e.jsxs("div",{className:"flex items-center justify-between border-b border-[#fde68a] bg-[#fef3c7]/60 px-4 py-2",children:[e.jsxs("div",{className:"text-[13px] text-warn",children:["⚠️ 有 ",s," 项配置变更待重启 baxian server 才生效"]}),e.jsx("button",{onClick:()=>{o()},className:"btn-secondary !border-warn !text-warn hover:!bg-[#fef3c7] hover:!border-warn hover:!text-warn",children:"现在重启"})]})}const nt=({isActive:t})=>["rounded-md px-2 py-1 text-[13px] transition-colors sm:px-2.5",t?"bg-og-50 text-og-1000":"text-og-500 hover:bg-og-50 hover:text-og-800"].join(" ");function Cs(){return e.jsx(yt,{children:e.jsxs("div",{className:"flex h-screen flex-col bg-page",children:[e.jsxs("nav",{className:"flex h-12 flex-none items-center justify-between gap-2 border-b border-hairline bg-surface px-3 sm:gap-4 sm:px-6",children:[e.jsxs("div",{className:"flex min-w-0 flex-1 items-center gap-2 sm:gap-3",children:[e.jsx(Ns,{}),e.jsx(ks,{})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-0.5 sm:gap-1",children:[e.jsx(Be,{to:"/",end:!0,className:nt,children:"Dashboard"}),e.jsx(Be,{to:"/tasks",className:nt,children:"Tasks"})]})]}),e.jsx(Rs,{}),e.jsx("main",{className:"flex min-h-0 flex-1 flex-col overflow-y-auto p-6",children:e.jsxs(Nt,{children:[e.jsx(ce,{path:"/",element:e.jsx(bs,{})}),e.jsx(ce,{path:"/project/:id",element:e.jsx(gs,{})}),e.jsx(ce,{path:"/terminal/:agentId",element:e.jsx(js,{})}),e.jsx(ce,{path:"/tasks",element:e.jsx(ws,{})}),e.jsx(ce,{path:"/task/:id",element:e.jsx(ys,{})})]})})]})})}function As({children:t}){const[s,r]=a.useState({kind:"probing"}),o=a.useRef(s);a.useEffect(()=>{o.current=s},[s]);const n=a.useCallback(async()=>{r({kind:"probing"});try{await $.config.get(),r({kind:"authorized"})}catch(i){if(i instanceof ge&&i.status===401){r({kind:"unauthorized"});return}const d=i instanceof Error?i.message:"无法连接服务器";r({kind:"error",message:d})}},[]);return a.useEffect(()=>{n()},[n]),a.useEffect(()=>{const i=()=>{o.current.kind!=="probing"&&r({kind:"unauthorized",message:"登录已失效,请重新输入令牌"})};return window.addEventListener(be,i),()=>window.removeEventListener(be,i)},[]),s.kind==="authorized"?e.jsx(e.Fragment,{children:t}):s.kind==="error"?e.jsxs(De,{title:"无法连接服务器",children:[e.jsx("p",{className:"text-[13px] text-og-600",children:s.message}),e.jsx("button",{type:"button",onClick:()=>{n()},className:"btn-primary mt-4 w-full",children:"重试"})]}):s.kind==="probing"?e.jsx(De,{title:"加载中",children:e.jsx("p",{className:"text-[13px] text-og-500",children:"正在检查登录状态…"})}):e.jsx(Ts,{message:s.message,onSubmit:async i=>{St(i);try{await $.config.get(),r({kind:"authorized"})}catch(d){if(kt(),d instanceof ge&&d.status===401){r({kind:"unauthorized",message:"令牌无效,请重试"});return}const p=d instanceof Error?d.message:"登录失败";r({kind:"error",message:p})}}})}function De({title:t,children:s}){return e.jsx("div",{className:"flex min-h-screen items-center justify-center bg-page px-4",children:e.jsxs("div",{className:"w-full max-w-sm rounded-lg border border-hairline bg-surface px-6 py-6",children:[e.jsx("h1",{className:"mb-3 font-display text-[16px] font-semibold tracking-tight text-og-1000",children:t}),s]})})}function Ts({message:t,onSubmit:s}){const[r,o]=a.useState(""),[n,i]=a.useState(!1),[d,p]=a.useState(void 0),x=async c=>{c.preventDefault();const h=r.trim();if(!h){p("请输入访问令牌");return}p(void 0),i(!0);try{await s(h)}finally{i(!1)}},b=d??t;return e.jsxs(De,{title:"登录 baxian",children:[e.jsx("p",{className:"mb-4 text-[13px] text-og-600",children:"服务器开启了访问鉴权,请输入访问令牌继续。"}),e.jsxs("form",{onSubmit:c=>{x(c)},children:[e.jsx("label",{className:"mb-1.5 block text-[12px] font-medium text-og-700",htmlFor:"baxian-token",children:"访问令牌"}),e.jsx("input",{id:"baxian-token",type:"password",autoComplete:"current-password",autoFocus:!0,value:r,onChange:c=>o(c.target.value),className:"w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 font-mono text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",placeholder:"请输入服务器配置的 token",disabled:n}),b&&e.jsx("p",{role:"alert",className:"mt-2 text-[12px] text-danger",children:b}),e.jsx("button",{type:"submit",disabled:n,className:"btn-primary mt-4 w-full",children:n?"登录中…":"登录"})]})]})}gt.createRoot(document.getElementById("root")).render(e.jsx(a.StrictMode,{children:e.jsx(Lt,{children:e.jsx(It,{children:e.jsx(As,{children:e.jsx(Cs,{})})})})}));
@@ -0,0 +1 @@
1
+ @font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-regular.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-italic.woff2) format("woff2");font-weight:400;font-style:italic;font-display:swap}@font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-bold.woff2) format("woff2");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-bolditalic.woff2) format("woff2");font-weight:700;font-style:italic;font-display:swap}@font-face{font-family:Lilex;src:url(/fonts/lilex-variable.woff2) format("woff2-variations");font-weight:200 700;font-style:normal;font-display:swap}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:iA Writer Quattro S,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}body{--tw-bg-opacity: 1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1));font-family:iA Writer Quattro S,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1));font-size:14px;line-height:1.55;-webkit-font-smoothing:antialiased;text-rendering:geometricprecision}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.btn-primary{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;border-radius:6px;--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1));padding:.375rem .75rem;font-size:13px;font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.btn-primary:hover{--tw-bg-opacity: 1;background-color:rgb(15 59 184 / var(--tw-bg-opacity, 1))}.btn-primary:disabled{cursor:not-allowed;opacity:.5}.btn-secondary{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;border-radius:6px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(206 209 214 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));padding:.375rem .75rem;font-size:13px;font-weight:500;--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.btn-secondary:hover{--tw-border-opacity: 1;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(19 72 220 / var(--tw-text-opacity, 1))}.btn-secondary:disabled{cursor:not-allowed;opacity:.5}.btn-ghost{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;border-radius:6px;background-color:transparent;padding:.375rem .75rem;font-size:13px;font-weight:500;--tw-text-opacity: 1;color:rgb(109 116 132 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.btn-ghost:hover{--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1))}.btn-ghost:disabled{cursor:not-allowed;opacity:.5}.pill{display:inline-flex;align-items:center;gap:.375rem;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1));padding:.125rem .5rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:11px;line-height:1.4;--tw-text-opacity: 1;color:rgb(83 89 100 / var(--tw-text-opacity, 1))}.pill:before{content:"";display:inline-block;height:.375rem;width:.375rem;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(171 175 184 / var(--tw-bg-opacity, 1))}.pill-live{--tw-bg-opacity: 1;background-color:rgb(230 244 236 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.pill-live:before{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.pill-warn{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.pill-warn:before{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.pill-review{--tw-bg-opacity: 1;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(19 72 220 / var(--tw-text-opacity, 1))}.pill-review:before{--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1))}.card{border-radius:8px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(232 233 236 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.card:hover{--tw-border-opacity: 1;border-color:rgb(206 209 214 / var(--tw-border-opacity, 1))}.status-dot{display:inline-block;height:1.25rem;width:1.25rem;flex-shrink:0;border-radius:9999px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(206 209 214 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1))}.status-dot--healthy{background-color:#e6f4ec;border-color:#15803d}.status-dot--warn{background-color:#fef3c7;border-color:#b45309;animation:breathe 1.8s ease-in-out infinite}.status-dot--danger{background-color:#fef2f2;border-color:#b91c1c;animation:breathe 1.8s ease-in-out infinite}.status-dot--info{background-color:#eaf0ff;border-color:#1348dc;animation:breathe 1.8s ease-in-out infinite}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.left-0{left:0}.right-4{right:1rem}.top-4{top:1rem}.top-full{top:100%}.z-20{z-index:20}.z-50{z-index:50}.z-\[60\]{z-index:60}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-10{margin-bottom:2.5rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-4{margin-right:1rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-12{height:3rem}.h-3\.5{height:.875rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-80{height:20rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-28{max-height:7rem}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0px}.min-h-screen{min-height:100vh}.w-1\.5{width:.375rem}.w-3\.5{width:.875rem}.w-6{width:1.5rem}.w-80{width:20rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[88px\]{min-width:88px}.min-w-full{min-width:100%}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-\[320px\]{max-width:320px}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-none{flex:none}.shrink-0{flex-shrink:0}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-1{row-gap:.25rem}.gap-y-2{row-gap:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-hairline>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(232 233 236 / var(--tw-divide-opacity, 1))}.self-center{align-self:center}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:8px}.rounded-md{border-radius:6px}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l-2{border-left-width:2px}.border-t{border-top-width:1px}.\!border-\[\#bbf7d0\]{--tw-border-opacity: 1 !important;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))!important}.\!border-\[\#fecaca\]{--tw-border-opacity: 1 !important;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))!important}.\!border-accent-soft{--tw-border-opacity: 1 !important;border-color:rgb(234 240 255 / var(--tw-border-opacity, 1))!important}.\!border-warn{--tw-border-opacity: 1 !important;border-color:rgb(180 83 9 / var(--tw-border-opacity, 1))!important}.border-\[\#bbf7d0\]{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-\[\#fde68a\]{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-\[\#fecaca\]{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-accent{--tw-border-opacity: 1;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1))}.border-accent-soft{--tw-border-opacity: 1;border-color:rgb(234 240 255 / var(--tw-border-opacity, 1))}.border-hairline{--tw-border-opacity: 1;border-color:rgb(232 233 236 / var(--tw-border-opacity, 1))}.border-og-100{--tw-border-opacity: 1;border-color:rgb(206 209 214 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.bg-\[\#f0fdf4\]{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-\[\#fdfdfd\]{--tw-bg-opacity: 1;background-color:rgb(253 253 253 / var(--tw-bg-opacity, 1))}.bg-\[\#fef2f2\]{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-\[\#fef3c7\]{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-\[\#fef3c7\]\/60{background-color:#fef3c799}.bg-accent-soft{--tw-bg-opacity: 1;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1))}.bg-accent-soft\/40{background-color:#eaf0ff66}.bg-og-1000\/45{background-color:#0d0d0f73}.bg-og-50{--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1))}.bg-og-50\/40{background-color:#e3e4e766}.bg-page{--tw-bg-opacity: 1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1))}.bg-success{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.bg-surface{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-display{font-family:Lilex,iA Writer Quattro S,ui-sans-serif,system-ui,sans-serif}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tracking-\[0\.05em\]{letter-spacing:.05em}.tracking-\[0\.06em\]{letter-spacing:.06em}.tracking-tight{letter-spacing:-.025em}.\!text-accent{--tw-text-opacity: 1 !important;color:rgb(19 72 220 / var(--tw-text-opacity, 1))!important}.\!text-danger{--tw-text-opacity: 1 !important;color:rgb(185 28 28 / var(--tw-text-opacity, 1))!important}.\!text-success{--tw-text-opacity: 1 !important;color:rgb(21 128 61 / var(--tw-text-opacity, 1))!important}.\!text-warn{--tw-text-opacity: 1 !important;color:rgb(180 83 9 / var(--tw-text-opacity, 1))!important}.text-accent{--tw-text-opacity: 1;color:rgb(19 72 220 / var(--tw-text-opacity, 1))}.text-current{color:currentColor}.text-danger{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-og-1000{--tw-text-opacity: 1;color:rgb(13 13 15 / var(--tw-text-opacity, 1))}.text-og-400{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.text-og-500{--tw-text-opacity: 1;color:rgb(109 116 132 / var(--tw-text-opacity, 1))}.text-og-600{--tw-text-opacity: 1;color:rgb(98 105 118 / var(--tw-text-opacity, 1))}.text-og-700{--tw-text-opacity: 1;color:rgb(83 89 100 / var(--tw-text-opacity, 1))}.text-og-800{--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1))}.text-success{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-warn{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.accent-\[\#1348dc\]{accent-color:#1348dc}.opacity-50{opacity:.5}.opacity-80{opacity:.8}.shadow-modal{--tw-shadow: 0 12px 32px rgba(15, 23, 42, .12);--tw-shadow-colored: 0 12px 32px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-toast{--tw-shadow: 0 4px 12px rgba(15, 23, 42, .08);--tw-shadow-colored: 0 4px 12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}@keyframes breathe{0%,to{opacity:1}50%{opacity:.35}}.placeholder\:text-og-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.placeholder\:text-og-400::placeholder{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.hover\:\!border-accent:hover{--tw-border-opacity: 1 !important;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1))!important}.hover\:\!border-danger:hover{--tw-border-opacity: 1 !important;border-color:rgb(185 28 28 / var(--tw-border-opacity, 1))!important}.hover\:\!border-success:hover{--tw-border-opacity: 1 !important;border-color:rgb(21 128 61 / var(--tw-border-opacity, 1))!important}.hover\:\!border-warn:hover{--tw-border-opacity: 1 !important;border-color:rgb(180 83 9 / var(--tw-border-opacity, 1))!important}.hover\:border-accent:hover{--tw-border-opacity: 1;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1))}.hover\:\!bg-\[\#dcfce7\]:hover{--tw-bg-opacity: 1 !important;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))!important}.hover\:\!bg-\[\#fef2f2\]:hover{--tw-bg-opacity: 1 !important;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))!important}.hover\:\!bg-\[\#fef3c7\]:hover{--tw-bg-opacity: 1 !important;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))!important}.hover\:\!bg-\[\#fef3c7\]\/60:hover{background-color:#fef3c799!important}.hover\:\!bg-accent-soft:hover{--tw-bg-opacity: 1 !important;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1))!important}.hover\:bg-og-50:hover{--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1))}.hover\:bg-og-50\/40:hover{background-color:#e3e4e766}.hover\:bg-og-50\/60:hover{background-color:#e3e4e799}.hover\:\!text-danger:hover{--tw-text-opacity: 1 !important;color:rgb(185 28 28 / var(--tw-text-opacity, 1))!important}.hover\:\!text-warn:hover{--tw-text-opacity: 1 !important;color:rgb(180 83 9 / var(--tw-text-opacity, 1))!important}.hover\:text-accent:hover{--tw-text-opacity: 1;color:rgb(19 72 220 / var(--tw-text-opacity, 1))}.hover\:text-accent-hover:hover{--tw-text-opacity: 1;color:rgb(15 59 184 / var(--tw-text-opacity, 1))}.hover\:text-og-800:hover{--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1))}.hover\:opacity-100:hover{opacity:1}.focus\:border-accent:focus{--tw-border-opacity: 1;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-\[3px\]:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-accent-soft:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(234 240 255 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:640px){.sm\:inline{display:inline}.sm\:table-cell{display:table-cell}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:gap-1{gap:.25rem}.sm\:gap-3{gap:.75rem}.sm\:gap-4{gap:1rem}.sm\:px-2\.5{padding-left:.625rem;padding-right:.625rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media(min-width:768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(min-width:1280px){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
@@ -9,4 +9,4 @@ import{r as i}from"./react-BG4Iuztk.js";/**
9
9
  * @license MIT
10
10
  */var fe="popstate";function de(e){return typeof e=="object"&&e!=null&&"pathname"in e&&"search"in e&&"hash"in e&&"state"in e&&"key"in e}function Ue(e={}){function t(r,a){var c;let o=(c=a.state)==null?void 0:c.masked,{pathname:l,search:s,hash:u}=o||r.location;return Z("",{pathname:l,search:s,hash:u},a.state&&a.state.usr||null,a.state&&a.state.key||"default",o?{pathname:r.location.pathname,search:r.location.search,hash:r.location.hash}:void 0)}function n(r,a){return typeof a=="string"?a:O(a)}return He(t,n,null,e)}function E(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function L(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function We(){return Math.random().toString(36).substring(2,10)}function he(e,t){return{usr:e.state,key:e.key,idx:t,masked:e.unstable_mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function Z(e,t,n=null,r,a){return{pathname:typeof e=="string"?e:e.pathname,search:"",hash:"",...typeof t=="string"?N(t):t,state:n,key:t&&t.key||r||We(),unstable_mask:a}}function O({pathname:e="/",search:t="",hash:n=""}){return t&&t!=="?"&&(e+=t.charAt(0)==="?"?t:"?"+t),n&&n!=="#"&&(e+=n.charAt(0)==="#"?n:"#"+n),e}function N(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substring(n),e=e.substring(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substring(r),e=e.substring(0,r)),e&&(t.pathname=e)}return t}function He(e,t,n,r={}){let{window:a=document.defaultView,v5Compat:o=!1}=r,l=a.history,s="POP",u=null,c=d();c==null&&(c=0,l.replaceState({...l.state,idx:c},""));function d(){return(l.state||{idx:null}).idx}function f(){s="POP";let p=d(),h=p==null?null:p-c;c=p,u&&u({action:s,location:y.location,delta:h})}function m(p,h){s="PUSH";let R=de(p)?p:Z(y.location,p,h);c=d()+1;let w=he(R,c),C=y.createHref(R.unstable_mask||R);try{l.pushState(w,"",C)}catch(x){if(x instanceof DOMException&&x.name==="DataCloneError")throw x;a.location.assign(C)}o&&u&&u({action:s,location:y.location,delta:1})}function g(p,h){s="REPLACE";let R=de(p)?p:Z(y.location,p,h);c=d();let w=he(R,c),C=y.createHref(R.unstable_mask||R);l.replaceState(w,"",C),o&&u&&u({action:s,location:y.location,delta:0})}function v(p){return ze(p)}let y={get action(){return s},get location(){return e(a,l)},listen(p){if(u)throw new Error("A history only accepts one active listener");return a.addEventListener(fe,f),u=p,()=>{a.removeEventListener(fe,f),u=null}},createHref(p){return t(a,p)},createURL:v,encodeLocation(p){let h=v(p);return{pathname:h.pathname,search:h.search,hash:h.hash}},push:m,replace:g,go(p){return l.go(p)}};return y}function ze(e,t=!1){let n="http://localhost";typeof window<"u"&&(n=window.location.origin!=="null"?window.location.origin:window.location.href),E(n,"No window.location.(origin|href) available to create URL");let r=typeof e=="string"?e:O(e);return r=r.replace(/ $/,"%20"),!t&&r.startsWith("//")&&(r=n+r),new URL(r,n)}function ve(e,t,n="/"){return je(e,t,n,!1)}function je(e,t,n,r){let a=typeof t=="string"?N(t):t,o=$(a.pathname||"/",n);if(o==null)return null;let l=Re(e);Ve(l);let s=null;for(let u=0;s==null&&u<l.length;++u){let c=rt(o);s=et(l[u],c,r)}return s}function Re(e,t=[],n=[],r="",a=!1){let o=(l,s,u=a,c)=>{let d={relativePath:c===void 0?l.path||"":c,caseSensitive:l.caseSensitive===!0,childrenIndex:s,route:l};if(d.relativePath.startsWith("/")){if(!d.relativePath.startsWith(r)&&u)return;E(d.relativePath.startsWith(r),`Absolute route path "${d.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),d.relativePath=d.relativePath.slice(r.length)}let f=S([r,d.relativePath]),m=n.concat(d);l.children&&l.children.length>0&&(E(l.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${f}".`),Re(l.children,t,m,f,u)),!(l.path==null&&!l.index)&&t.push({path:f,score:Qe(f,l.index),routesMeta:m})};return e.forEach((l,s)=>{var u;if(l.path===""||!((u=l.path)!=null&&u.includes("?")))o(l,s);else for(let c of we(l.path))o(l,s,!0,c)}),t}function we(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,a=n.endsWith("?"),o=n.replace(/\?$/,"");if(r.length===0)return a?[o,""]:[o];let l=we(r.join("/")),s=[];return s.push(...l.map(u=>u===""?o:[o,u].join("/"))),a&&s.push(...l),s.map(u=>e.startsWith("/")&&u===""?"/":u)}function Ve(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:Ze(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}var Je=/^:[\w-]+$/,Ke=3,qe=2,Ye=1,Ge=10,Xe=-2,me=e=>e==="*";function Qe(e,t){let n=e.split("/"),r=n.length;return n.some(me)&&(r+=Xe),t&&(r+=qe),n.filter(a=>!me(a)).reduce((a,o)=>a+(Je.test(o)?Ke:o===""?Ye:Ge),r)}function Ze(e,t){return e.length===t.length&&e.slice(0,-1).every((r,a)=>r===t[a])?e[e.length-1]-t[t.length-1]:0}function et(e,t,n=!1){let{routesMeta:r}=e,a={},o="/",l=[];for(let s=0;s<r.length;++s){let u=r[s],c=s===r.length-1,d=o==="/"?t:t.slice(o.length)||"/",f=V({path:u.relativePath,caseSensitive:u.caseSensitive,end:c},d),m=u.route;if(!f&&c&&n&&!r[r.length-1].route.index&&(f=V({path:u.relativePath,caseSensitive:u.caseSensitive,end:!1},d)),!f)return null;Object.assign(a,f.params),l.push({params:a,pathname:S([o,f.pathname]),pathnameBase:lt(S([o,f.pathnameBase])),route:m}),f.pathnameBase!=="/"&&(o=S([o,f.pathnameBase]))}return l}function V(e,t){typeof e=="string"&&(e={path:e,caseSensitive:!1,end:!0});let[n,r]=tt(e.path,e.caseSensitive,e.end),a=t.match(n);if(!a)return null;let o=a[0],l=o.replace(/(.)\/+$/,"$1"),s=a.slice(1);return{params:r.reduce((c,{paramName:d,isOptional:f},m)=>{if(d==="*"){let v=s[m]||"";l=o.slice(0,o.length-v.length).replace(/(.)\/+$/,"$1")}const g=s[m];return f&&!g?c[d]=void 0:c[d]=(g||"").replace(/%2F/g,"/"),c},{}),pathname:o,pathnameBase:l,pattern:e}}function tt(e,t=!1,n=!0){L(e==="*"||!e.endsWith("*")||e.endsWith("/*"),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,"/*")}".`);let r=[],a="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(l,s,u,c,d)=>{if(r.push({paramName:s,isOptional:u!=null}),u){let f=d.charAt(c+l.length);return f&&f!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return e.endsWith("*")?(r.push({paramName:"*"}),a+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?a+="\\/*$":e!==""&&e!=="/"&&(a+="(?:(?=\\/|$))"),[new RegExp(a,t?void 0:"i"),r]}function rt(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return L(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function $(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}var nt=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function at(e,t="/"){let{pathname:n,search:r="",hash:a=""}=typeof e=="string"?N(e):e,o;return n?(n=xe(n),n.startsWith("/")?o=pe(n.substring(1),"/"):o=pe(n,t)):o=t,{pathname:o,search:it(r),hash:st(a)}}function pe(e,t){let n=J(t).split("/");return e.split("/").forEach(a=>{a===".."?n.length>1&&n.pop():a!=="."&&n.push(a)}),n.length>1?n.join("/"):"/"}function G(e,t,n,r){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function ot(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function Ee(e){let t=ot(e);return t.map((n,r)=>r===t.length-1?n.pathname:n.pathnameBase)}function te(e,t,n,r=!1){let a;typeof e=="string"?a=N(e):(a={...e},E(!a.pathname||!a.pathname.includes("?"),G("?","pathname","search",a)),E(!a.pathname||!a.pathname.includes("#"),G("#","pathname","hash",a)),E(!a.search||!a.search.includes("#"),G("#","search","hash",a)));let o=e===""||a.pathname==="",l=o?"/":a.pathname,s;if(l==null)s=n;else{let f=t.length-1;if(!r&&l.startsWith("..")){let m=l.split("/");for(;m[0]==="..";)m.shift(),f-=1;a.pathname=m.join("/")}s=f>=0?t[f]:"/"}let u=at(a,s),c=l&&l!=="/"&&l.endsWith("/"),d=(o||l===".")&&n.endsWith("/");return!u.pathname.endsWith("/")&&(c||d)&&(u.pathname+="/"),u}var xe=e=>e.replace(/\/\/+/g,"/"),S=e=>xe(e.join("/")),J=e=>e.replace(/\/+$/,""),lt=e=>J(e).replace(/^\/*/,"/"),it=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,st=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e,ut=class{constructor(e,t,n,r=!1){this.status=e,this.statusText=t||"",this.internal=r,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function ct(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}function ft(e){let t=e.map(n=>n.route.path).filter(Boolean);return S(t)||"/"}var Ce=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function be(e,t){let n=e;if(typeof n!="string"||!nt.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let r=n,a=!1;if(Ce)try{let o=new URL(window.location.href),l=n.startsWith("//")?new URL(o.protocol+n):new URL(n),s=$(l.pathname,t);l.origin===o.origin&&s!=null?n=s+l.search+l.hash:a=!0}catch{L(!1,`<Link to="${n}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:a,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var Se=["POST","PUT","PATCH","DELETE"];new Set(Se);var dt=["GET",...Se];new Set(dt);var _=i.createContext(null);_.displayName="DataRouter";var K=i.createContext(null);K.displayName="DataRouterState";var Pe=i.createContext(!1);function ht(){return i.useContext(Pe)}var Le=i.createContext({isTransitioning:!1});Le.displayName="ViewTransition";var mt=i.createContext(new Map);mt.displayName="Fetchers";var pt=i.createContext(null);pt.displayName="Await";var b=i.createContext(null);b.displayName="Navigation";var A=i.createContext(null);A.displayName="Location";var k=i.createContext({outlet:null,matches:[],isDataRoute:!1});k.displayName="Route";var re=i.createContext(null);re.displayName="RouteError";var ke="REACT_ROUTER_ERROR",yt="REDIRECT",gt="ROUTE_ERROR_RESPONSE";function vt(e){if(e.startsWith(`${ke}:${yt}:{`))try{let t=JSON.parse(e.slice(28));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.location=="string"&&typeof t.reloadDocument=="boolean"&&typeof t.replace=="boolean")return t}catch{}}function Rt(e){if(e.startsWith(`${ke}:${gt}:{`))try{let t=JSON.parse(e.slice(40));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string")return new ut(t.status,t.statusText,t.data)}catch{}}function wt(e,{relative:t}={}){E(U(),"useHref() may be used only in the context of a <Router> component.");let{basename:n,navigator:r}=i.useContext(b),{hash:a,pathname:o,search:l}=W(e,{relative:t}),s=o;return n!=="/"&&(s=o==="/"?n:S([n,o])),r.createHref({pathname:s,search:l,hash:a})}function U(){return i.useContext(A)!=null}function T(){return E(U(),"useLocation() may be used only in the context of a <Router> component."),i.useContext(A).location}var $e="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Te(e){i.useContext(b).static||i.useLayoutEffect(e)}function Et(){let{isDataRoute:e}=i.useContext(k);return e?Nt():xt()}function xt(){E(U(),"useNavigate() may be used only in the context of a <Router> component.");let e=i.useContext(_),{basename:t,navigator:n}=i.useContext(b),{matches:r}=i.useContext(k),{pathname:a}=T(),o=JSON.stringify(Ee(r)),l=i.useRef(!1);return Te(()=>{l.current=!0}),i.useCallback((u,c={})=>{if(L(l.current,$e),!l.current)return;if(typeof u=="number"){n.go(u);return}let d=te(u,JSON.parse(o),a,c.relative==="path");e==null&&t!=="/"&&(d.pathname=d.pathname==="/"?t:S([t,d.pathname])),(c.replace?n.replace:n.push)(d,c.state,c)},[t,n,o,a,e])}i.createContext(null);function gr(){let{matches:e}=i.useContext(k),t=e[e.length-1];return(t==null?void 0:t.params)??{}}function W(e,{relative:t}={}){let{matches:n}=i.useContext(k),{pathname:r}=T(),a=JSON.stringify(Ee(n));return i.useMemo(()=>te(e,JSON.parse(a),r,t==="path"),[e,a,r,t])}function Ct(e,t){return De(e,t)}function De(e,t,n){var p;E(U(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:r}=i.useContext(b),{matches:a}=i.useContext(k),o=a[a.length-1],l=o?o.params:{},s=o?o.pathname:"/",u=o?o.pathnameBase:"/",c=o&&o.route;{let h=c&&c.path||"";Ie(s,!c||h.endsWith("*")||h.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${s}" (under <Route path="${h}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
11
11
 
12
- Please change the parent <Route path="${h}"> to <Route path="${h==="/"?"*":`${h}/*`}">.`)}let d=T(),f;if(t){let h=typeof t=="string"?N(t):t;E(u==="/"||((p=h.pathname)==null?void 0:p.startsWith(u)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${u}" but pathname "${h.pathname}" was given in the \`location\` prop.`),f=h}else f=d;let m=f.pathname||"/",g=m;if(u!=="/"){let h=u.replace(/^\//,"").split("/");g="/"+m.replace(/^\//,"").split("/").slice(h.length).join("/")}let v=ve(e,{pathname:g});L(c||v!=null,`No routes matched location "${f.pathname}${f.search}${f.hash}" `),L(v==null||v[v.length-1].route.element!==void 0||v[v.length-1].route.Component!==void 0||v[v.length-1].route.lazy!==void 0,`Matched leaf route at location "${f.pathname}${f.search}${f.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let y=kt(v&&v.map(h=>Object.assign({},h,{params:Object.assign({},l,h.params),pathname:S([u,r.encodeLocation?r.encodeLocation(h.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:h.pathname]),pathnameBase:h.pathnameBase==="/"?u:S([u,r.encodeLocation?r.encodeLocation(h.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:h.pathnameBase])})),a,n);return t&&y?i.createElement(A.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...f},navigationType:"POP"}},y):y}function bt(){let e=It(),t=ct(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r="rgba(200,200,200, 0.5)",a={padding:"0.5rem",backgroundColor:r},o={padding:"2px 4px",backgroundColor:r},l=null;return console.error("Error handled by React Router default ErrorBoundary:",e),l=i.createElement(i.Fragment,null,i.createElement("p",null,"💿 Hey developer 👋"),i.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",i.createElement("code",{style:o},"ErrorBoundary")," or"," ",i.createElement("code",{style:o},"errorElement")," prop on your route.")),i.createElement(i.Fragment,null,i.createElement("h2",null,"Unexpected Application Error!"),i.createElement("h3",{style:{fontStyle:"italic"}},t),n?i.createElement("pre",{style:a},n):null,l)}var St=i.createElement(bt,null),Fe=class extends i.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error("React Router caught the following error during render",e)}render(){let e=this.state.error;if(this.context&&typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){const n=Rt(e.digest);n&&(e=n)}let t=e!==void 0?i.createElement(k.Provider,{value:this.props.routeContext},i.createElement(re.Provider,{value:e,children:this.props.component})):this.props.children;return this.context?i.createElement(Pt,{error:e},t):t}};Fe.contextType=Pe;var X=new WeakMap;function Pt({children:e,error:t}){let{basename:n}=i.useContext(b);if(typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){let r=vt(t.digest);if(r){let a=X.get(t);if(a)throw a;let o=be(r.location,n);if(Ce&&!X.get(t))if(o.isExternal||r.reloadDocument)window.location.href=o.absoluteURL||o.to;else{const l=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(o.to,{replace:r.replace}));throw X.set(t,l),l}return i.createElement("meta",{httpEquiv:"refresh",content:`0;url=${o.absoluteURL||o.to}`})}}return e}function Lt({routeContext:e,match:t,children:n}){let r=i.useContext(_);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),i.createElement(k.Provider,{value:e},n)}function kt(e,t=[],n){let r=n==null?void 0:n.state;if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let a=e,o=r==null?void 0:r.errors;if(o!=null){let d=a.findIndex(f=>f.route.id&&(o==null?void 0:o[f.route.id])!==void 0);E(d>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),a=a.slice(0,Math.min(a.length,d+1))}let l=!1,s=-1;if(n&&r){l=r.renderFallback;for(let d=0;d<a.length;d++){let f=a[d];if((f.route.HydrateFallback||f.route.hydrateFallbackElement)&&(s=d),f.route.id){let{loaderData:m,errors:g}=r,v=f.route.loader&&!m.hasOwnProperty(f.route.id)&&(!g||g[f.route.id]===void 0);if(f.route.lazy||v){n.isStatic&&(l=!0),s>=0?a=a.slice(0,s+1):a=[a[0]];break}}}}let u=n==null?void 0:n.onError,c=r&&u?(d,f)=>{var m,g;u(d,{location:r.location,params:((g=(m=r.matches)==null?void 0:m[0])==null?void 0:g.params)??{},unstable_pattern:ft(r.matches),errorInfo:f})}:void 0;return a.reduceRight((d,f,m)=>{let g,v=!1,y=null,p=null;r&&(g=o&&f.route.id?o[f.route.id]:void 0,y=f.route.errorElement||St,l&&(s<0&&m===0?(Ie("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),v=!0,p=null):s===m&&(v=!0,p=f.route.hydrateFallbackElement||null)));let h=t.concat(a.slice(0,m+1)),R=()=>{let w;return g?w=y:v?w=p:f.route.Component?w=i.createElement(f.route.Component,null):f.route.element?w=f.route.element:w=d,i.createElement(Lt,{match:f,routeContext:{outlet:d,matches:h,isDataRoute:r!=null},children:w})};return r&&(f.route.ErrorBoundary||f.route.errorElement||m===0)?i.createElement(Fe,{location:r.location,revalidation:r.revalidation,component:y,error:g,children:R(),routeContext:{outlet:null,matches:h,isDataRoute:!0},onError:c}):R()},null)}function ne(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function $t(e){let t=i.useContext(_);return E(t,ne(e)),t}function Tt(e){let t=i.useContext(K);return E(t,ne(e)),t}function Dt(e){let t=i.useContext(k);return E(t,ne(e)),t}function ae(e){let t=Dt(e),n=t.matches[t.matches.length-1];return E(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Ft(){return ae("useRouteId")}function It(){var r;let e=i.useContext(re),t=Tt("useRouteError"),n=ae("useRouteError");return e!==void 0?e:(r=t.errors)==null?void 0:r[n]}function Nt(){let{router:e}=$t("useNavigate"),t=ae("useNavigate"),n=i.useRef(!1);return Te(()=>{n.current=!0}),i.useCallback(async(a,o={})=>{L(n.current,$e),n.current&&(typeof a=="number"?await e.navigate(a):await e.navigate(a,{fromRouteId:t,...o}))},[e,t])}var ye={};function Ie(e,t,n){!t&&!ye[e]&&(ye[e]=!0,L(!1,n))}i.memo(_t);function _t({routes:e,future:t,state:n,isStatic:r,onError:a}){return De(e,void 0,{state:n,isStatic:r,onError:a})}function Bt(e){E(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function Mt({basename:e="/",children:t=null,location:n,navigationType:r="POP",navigator:a,static:o=!1,unstable_useTransitions:l}){E(!U(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let s=e.replace(/^\/*/,"/"),u=i.useMemo(()=>({basename:s,navigator:a,static:o,unstable_useTransitions:l,future:{}}),[s,a,o,l]);typeof n=="string"&&(n=N(n));let{pathname:c="/",search:d="",hash:f="",state:m=null,key:g="default",unstable_mask:v}=n,y=i.useMemo(()=>{let p=$(c,s);return p==null?null:{location:{pathname:p,search:d,hash:f,state:m,key:g,unstable_mask:v},navigationType:r}},[s,c,d,f,m,g,r,v]);return L(y!=null,`<Router basename="${s}"> is not able to match the URL "${c}${d}${f}" because it does not start with the basename, so the <Router> won't render anything.`),y==null?null:i.createElement(b.Provider,{value:u},i.createElement(A.Provider,{children:t,value:y}))}function vr({children:e,location:t}){return Ct(ee(e),t)}function ee(e,t=[]){let n=[];return i.Children.forEach(e,(r,a)=>{if(!i.isValidElement(r))return;let o=[...t,a];if(r.type===i.Fragment){n.push.apply(n,ee(r.props.children,o));return}E(r.type===Bt,`[${typeof r.type=="string"?r.type:r.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),E(!r.props.index||!r.props.children,"An index route cannot have child routes.");let l={id:r.props.id||o.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(l.children=ee(r.props.children,o)),n.push(l)}),n}var z="get",j="application/x-www-form-urlencoded";function q(e){return typeof HTMLElement<"u"&&e instanceof HTMLElement}function Ot(e){return q(e)&&e.tagName.toLowerCase()==="button"}function At(e){return q(e)&&e.tagName.toLowerCase()==="form"}function Ut(e){return q(e)&&e.tagName.toLowerCase()==="input"}function Wt(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Ht(e,t){return e.button===0&&(!t||t==="_self")&&!Wt(e)}var H=null;function zt(){if(H===null)try{new FormData(document.createElement("form"),0),H=!1}catch{H=!0}return H}var jt=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Q(e){return e!=null&&!jt.has(e)?(L(!1,`"${e}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${j}"`),null):e}function Vt(e,t){let n,r,a,o,l;if(At(e)){let s=e.getAttribute("action");r=s?$(s,t):null,n=e.getAttribute("method")||z,a=Q(e.getAttribute("enctype"))||j,o=new FormData(e)}else if(Ot(e)||Ut(e)&&(e.type==="submit"||e.type==="image")){let s=e.form;if(s==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let u=e.getAttribute("formaction")||s.getAttribute("action");if(r=u?$(u,t):null,n=e.getAttribute("formmethod")||s.getAttribute("method")||z,a=Q(e.getAttribute("formenctype"))||Q(s.getAttribute("enctype"))||j,o=new FormData(s,e),!zt()){let{name:c,type:d,value:f}=e;if(d==="image"){let m=c?`${c}.`:"";o.append(`${m}x`,"0"),o.append(`${m}y`,"0")}else c&&o.append(c,f)}}else{if(q(e))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');n=z,r=null,a=j,l=e}return o&&a==="text/plain"&&(l=o,o=void 0),{action:r,method:n.toLowerCase(),encType:a,formData:o,body:l}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function oe(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function Ne(e,t,n,r){let a=typeof e=="string"?new URL(e,typeof window>"u"?"server://singlefetch/":window.location.origin):e;return n?a.pathname.endsWith("/")?a.pathname=`${a.pathname}_.${r}`:a.pathname=`${a.pathname}.${r}`:a.pathname==="/"?a.pathname=`_root.${r}`:t&&$(a.pathname,t)==="/"?a.pathname=`${J(t)}/_root.${r}`:a.pathname=`${J(a.pathname)}.${r}`,a}async function Jt(e,t){if(e.id in t)return t[e.id];try{let n=await import(e.module);return t[e.id]=n,n}catch(n){return console.error(`Error loading route module \`${e.module}\`, reloading page...`),console.error(n),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function Kt(e){return e==null?!1:e.href==null?e.rel==="preload"&&typeof e.imageSrcSet=="string"&&typeof e.imageSizes=="string":typeof e.rel=="string"&&typeof e.href=="string"}async function qt(e,t,n){let r=await Promise.all(e.map(async a=>{let o=t.routes[a.route.id];if(o){let l=await Jt(o,n);return l.links?l.links():[]}return[]}));return Qt(r.flat(1).filter(Kt).filter(a=>a.rel==="stylesheet"||a.rel==="preload").map(a=>a.rel==="stylesheet"?{...a,rel:"prefetch",as:"style"}:{...a,rel:"prefetch"}))}function ge(e,t,n,r,a,o){let l=(u,c)=>n[c]?u.route.id!==n[c].route.id:!0,s=(u,c)=>{var d;return n[c].pathname!==u.pathname||((d=n[c].route.path)==null?void 0:d.endsWith("*"))&&n[c].params["*"]!==u.params["*"]};return o==="assets"?t.filter((u,c)=>l(u,c)||s(u,c)):o==="data"?t.filter((u,c)=>{var f;let d=r.routes[u.route.id];if(!d||!d.hasLoader)return!1;if(l(u,c)||s(u,c))return!0;if(u.route.shouldRevalidate){let m=u.route.shouldRevalidate({currentUrl:new URL(a.pathname+a.search+a.hash,window.origin),currentParams:((f=n[0])==null?void 0:f.params)||{},nextUrl:new URL(e,window.origin),nextParams:u.params,defaultShouldRevalidate:!0});if(typeof m=="boolean")return m}return!0}):[]}function Yt(e,t,{includeHydrateFallback:n}={}){return Gt(e.map(r=>{let a=t.routes[r.route.id];if(!a)return[];let o=[a.module];return a.clientActionModule&&(o=o.concat(a.clientActionModule)),a.clientLoaderModule&&(o=o.concat(a.clientLoaderModule)),n&&a.hydrateFallbackModule&&(o=o.concat(a.hydrateFallbackModule)),a.imports&&(o=o.concat(a.imports)),o}).flat(1))}function Gt(e){return[...new Set(e)]}function Xt(e){let t={},n=Object.keys(e).sort();for(let r of n)t[r]=e[r];return t}function Qt(e,t){let n=new Set;return new Set(t),e.reduce((r,a)=>{let o=JSON.stringify(Xt(a));return n.has(o)||(n.add(o),r.push({key:o,link:a})),r},[])}function le(){let e=i.useContext(_);return oe(e,"You must render this element inside a <DataRouterContext.Provider> element"),e}function Zt(){let e=i.useContext(K);return oe(e,"You must render this element inside a <DataRouterStateContext.Provider> element"),e}var ie=i.createContext(void 0);ie.displayName="FrameworkContext";function se(){let e=i.useContext(ie);return oe(e,"You must render this element inside a <HydratedRouter> element"),e}function er(e,t){let n=i.useContext(ie),[r,a]=i.useState(!1),[o,l]=i.useState(!1),{onFocus:s,onBlur:u,onMouseEnter:c,onMouseLeave:d,onTouchStart:f}=t,m=i.useRef(null);i.useEffect(()=>{if(e==="render"&&l(!0),e==="viewport"){let y=h=>{h.forEach(R=>{l(R.isIntersecting)})},p=new IntersectionObserver(y,{threshold:.5});return m.current&&p.observe(m.current),()=>{p.disconnect()}}},[e]),i.useEffect(()=>{if(r){let y=setTimeout(()=>{l(!0)},100);return()=>{clearTimeout(y)}}},[r]);let g=()=>{a(!0)},v=()=>{a(!1),l(!1)};return n?e!=="intent"?[o,m,{}]:[o,m,{onFocus:M(s,g),onBlur:M(u,v),onMouseEnter:M(c,g),onMouseLeave:M(d,v),onTouchStart:M(f,g)}]:[!1,m,{}]}function M(e,t){return n=>{e&&e(n),n.defaultPrevented||t(n)}}function tr({page:e,...t}){let n=ht(),{router:r}=le(),a=i.useMemo(()=>ve(r.routes,e,r.basename),[r.routes,e,r.basename]);return a?n?i.createElement(nr,{page:e,matches:a,...t}):i.createElement(ar,{page:e,matches:a,...t}):null}function rr(e){let{manifest:t,routeModules:n}=se(),[r,a]=i.useState([]);return i.useEffect(()=>{let o=!1;return qt(e,t,n).then(l=>{o||a(l)}),()=>{o=!0}},[e,t,n]),r}function nr({page:e,matches:t,...n}){let r=T(),{future:a}=se(),{basename:o}=le(),l=i.useMemo(()=>{if(e===r.pathname+r.search+r.hash)return[];let s=Ne(e,o,a.unstable_trailingSlashAwareDataRequests,"rsc"),u=!1,c=[];for(let d of t)typeof d.route.shouldRevalidate=="function"?u=!0:c.push(d.route.id);return u&&c.length>0&&s.searchParams.set("_routes",c.join(",")),[s.pathname+s.search]},[o,a.unstable_trailingSlashAwareDataRequests,e,r,t]);return i.createElement(i.Fragment,null,l.map(s=>i.createElement("link",{key:s,rel:"prefetch",as:"fetch",href:s,...n})))}function ar({page:e,matches:t,...n}){let r=T(),{future:a,manifest:o,routeModules:l}=se(),{basename:s}=le(),{loaderData:u,matches:c}=Zt(),d=i.useMemo(()=>ge(e,t,c,o,r,"data"),[e,t,c,o,r]),f=i.useMemo(()=>ge(e,t,c,o,r,"assets"),[e,t,c,o,r]),m=i.useMemo(()=>{if(e===r.pathname+r.search+r.hash)return[];let y=new Set,p=!1;if(t.forEach(R=>{var C;let w=o.routes[R.route.id];!w||!w.hasLoader||(!d.some(x=>x.route.id===R.route.id)&&R.route.id in u&&((C=l[R.route.id])!=null&&C.shouldRevalidate)||w.hasClientLoader?p=!0:y.add(R.route.id))}),y.size===0)return[];let h=Ne(e,s,a.unstable_trailingSlashAwareDataRequests,"data");return p&&y.size>0&&h.searchParams.set("_routes",t.filter(R=>y.has(R.route.id)).map(R=>R.route.id).join(",")),[h.pathname+h.search]},[s,a.unstable_trailingSlashAwareDataRequests,u,r,o,d,t,e,l]),g=i.useMemo(()=>Yt(f,o),[f,o]),v=rr(f);return i.createElement(i.Fragment,null,m.map(y=>i.createElement("link",{key:y,rel:"prefetch",as:"fetch",href:y,...n})),g.map(y=>i.createElement("link",{key:y,rel:"modulepreload",href:y,...n})),v.map(({key:y,link:p})=>i.createElement("link",{key:y,nonce:n.nonce,...p,crossOrigin:p.crossOrigin??n.crossOrigin})))}function or(...e){return t=>{e.forEach(n=>{typeof n=="function"?n(t):n!=null&&(n.current=t)})}}var lr=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{lr&&(window.__reactRouterVersion="7.14.2")}catch{}function Rr({basename:e,children:t,unstable_useTransitions:n,window:r}){let a=i.useRef();a.current==null&&(a.current=Ue({window:r,v5Compat:!0}));let o=a.current,[l,s]=i.useState({action:o.action,location:o.location}),u=i.useCallback(c=>{n===!1?s(c):i.startTransition(()=>s(c))},[n]);return i.useLayoutEffect(()=>o.listen(u),[o,u]),i.createElement(Mt,{basename:e,children:t,location:l.location,navigationType:l.action,navigator:o,unstable_useTransitions:n})}var _e=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Be=i.forwardRef(function({onClick:t,discover:n="render",prefetch:r="none",relative:a,reloadDocument:o,replace:l,unstable_mask:s,state:u,target:c,to:d,preventScrollReset:f,viewTransition:m,unstable_defaultShouldRevalidate:g,...v},y){let{basename:p,navigator:h,unstable_useTransitions:R}=i.useContext(b),w=typeof d=="string"&&_e.test(d),C=be(d,p);d=C.to;let x=wt(d,{relative:a}),P=T(),D=null;if(s){let F=te(s,[],P.unstable_mask?P.unstable_mask.pathname:"/",!0);p!=="/"&&(F.pathname=F.pathname==="/"?p:S([p,F.pathname])),D=h.createHref(F)}let[I,B,Y]=er(r,v),Oe=cr(d,{replace:l,unstable_mask:s,state:u,target:c,preventScrollReset:f,relative:a,viewTransition:m,unstable_defaultShouldRevalidate:g,unstable_useTransitions:R});function Ae(F){t&&t(F),F.defaultPrevented||Oe(F)}let ue=!(C.isExternal||o),ce=i.createElement("a",{...v,...Y,href:(ue?D:void 0)||C.absoluteURL||x,onClick:ue?Ae:t,ref:or(y,B),target:c,"data-discover":!w&&n==="render"?"true":void 0});return I&&!w?i.createElement(i.Fragment,null,ce,i.createElement(tr,{page:x})):ce});Be.displayName="Link";var ir=i.forwardRef(function({"aria-current":t="page",caseSensitive:n=!1,className:r="",end:a=!1,style:o,to:l,viewTransition:s,children:u,...c},d){let f=W(l,{relative:c.relative}),m=T(),g=i.useContext(K),{navigator:v,basename:y}=i.useContext(b),p=g!=null&&pr(f)&&s===!0,h=v.encodeLocation?v.encodeLocation(f).pathname:f.pathname,R=m.pathname,w=g&&g.navigation&&g.navigation.location?g.navigation.location.pathname:null;n||(R=R.toLowerCase(),w=w?w.toLowerCase():null,h=h.toLowerCase()),w&&y&&(w=$(w,y)||w);const C=h!=="/"&&h.endsWith("/")?h.length-1:h.length;let x=R===h||!a&&R.startsWith(h)&&R.charAt(C)==="/",P=w!=null&&(w===h||!a&&w.startsWith(h)&&w.charAt(h.length)==="/"),D={isActive:x,isPending:P,isTransitioning:p},I=x?t:void 0,B;typeof r=="function"?B=r(D):B=[r,x?"active":null,P?"pending":null,p?"transitioning":null].filter(Boolean).join(" ");let Y=typeof o=="function"?o(D):o;return i.createElement(Be,{...c,"aria-current":I,className:B,ref:d,style:Y,to:l,viewTransition:s},typeof u=="function"?u(D):u)});ir.displayName="NavLink";var sr=i.forwardRef(({discover:e="render",fetcherKey:t,navigate:n,reloadDocument:r,replace:a,state:o,method:l=z,action:s,onSubmit:u,relative:c,preventScrollReset:d,viewTransition:f,unstable_defaultShouldRevalidate:m,...g},v)=>{let{unstable_useTransitions:y}=i.useContext(b),p=hr(),h=mr(s,{relative:c}),R=l.toLowerCase()==="get"?"get":"post",w=typeof s=="string"&&_e.test(s),C=x=>{if(u&&u(x),x.defaultPrevented)return;x.preventDefault();let P=x.nativeEvent.submitter,D=(P==null?void 0:P.getAttribute("formmethod"))||l,I=()=>p(P||x.currentTarget,{fetcherKey:t,method:D,navigate:n,replace:a,state:o,relative:c,preventScrollReset:d,viewTransition:f,unstable_defaultShouldRevalidate:m});y&&n!==!1?i.startTransition(()=>I()):I()};return i.createElement("form",{ref:v,method:R,action:h,onSubmit:r?u:C,...g,"data-discover":!w&&e==="render"?"true":void 0})});sr.displayName="Form";function ur(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Me(e){let t=i.useContext(_);return E(t,ur(e)),t}function cr(e,{target:t,replace:n,unstable_mask:r,state:a,preventScrollReset:o,relative:l,viewTransition:s,unstable_defaultShouldRevalidate:u,unstable_useTransitions:c}={}){let d=Et(),f=T(),m=W(e,{relative:l});return i.useCallback(g=>{if(Ht(g,t)){g.preventDefault();let v=n!==void 0?n:O(f)===O(m),y=()=>d(e,{replace:v,unstable_mask:r,state:a,preventScrollReset:o,relative:l,viewTransition:s,unstable_defaultShouldRevalidate:u});c?i.startTransition(()=>y()):y()}},[f,d,m,n,r,a,t,e,o,l,s,u,c])}var fr=0,dr=()=>`__${String(++fr)}__`;function hr(){let{router:e}=Me("useSubmit"),{basename:t}=i.useContext(b),n=Ft(),r=e.fetch,a=e.navigate;return i.useCallback(async(o,l={})=>{let{action:s,method:u,encType:c,formData:d,body:f}=Vt(o,t);if(l.navigate===!1){let m=l.fetcherKey||dr();await r(m,n,l.action||s,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:d,body:f,formMethod:l.method||u,formEncType:l.encType||c,flushSync:l.flushSync})}else await a(l.action||s,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:d,body:f,formMethod:l.method||u,formEncType:l.encType||c,replace:l.replace,state:l.state,fromRouteId:n,flushSync:l.flushSync,viewTransition:l.viewTransition})},[r,a,t,n])}function mr(e,{relative:t}={}){let{basename:n}=i.useContext(b),r=i.useContext(k);E(r,"useFormAction must be used inside a RouteContext");let[a]=r.matches.slice(-1),o={...W(e||".",{relative:t})},l=T();if(e==null){o.search=l.search;let s=new URLSearchParams(o.search),u=s.getAll("index");if(u.some(d=>d==="")){s.delete("index"),u.filter(f=>f).forEach(f=>s.append("index",f));let d=s.toString();o.search=d?`?${d}`:""}}return(!e||e===".")&&a.route.index&&(o.search=o.search?o.search.replace(/^\?/,"?index&"):"?index"),n!=="/"&&(o.pathname=o.pathname==="/"?n:S([n,o.pathname])),O(o)}function pr(e,{relative:t}={}){let n=i.useContext(Le);E(n!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=Me("useViewTransitionState"),a=W(e,{relative:t});if(!n.isTransitioning)return!1;let o=$(n.currentLocation.pathname,r)||n.currentLocation.pathname,l=$(n.nextLocation.pathname,r)||n.nextLocation.pathname;return V(a.pathname,l)!=null||V(a.pathname,o)!=null}export{Rr as B,Be as L,ir as N,vr as R,gr as a,Bt as b,Et as u};
12
+ Please change the parent <Route path="${h}"> to <Route path="${h==="/"?"*":`${h}/*`}">.`)}let d=T(),f;if(t){let h=typeof t=="string"?N(t):t;E(u==="/"||((p=h.pathname)==null?void 0:p.startsWith(u)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${u}" but pathname "${h.pathname}" was given in the \`location\` prop.`),f=h}else f=d;let m=f.pathname||"/",g=m;if(u!=="/"){let h=u.replace(/^\//,"").split("/");g="/"+m.replace(/^\//,"").split("/").slice(h.length).join("/")}let v=ve(e,{pathname:g});L(c||v!=null,`No routes matched location "${f.pathname}${f.search}${f.hash}" `),L(v==null||v[v.length-1].route.element!==void 0||v[v.length-1].route.Component!==void 0||v[v.length-1].route.lazy!==void 0,`Matched leaf route at location "${f.pathname}${f.search}${f.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let y=kt(v&&v.map(h=>Object.assign({},h,{params:Object.assign({},l,h.params),pathname:S([u,r.encodeLocation?r.encodeLocation(h.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:h.pathname]),pathnameBase:h.pathnameBase==="/"?u:S([u,r.encodeLocation?r.encodeLocation(h.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:h.pathnameBase])})),a,n);return t&&y?i.createElement(A.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...f},navigationType:"POP"}},y):y}function bt(){let e=It(),t=ct(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r="rgba(200,200,200, 0.5)",a={padding:"0.5rem",backgroundColor:r},o={padding:"2px 4px",backgroundColor:r},l=null;return console.error("Error handled by React Router default ErrorBoundary:",e),l=i.createElement(i.Fragment,null,i.createElement("p",null,"💿 Hey developer 👋"),i.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",i.createElement("code",{style:o},"ErrorBoundary")," or"," ",i.createElement("code",{style:o},"errorElement")," prop on your route.")),i.createElement(i.Fragment,null,i.createElement("h2",null,"Unexpected Application Error!"),i.createElement("h3",{style:{fontStyle:"italic"}},t),n?i.createElement("pre",{style:a},n):null,l)}var St=i.createElement(bt,null),Fe=class extends i.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error("React Router caught the following error during render",e)}render(){let e=this.state.error;if(this.context&&typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){const n=Rt(e.digest);n&&(e=n)}let t=e!==void 0?i.createElement(k.Provider,{value:this.props.routeContext},i.createElement(re.Provider,{value:e,children:this.props.component})):this.props.children;return this.context?i.createElement(Pt,{error:e},t):t}};Fe.contextType=Pe;var X=new WeakMap;function Pt({children:e,error:t}){let{basename:n}=i.useContext(b);if(typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){let r=vt(t.digest);if(r){let a=X.get(t);if(a)throw a;let o=be(r.location,n);if(Ce&&!X.get(t))if(o.isExternal||r.reloadDocument)window.location.href=o.absoluteURL||o.to;else{const l=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(o.to,{replace:r.replace}));throw X.set(t,l),l}return i.createElement("meta",{httpEquiv:"refresh",content:`0;url=${o.absoluteURL||o.to}`})}}return e}function Lt({routeContext:e,match:t,children:n}){let r=i.useContext(_);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),i.createElement(k.Provider,{value:e},n)}function kt(e,t=[],n){let r=n==null?void 0:n.state;if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let a=e,o=r==null?void 0:r.errors;if(o!=null){let d=a.findIndex(f=>f.route.id&&(o==null?void 0:o[f.route.id])!==void 0);E(d>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),a=a.slice(0,Math.min(a.length,d+1))}let l=!1,s=-1;if(n&&r){l=r.renderFallback;for(let d=0;d<a.length;d++){let f=a[d];if((f.route.HydrateFallback||f.route.hydrateFallbackElement)&&(s=d),f.route.id){let{loaderData:m,errors:g}=r,v=f.route.loader&&!m.hasOwnProperty(f.route.id)&&(!g||g[f.route.id]===void 0);if(f.route.lazy||v){n.isStatic&&(l=!0),s>=0?a=a.slice(0,s+1):a=[a[0]];break}}}}let u=n==null?void 0:n.onError,c=r&&u?(d,f)=>{var m,g;u(d,{location:r.location,params:((g=(m=r.matches)==null?void 0:m[0])==null?void 0:g.params)??{},unstable_pattern:ft(r.matches),errorInfo:f})}:void 0;return a.reduceRight((d,f,m)=>{let g,v=!1,y=null,p=null;r&&(g=o&&f.route.id?o[f.route.id]:void 0,y=f.route.errorElement||St,l&&(s<0&&m===0?(Ie("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),v=!0,p=null):s===m&&(v=!0,p=f.route.hydrateFallbackElement||null)));let h=t.concat(a.slice(0,m+1)),R=()=>{let w;return g?w=y:v?w=p:f.route.Component?w=i.createElement(f.route.Component,null):f.route.element?w=f.route.element:w=d,i.createElement(Lt,{match:f,routeContext:{outlet:d,matches:h,isDataRoute:r!=null},children:w})};return r&&(f.route.ErrorBoundary||f.route.errorElement||m===0)?i.createElement(Fe,{location:r.location,revalidation:r.revalidation,component:y,error:g,children:R(),routeContext:{outlet:null,matches:h,isDataRoute:!0},onError:c}):R()},null)}function ne(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function $t(e){let t=i.useContext(_);return E(t,ne(e)),t}function Tt(e){let t=i.useContext(K);return E(t,ne(e)),t}function Dt(e){let t=i.useContext(k);return E(t,ne(e)),t}function ae(e){let t=Dt(e),n=t.matches[t.matches.length-1];return E(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Ft(){return ae("useRouteId")}function It(){var r;let e=i.useContext(re),t=Tt("useRouteError"),n=ae("useRouteError");return e!==void 0?e:(r=t.errors)==null?void 0:r[n]}function Nt(){let{router:e}=$t("useNavigate"),t=ae("useNavigate"),n=i.useRef(!1);return Te(()=>{n.current=!0}),i.useCallback(async(a,o={})=>{L(n.current,$e),n.current&&(typeof a=="number"?await e.navigate(a):await e.navigate(a,{fromRouteId:t,...o}))},[e,t])}var ye={};function Ie(e,t,n){!t&&!ye[e]&&(ye[e]=!0,L(!1,n))}i.memo(_t);function _t({routes:e,future:t,state:n,isStatic:r,onError:a}){return De(e,void 0,{state:n,isStatic:r,onError:a})}function Bt(e){E(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function Mt({basename:e="/",children:t=null,location:n,navigationType:r="POP",navigator:a,static:o=!1,unstable_useTransitions:l}){E(!U(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let s=e.replace(/^\/*/,"/"),u=i.useMemo(()=>({basename:s,navigator:a,static:o,unstable_useTransitions:l,future:{}}),[s,a,o,l]);typeof n=="string"&&(n=N(n));let{pathname:c="/",search:d="",hash:f="",state:m=null,key:g="default",unstable_mask:v}=n,y=i.useMemo(()=>{let p=$(c,s);return p==null?null:{location:{pathname:p,search:d,hash:f,state:m,key:g,unstable_mask:v},navigationType:r}},[s,c,d,f,m,g,r,v]);return L(y!=null,`<Router basename="${s}"> is not able to match the URL "${c}${d}${f}" because it does not start with the basename, so the <Router> won't render anything.`),y==null?null:i.createElement(b.Provider,{value:u},i.createElement(A.Provider,{children:t,value:y}))}function vr({children:e,location:t}){return Ct(ee(e),t)}function ee(e,t=[]){let n=[];return i.Children.forEach(e,(r,a)=>{if(!i.isValidElement(r))return;let o=[...t,a];if(r.type===i.Fragment){n.push.apply(n,ee(r.props.children,o));return}E(r.type===Bt,`[${typeof r.type=="string"?r.type:r.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),E(!r.props.index||!r.props.children,"An index route cannot have child routes.");let l={id:r.props.id||o.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(l.children=ee(r.props.children,o)),n.push(l)}),n}var z="get",j="application/x-www-form-urlencoded";function q(e){return typeof HTMLElement<"u"&&e instanceof HTMLElement}function Ot(e){return q(e)&&e.tagName.toLowerCase()==="button"}function At(e){return q(e)&&e.tagName.toLowerCase()==="form"}function Ut(e){return q(e)&&e.tagName.toLowerCase()==="input"}function Wt(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Ht(e,t){return e.button===0&&(!t||t==="_self")&&!Wt(e)}var H=null;function zt(){if(H===null)try{new FormData(document.createElement("form"),0),H=!1}catch{H=!0}return H}var jt=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Q(e){return e!=null&&!jt.has(e)?(L(!1,`"${e}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${j}"`),null):e}function Vt(e,t){let n,r,a,o,l;if(At(e)){let s=e.getAttribute("action");r=s?$(s,t):null,n=e.getAttribute("method")||z,a=Q(e.getAttribute("enctype"))||j,o=new FormData(e)}else if(Ot(e)||Ut(e)&&(e.type==="submit"||e.type==="image")){let s=e.form;if(s==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let u=e.getAttribute("formaction")||s.getAttribute("action");if(r=u?$(u,t):null,n=e.getAttribute("formmethod")||s.getAttribute("method")||z,a=Q(e.getAttribute("formenctype"))||Q(s.getAttribute("enctype"))||j,o=new FormData(s,e),!zt()){let{name:c,type:d,value:f}=e;if(d==="image"){let m=c?`${c}.`:"";o.append(`${m}x`,"0"),o.append(`${m}y`,"0")}else c&&o.append(c,f)}}else{if(q(e))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');n=z,r=null,a=j,l=e}return o&&a==="text/plain"&&(l=o,o=void 0),{action:r,method:n.toLowerCase(),encType:a,formData:o,body:l}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function oe(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function Ne(e,t,n,r){let a=typeof e=="string"?new URL(e,typeof window>"u"?"server://singlefetch/":window.location.origin):e;return n?a.pathname.endsWith("/")?a.pathname=`${a.pathname}_.${r}`:a.pathname=`${a.pathname}.${r}`:a.pathname==="/"?a.pathname=`_root.${r}`:t&&$(a.pathname,t)==="/"?a.pathname=`${J(t)}/_root.${r}`:a.pathname=`${J(a.pathname)}.${r}`,a}async function Jt(e,t){if(e.id in t)return t[e.id];try{let n=await import(e.module);return t[e.id]=n,n}catch(n){return console.error(`Error loading route module \`${e.module}\`, reloading page...`),console.error(n),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function Kt(e){return e==null?!1:e.href==null?e.rel==="preload"&&typeof e.imageSrcSet=="string"&&typeof e.imageSizes=="string":typeof e.rel=="string"&&typeof e.href=="string"}async function qt(e,t,n){let r=await Promise.all(e.map(async a=>{let o=t.routes[a.route.id];if(o){let l=await Jt(o,n);return l.links?l.links():[]}return[]}));return Qt(r.flat(1).filter(Kt).filter(a=>a.rel==="stylesheet"||a.rel==="preload").map(a=>a.rel==="stylesheet"?{...a,rel:"prefetch",as:"style"}:{...a,rel:"prefetch"}))}function ge(e,t,n,r,a,o){let l=(u,c)=>n[c]?u.route.id!==n[c].route.id:!0,s=(u,c)=>{var d;return n[c].pathname!==u.pathname||((d=n[c].route.path)==null?void 0:d.endsWith("*"))&&n[c].params["*"]!==u.params["*"]};return o==="assets"?t.filter((u,c)=>l(u,c)||s(u,c)):o==="data"?t.filter((u,c)=>{var f;let d=r.routes[u.route.id];if(!d||!d.hasLoader)return!1;if(l(u,c)||s(u,c))return!0;if(u.route.shouldRevalidate){let m=u.route.shouldRevalidate({currentUrl:new URL(a.pathname+a.search+a.hash,window.origin),currentParams:((f=n[0])==null?void 0:f.params)||{},nextUrl:new URL(e,window.origin),nextParams:u.params,defaultShouldRevalidate:!0});if(typeof m=="boolean")return m}return!0}):[]}function Yt(e,t,{includeHydrateFallback:n}={}){return Gt(e.map(r=>{let a=t.routes[r.route.id];if(!a)return[];let o=[a.module];return a.clientActionModule&&(o=o.concat(a.clientActionModule)),a.clientLoaderModule&&(o=o.concat(a.clientLoaderModule)),n&&a.hydrateFallbackModule&&(o=o.concat(a.hydrateFallbackModule)),a.imports&&(o=o.concat(a.imports)),o}).flat(1))}function Gt(e){return[...new Set(e)]}function Xt(e){let t={},n=Object.keys(e).sort();for(let r of n)t[r]=e[r];return t}function Qt(e,t){let n=new Set;return new Set(t),e.reduce((r,a)=>{let o=JSON.stringify(Xt(a));return n.has(o)||(n.add(o),r.push({key:o,link:a})),r},[])}function le(){let e=i.useContext(_);return oe(e,"You must render this element inside a <DataRouterContext.Provider> element"),e}function Zt(){let e=i.useContext(K);return oe(e,"You must render this element inside a <DataRouterStateContext.Provider> element"),e}var ie=i.createContext(void 0);ie.displayName="FrameworkContext";function se(){let e=i.useContext(ie);return oe(e,"You must render this element inside a <HydratedRouter> element"),e}function er(e,t){let n=i.useContext(ie),[r,a]=i.useState(!1),[o,l]=i.useState(!1),{onFocus:s,onBlur:u,onMouseEnter:c,onMouseLeave:d,onTouchStart:f}=t,m=i.useRef(null);i.useEffect(()=>{if(e==="render"&&l(!0),e==="viewport"){let y=h=>{h.forEach(R=>{l(R.isIntersecting)})},p=new IntersectionObserver(y,{threshold:.5});return m.current&&p.observe(m.current),()=>{p.disconnect()}}},[e]),i.useEffect(()=>{if(r){let y=setTimeout(()=>{l(!0)},100);return()=>{clearTimeout(y)}}},[r]);let g=()=>{a(!0)},v=()=>{a(!1),l(!1)};return n?e!=="intent"?[o,m,{}]:[o,m,{onFocus:M(s,g),onBlur:M(u,v),onMouseEnter:M(c,g),onMouseLeave:M(d,v),onTouchStart:M(f,g)}]:[!1,m,{}]}function M(e,t){return n=>{e&&e(n),n.defaultPrevented||t(n)}}function tr({page:e,...t}){let n=ht(),{router:r}=le(),a=i.useMemo(()=>ve(r.routes,e,r.basename),[r.routes,e,r.basename]);return a?n?i.createElement(nr,{page:e,matches:a,...t}):i.createElement(ar,{page:e,matches:a,...t}):null}function rr(e){let{manifest:t,routeModules:n}=se(),[r,a]=i.useState([]);return i.useEffect(()=>{let o=!1;return qt(e,t,n).then(l=>{o||a(l)}),()=>{o=!0}},[e,t,n]),r}function nr({page:e,matches:t,...n}){let r=T(),{future:a}=se(),{basename:o}=le(),l=i.useMemo(()=>{if(e===r.pathname+r.search+r.hash)return[];let s=Ne(e,o,a.unstable_trailingSlashAwareDataRequests,"rsc"),u=!1,c=[];for(let d of t)typeof d.route.shouldRevalidate=="function"?u=!0:c.push(d.route.id);return u&&c.length>0&&s.searchParams.set("_routes",c.join(",")),[s.pathname+s.search]},[o,a.unstable_trailingSlashAwareDataRequests,e,r,t]);return i.createElement(i.Fragment,null,l.map(s=>i.createElement("link",{key:s,rel:"prefetch",as:"fetch",href:s,...n})))}function ar({page:e,matches:t,...n}){let r=T(),{future:a,manifest:o,routeModules:l}=se(),{basename:s}=le(),{loaderData:u,matches:c}=Zt(),d=i.useMemo(()=>ge(e,t,c,o,r,"data"),[e,t,c,o,r]),f=i.useMemo(()=>ge(e,t,c,o,r,"assets"),[e,t,c,o,r]),m=i.useMemo(()=>{if(e===r.pathname+r.search+r.hash)return[];let y=new Set,p=!1;if(t.forEach(R=>{var C;let w=o.routes[R.route.id];!w||!w.hasLoader||(!d.some(x=>x.route.id===R.route.id)&&R.route.id in u&&((C=l[R.route.id])!=null&&C.shouldRevalidate)||w.hasClientLoader?p=!0:y.add(R.route.id))}),y.size===0)return[];let h=Ne(e,s,a.unstable_trailingSlashAwareDataRequests,"data");return p&&y.size>0&&h.searchParams.set("_routes",t.filter(R=>y.has(R.route.id)).map(R=>R.route.id).join(",")),[h.pathname+h.search]},[s,a.unstable_trailingSlashAwareDataRequests,u,r,o,d,t,e,l]),g=i.useMemo(()=>Yt(f,o),[f,o]),v=rr(f);return i.createElement(i.Fragment,null,m.map(y=>i.createElement("link",{key:y,rel:"prefetch",as:"fetch",href:y,...n})),g.map(y=>i.createElement("link",{key:y,rel:"modulepreload",href:y,...n})),v.map(({key:y,link:p})=>i.createElement("link",{key:y,nonce:n.nonce,...p,crossOrigin:p.crossOrigin??n.crossOrigin})))}function or(...e){return t=>{e.forEach(n=>{typeof n=="function"?n(t):n!=null&&(n.current=t)})}}var lr=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{lr&&(window.__reactRouterVersion="7.14.2")}catch{}function Rr({basename:e,children:t,unstable_useTransitions:n,window:r}){let a=i.useRef();a.current==null&&(a.current=Ue({window:r,v5Compat:!0}));let o=a.current,[l,s]=i.useState({action:o.action,location:o.location}),u=i.useCallback(c=>{n===!1?s(c):i.startTransition(()=>s(c))},[n]);return i.useLayoutEffect(()=>o.listen(u),[o,u]),i.createElement(Mt,{basename:e,children:t,location:l.location,navigationType:l.action,navigator:o,unstable_useTransitions:n})}var _e=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Be=i.forwardRef(function({onClick:t,discover:n="render",prefetch:r="none",relative:a,reloadDocument:o,replace:l,unstable_mask:s,state:u,target:c,to:d,preventScrollReset:f,viewTransition:m,unstable_defaultShouldRevalidate:g,...v},y){let{basename:p,navigator:h,unstable_useTransitions:R}=i.useContext(b),w=typeof d=="string"&&_e.test(d),C=be(d,p);d=C.to;let x=wt(d,{relative:a}),P=T(),D=null;if(s){let F=te(s,[],P.unstable_mask?P.unstable_mask.pathname:"/",!0);p!=="/"&&(F.pathname=F.pathname==="/"?p:S([p,F.pathname])),D=h.createHref(F)}let[I,B,Y]=er(r,v),Oe=cr(d,{replace:l,unstable_mask:s,state:u,target:c,preventScrollReset:f,relative:a,viewTransition:m,unstable_defaultShouldRevalidate:g,unstable_useTransitions:R});function Ae(F){t&&t(F),F.defaultPrevented||Oe(F)}let ue=!(C.isExternal||o),ce=i.createElement("a",{...v,...Y,href:(ue?D:void 0)||C.absoluteURL||x,onClick:ue?Ae:t,ref:or(y,B),target:c,"data-discover":!w&&n==="render"?"true":void 0});return I&&!w?i.createElement(i.Fragment,null,ce,i.createElement(tr,{page:x})):ce});Be.displayName="Link";var ir=i.forwardRef(function({"aria-current":t="page",caseSensitive:n=!1,className:r="",end:a=!1,style:o,to:l,viewTransition:s,children:u,...c},d){let f=W(l,{relative:c.relative}),m=T(),g=i.useContext(K),{navigator:v,basename:y}=i.useContext(b),p=g!=null&&pr(f)&&s===!0,h=v.encodeLocation?v.encodeLocation(f).pathname:f.pathname,R=m.pathname,w=g&&g.navigation&&g.navigation.location?g.navigation.location.pathname:null;n||(R=R.toLowerCase(),w=w?w.toLowerCase():null,h=h.toLowerCase()),w&&y&&(w=$(w,y)||w);const C=h!=="/"&&h.endsWith("/")?h.length-1:h.length;let x=R===h||!a&&R.startsWith(h)&&R.charAt(C)==="/",P=w!=null&&(w===h||!a&&w.startsWith(h)&&w.charAt(h.length)==="/"),D={isActive:x,isPending:P,isTransitioning:p},I=x?t:void 0,B;typeof r=="function"?B=r(D):B=[r,x?"active":null,P?"pending":null,p?"transitioning":null].filter(Boolean).join(" ");let Y=typeof o=="function"?o(D):o;return i.createElement(Be,{...c,"aria-current":I,className:B,ref:d,style:Y,to:l,viewTransition:s},typeof u=="function"?u(D):u)});ir.displayName="NavLink";var sr=i.forwardRef(({discover:e="render",fetcherKey:t,navigate:n,reloadDocument:r,replace:a,state:o,method:l=z,action:s,onSubmit:u,relative:c,preventScrollReset:d,viewTransition:f,unstable_defaultShouldRevalidate:m,...g},v)=>{let{unstable_useTransitions:y}=i.useContext(b),p=hr(),h=mr(s,{relative:c}),R=l.toLowerCase()==="get"?"get":"post",w=typeof s=="string"&&_e.test(s),C=x=>{if(u&&u(x),x.defaultPrevented)return;x.preventDefault();let P=x.nativeEvent.submitter,D=(P==null?void 0:P.getAttribute("formmethod"))||l,I=()=>p(P||x.currentTarget,{fetcherKey:t,method:D,navigate:n,replace:a,state:o,relative:c,preventScrollReset:d,viewTransition:f,unstable_defaultShouldRevalidate:m});y&&n!==!1?i.startTransition(()=>I()):I()};return i.createElement("form",{ref:v,method:R,action:h,onSubmit:r?u:C,...g,"data-discover":!w&&e==="render"?"true":void 0})});sr.displayName="Form";function ur(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Me(e){let t=i.useContext(_);return E(t,ur(e)),t}function cr(e,{target:t,replace:n,unstable_mask:r,state:a,preventScrollReset:o,relative:l,viewTransition:s,unstable_defaultShouldRevalidate:u,unstable_useTransitions:c}={}){let d=Et(),f=T(),m=W(e,{relative:l});return i.useCallback(g=>{if(Ht(g,t)){g.preventDefault();let v=n!==void 0?n:O(f)===O(m),y=()=>d(e,{replace:v,unstable_mask:r,state:a,preventScrollReset:o,relative:l,viewTransition:s,unstable_defaultShouldRevalidate:u});c?i.startTransition(()=>y()):y()}},[f,d,m,n,r,a,t,e,o,l,s,u,c])}var fr=0,dr=()=>`__${String(++fr)}__`;function hr(){let{router:e}=Me("useSubmit"),{basename:t}=i.useContext(b),n=Ft(),r=e.fetch,a=e.navigate;return i.useCallback(async(o,l={})=>{let{action:s,method:u,encType:c,formData:d,body:f}=Vt(o,t);if(l.navigate===!1){let m=l.fetcherKey||dr();await r(m,n,l.action||s,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:d,body:f,formMethod:l.method||u,formEncType:l.encType||c,flushSync:l.flushSync})}else await a(l.action||s,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:d,body:f,formMethod:l.method||u,formEncType:l.encType||c,replace:l.replace,state:l.state,fromRouteId:n,flushSync:l.flushSync,viewTransition:l.viewTransition})},[r,a,t,n])}function mr(e,{relative:t}={}){let{basename:n}=i.useContext(b),r=i.useContext(k);E(r,"useFormAction must be used inside a RouteContext");let[a]=r.matches.slice(-1),o={...W(e||".",{relative:t})},l=T();if(e==null){o.search=l.search;let s=new URLSearchParams(o.search),u=s.getAll("index");if(u.some(d=>d==="")){s.delete("index"),u.filter(f=>f).forEach(f=>s.append("index",f));let d=s.toString();o.search=d?`?${d}`:""}}return(!e||e===".")&&a.route.index&&(o.search=o.search?o.search.replace(/^\?/,"?index&"):"?index"),n!=="/"&&(o.pathname=o.pathname==="/"?n:S([n,o.pathname])),O(o)}function pr(e,{relative:t}={}){let n=i.useContext(Le);E(n!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=Me("useViewTransitionState"),a=W(e,{relative:t});if(!n.isTransitioning)return!1;let o=$(n.currentLocation.pathname,r)||n.currentLocation.pathname,l=$(n.nextLocation.pathname,r)||n.nextLocation.pathname;return V(a.pathname,l)!=null||V(a.pathname,o)!=null}export{Rr as B,Be as L,ir as N,vr as R,gr as a,T as b,Bt as c,Et as u};
@@ -4,12 +4,12 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>baxian</title>
7
- <script type="module" crossorigin src="/assets/index-CwgeJoE9.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-NBPoRVS-.js"></script>
8
8
  <link rel="modulepreload" crossorigin href="/assets/react-BG4Iuztk.js">
9
9
  <link rel="modulepreload" crossorigin href="/assets/xterm-D5X2JljJ.js">
10
- <link rel="modulepreload" crossorigin href="/assets/router-BVggVFlO.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/router-CApkciQz.js">
11
11
  <link rel="stylesheet" crossorigin href="/assets/xterm-CFbL2ovg.css">
12
- <link rel="stylesheet" crossorigin href="/assets/index-HZEqpYr7.css">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-xOQlV4Ki.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baxian",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "AI agent orchestration",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -1,4 +0,0 @@
1
- var ot=Object.defineProperty;var ct=(s,t,r)=>t in s?ot(s,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[t]=r;var _=(s,t,r)=>ct(s,typeof t!="symbol"?t+"":t,r);import{r as a,j as e,c as lt}from"./react-BG4Iuztk.js";import{x as dt,a as ut}from"./xterm-D5X2JljJ.js";import{L as ce,u as Ae,a as Ce,B as ht,N as Le,R as ft,b as oe}from"./router-BVggVFlO.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))o(n);new MutationObserver(n=>{for(const i of n)if(i.type==="childList")for(const l of i.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&o(l)}).observe(document,{childList:!0,subtree:!0});function r(n){const i={};return n.integrity&&(i.integrity=n.integrity),n.referrerPolicy&&(i.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?i.credentials="include":n.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(n){if(n.ep)return;n.ep=!0;const i=r(n);fetch(n.href,i)}})();const be="/api",Te="baxian.token",ke="baxian:unauthorized";function Ie(){try{return typeof localStorage<"u"?localStorage.getItem(Te):null}catch{return null}}function xt(s){try{localStorage.setItem(Te,s)}catch(t){console.error("Failed to save auth token to localStorage",t)}}function mt(){try{localStorage.removeItem(Te)}catch(s){console.error("Failed to clear auth token from localStorage",s)}}function le(s){const t=Ie();return{...s??{},...t?{Authorization:`Bearer ${t}`}:{}}}class me extends Error{constructor(t,r,o){super(r),this.status=t,this.details=o,this.name="ApiError"}}async function de(s){const t=await s.text();let r=t||`HTTP ${s.status}`,o;try{const n=JSON.parse(t);typeof n.error=="string"&&(r=n.error),Array.isArray(n.details)&&(o=n.details)}catch{}throw s.status===401&&typeof window<"u"&&window.dispatchEvent(new CustomEvent(ke)),new me(s.status,r,o)}async function se(s){const t=await fetch(`${be}${s}`,{headers:le()});return t.ok||await de(t),t.json()}async function pt(){const s=await fetch("/health");return s.ok||await de(s),s.json()}async function Z(s,t,r){const o=t!==void 0,n=await fetch(`${be}${s}`,{method:"POST",headers:o?le({"Content-Type":"application/json"}):le(),body:o?JSON.stringify(t):void 0,signal:r==null?void 0:r.signal});return n.ok||await de(n),n.json()}async function bt(s,t,r){const o=await fetch(`${be}${s}`,{method:"PATCH",headers:le({"Content-Type":"application/json"}),body:t?JSON.stringify(t):void 0,signal:r==null?void 0:r.signal});if(o.ok||await de(o),o.status===204)return;const n=await o.text();if(n)return JSON.parse(n)}async function _e(s){const t=await fetch(`${be}${s}`,{method:"DELETE",headers:le()});if(t.ok||await de(t),t.status===204)return;const r=await t.text();if(r)return JSON.parse(r)}const W=encodeURIComponent,O={agents:{list:()=>se("/agents"),get:s=>se(`/agents/${W(s)}`),stop:s=>_e(`/agents/${W(s)}/session`),probe:(s,t,r)=>Z("/agents/probe",{mode:s,host:t},r)},tasks:{list:s=>se(`/tasks${s?`?projectId=${W(s)}`:""}`),get:s=>se(`/tasks/${W(s)}`),create:s=>Z("/tasks",s),update:(s,t)=>bt(`/tasks/${W(s)}`,t),retry:s=>Z(`/tasks/${W(s)}/retry`),review:s=>Z(`/tasks/${W(s)}/review`)},projects:{list:()=>se("/projects"),get:s=>se(`/projects/${W(s)}`),create:s=>Z("/projects",s),addAgent:(s,t)=>Z(`/projects/${W(s)}/agents`,t),deleteAgent:(s,t)=>_e(`/projects/${W(s)}/agents/${W(t)}`),resumeAgent:(s,t)=>Z(`/projects/${W(s)}/agents/${W(t)}/resume`),bootstrap:s=>Z(`/projects/${W(s)}/bootstrap`)},config:{get:()=>se("/config")},health:{get:pt},server:{restart:()=>Z("/restart")}},Ye=a.createContext(null),gt={success:"border-[#bbf7d0] bg-[#f0fdf4] text-success",warn:"border-[#fde68a] bg-[#fef3c7] text-warn",error:"border-[#fecaca] bg-[#fef2f2] text-danger"},jt={success:"✅",warn:"⚠️",error:"❌"};let vt=1;function wt({children:s}){const[t,r]=a.useState([]),o=a.useCallback(i=>{r(l=>l.filter(f=>f.id!==i))},[]),n=a.useCallback(i=>{const l=vt++,f=i.durationMs??3e3;r(b=>[...b,{...i,id:l}]),setTimeout(()=>o(l),f)},[o]);return e.jsxs(Ye.Provider,{value:{show:n},children:[s,e.jsx("div",{className:"pointer-events-none fixed right-4 top-4 z-[60] flex flex-col gap-2",children:t.map(i=>e.jsx("div",{className:`pointer-events-auto w-80 rounded-lg border px-4 py-3 shadow-toast ${gt[i.kind]}`,role:"status",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{"aria-hidden":!0,className:"text-[14px]",children:jt[i.kind]}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-[13px] font-semibold",children:i.title}),i.body&&e.jsx("div",{className:"mt-1 whitespace-pre-line text-[12px] text-og-700",children:i.body})]}),e.jsx("button",{type:"button",onClick:()=>o(i.id),className:"text-current opacity-50 transition-opacity hover:opacity-100","aria-label":"Dismiss",children:"✕"})]})},i.id))})]})}function ue(){const s=a.useContext(Ye);if(!s)throw new Error("useToast must be inside <ToastProvider>");return s}const pe="baxian.pendingRestart",yt=500,Nt=3e4,Ze=a.createContext(null);function St(){try{const s=localStorage.getItem(pe);if(!s)return{count:0,baselineStartedAt:null};const t=JSON.parse(s);return{count:typeof t.count=="number"?t.count:0,baselineStartedAt:typeof t.baselineStartedAt=="string"?t.baselineStartedAt:null}}catch{return{count:0,baselineStartedAt:null}}}function kt(s){try{s.count<=0?localStorage.removeItem(pe):localStorage.setItem(pe,JSON.stringify(s))}catch{}}function Et({children:s}){const t=St(),[r,o]=a.useState(t.count),[n,i]=a.useState(t.baselineStartedAt),[l,f]=a.useState(t.count>0?"pending":"idle"),[b,p]=a.useState(),u=a.useRef(t.count),h=a.useRef(t.count>0?"pending":"idle"),m=a.useRef(0),x=a.useCallback(N=>{u.current=N,o(N)},[]),d=a.useCallback(N=>{o(A=>{const g=N(A);return u.current=g,g})},[]),v=a.useCallback(N=>{h.current=N,f(N)},[]);a.useEffect(()=>{kt({count:r,baselineStartedAt:n})},[r,n]),a.useEffect(()=>{let N=!1;(async()=>{try{const g=await O.health.get();if(N)return;i(R=>R!==null&&g.startedAt!==R?(x(0),v("idle"),null):R)}catch{}})();const A=g=>{if(g.key===pe){if(g.newValue===null){if(h.current==="restarting"&&m.current>0){x(m.current),i(null);return}x(0),i(null),h.current!=="restarting"&&v("idle");return}try{const R=JSON.parse(g.newValue);typeof R.count=="number"&&(h.current==="restarting"&&R.count>u.current&&(m.current+=R.count-u.current),x(R.count),h.current!=="restarting"&&v(R.count>0?"pending":"idle")),typeof R.baselineStartedAt=="string"?i(R.baselineStartedAt):R.baselineStartedAt===null&&i(null)}catch{}}};return window.addEventListener("storage",A),()=>{N=!0,window.removeEventListener("storage",A)}},[x,v]);const c=a.useRef(!1),T=a.useCallback(()=>{d(N=>N+1),h.current==="restarting"?m.current+=1:v("pending"),i(N=>(N!==null||c.current||(c.current=!0,(async()=>{try{const A=await O.health.get();i(g=>g??A.startedAt)}catch{}finally{c.current=!1}})()),N))},[v,d]),$=a.useCallback(async()=>{m.current=0,p(void 0),v("restarting");let N;try{N=(await O.health.get()).startedAt}catch(g){v("failed"),p(`获取重启前 startedAt 失败: ${g instanceof Error?g.message:String(g)}`);return}try{await O.server.restart()}catch(g){if(!(g instanceof me&&g.status===409)){v("failed"),p(`触发重启失败: ${g instanceof Error?g.message:String(g)}`);return}}const A=Date.now();for(;Date.now()-A<Nt;){await new Promise(g=>setTimeout(g,yt));try{const g=await O.health.get();if(g.startedAt!==N){const R=m.current;m.current=0,i(R>0?g.startedAt:null),x(R),v(R>0?"pending":"idle");return}}catch{}}v("failed"),p("重启超时(30s 未恢复)。请检查日志或手动 baxian start -c <path>")},[x,v]);return e.jsx(Ze.Provider,{value:{phase:l,count:r,error:b,flagDirty:T,triggerRestart:$},children:s})}function ge(){const s=a.useContext(Ze);if(!s)throw new Error("usePendingRestart must be used inside PendingRestartProvider");return s}const Rt=[500,1e3,2e3,4e3,8e3,15e3,3e4];class Xe{constructor(t){_(this,"attempts",0);_(this,"timer",null);_(this,"delaysMs");this.opts=t,this.delaysMs=t.delaysMs??Rt}schedule(){if(this.timer||!this.shouldReconnect())return;const t=this.delaysMs[Math.min(this.attempts,this.delaysMs.length-1)];this.attempts+=1,this.timer=setTimeout(()=>{this.timer=null,this.shouldReconnect()&&this.opts.reconnect()},t)}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null)}reset(){this.attempts=0}shouldReconnect(){return this.opts.shouldReconnect?this.opts.shouldReconnect():!0}}let Fe=0;function At(){Fe++;const s=Math.random().toString(36).slice(2,8);return`sub-${Date.now().toString(36)}-${Fe}-${s}`}function Ct(s){return Array.from(new TextEncoder().encode(s)).map(t=>t.toString(16).padStart(2,"0")).join("")}function Tt(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/stream`}const It=(s,t)=>t&&t.length>0?new WebSocket(s,t):new WebSocket(s);class Pt{constructor(t={}){_(this,"wsUrl");_(this,"wsFactory");_(this,"tokenProvider");_(this,"ws",null);_(this,"subs",new Map);_(this,"snapshotPending",new Set);_(this,"preSubscribeQueue",new Map);_(this,"outbox",[]);_(this,"reconnectScheduler");_(this,"explicitlyClosed",!1);this.wsUrl=t.wsUrl??Tt(),this.wsFactory=t.wsFactory??It,this.tokenProvider=t.tokenProvider??Ie,this.reconnectScheduler=new Xe({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.subs.size>0})}subscribe(t){const r=At(),o={subscriberId:r,agentId:t.agentId,mode:t.mode,onSnapshot:t.onSnapshot,onData:t.onData,onError:t.onError,onSessionGone:t.onSessionGone};return this.subs.set(r,o),this.snapshotPending.add(r),this.preSubscribeQueue.set(r,[]),this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",subscriberId:r,agentId:t.agentId,mode:t.mode}),{subscriberId:r,unsubscribe:()=>this.unsubscribe(r)}}send(t,r){if(this.subs.has(t)){if(this.snapshotPending.has(t)){this.outbox.push({op:"input",subscriberId:t,data:r});return}this.wsSendOrQueue({op:"input",subscriberId:t,data:r})}}resize(t,r,o){const n=this.subs.get(t);n&&(n.lastSize={cols:r,rows:o},!this.snapshotPending.has(t)&&this.wsSendOrQueue({op:"resize",subscriberId:t,cols:r,rows:o}))}ping(){this.wsSendOrQueue({op:"ping"})}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.subs.clear(),this.snapshotPending.clear(),this.preSubscribeQueue.clear(),this.outbox=[]}unsubscribe(t){this.subs.has(t)&&(this.subs.delete(t),this.snapshotPending.delete(t),this.preSubscribeQueue.delete(t),this.wsSendOrQueue({op:"unsubscribe",subscriberId:t}),this.subs.size===0&&this.teardownSocket())}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const t=this.tokenProvider(),r=t?[`baxian.token.${Ct(t)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,r)}catch(n){console.warn("[pane-stream] WebSocket constructor threw:",n),this.scheduleReconnect();return}this.ws=o,o.onopen=()=>{if(o!==this.ws)return;this.reconnectScheduler.reset();for(const i of this.subs.values()){this.snapshotPending.add(i.subscriberId),this.preSubscribeQueue.set(i.subscriberId,[]),i.snapshotSeq=void 0;try{o.send(JSON.stringify({op:"subscribe",subscriberId:i.subscriberId,agentId:i.agentId,mode:i.mode}))}catch(l){console.warn("[pane-stream] resubscribe send failed:",l)}}const n=this.outbox;this.outbox=[];for(const i of n)if(i.op!=="subscribe"){if("subscriberId"in i&&i.subscriberId){if(!this.subs.has(i.subscriberId))continue;if(this.snapshotPending.has(i.subscriberId)&&i.op!=="unsubscribe"){this.outbox.push(i);continue}}try{o.send(JSON.stringify(i))}catch(l){console.warn("[pane-stream] outbox flush failed:",l)}}},o.onmessage=n=>{if(o!==this.ws)return;let i;try{const l=typeof n.data=="string"?n.data:String(n.data);i=JSON.parse(l)}catch{return}this.handleMessage(i)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&this.subs.size!==0&&this.scheduleReconnect())},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}wsSendOrQueue(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(t));return}catch(r){console.warn("[pane-stream] send failed, will queue:",r)}this.outbox.push(t)}handleMessage(t){var r,o;switch(t.type){case"snapshot":this.handleSnapshot(t);break;case"subscribed":this.handleSubscribed(t);break;case"data":this.dispatch(t);break;case"session_gone":for(const n of[...this.subs.values()])n.agentId===t.agentId&&((r=n.onSessionGone)==null||r.call(n));break;case"error":{if(t.subscriberId){const n=this.subs.get(t.subscriberId);(o=n==null?void 0:n.onError)==null||o.call(n,{code:t.code,message:t.message})}else console.warn("[pane-stream] connection-level error:",t.code,t.message);break}}}handleSnapshot(t){const r=this.subs.get(t.subscriberId);r&&r.onSnapshot({cols:t.cols,rows:t.rows,data:t.data})}handleSubscribed(t){const r=this.subs.get(t.subscriberId);if(!r)return;r.snapshotSeq=t.snapshotSeq,r.lastSize||(r.lastSize={cols:t.cols,rows:t.rows}),this.snapshotPending.delete(t.subscriberId);const o=this.preSubscribeQueue.get(t.subscriberId);if(this.preSubscribeQueue.delete(t.subscriberId),o)for(const n of o)n.seq>t.snapshotSeq&&r.onData(n.data);r.mode==="full"&&r.lastSize&&this.wsSendOrQueue({op:"resize",subscriberId:r.subscriberId,cols:r.lastSize.cols,rows:r.lastSize.rows}),this.flushOutboxForSub(t.subscriberId)}flushOutboxForSub(t){if(this.outbox.length===0||!this.ws||this.ws.readyState!==WebSocket.OPEN)return;const r=[];for(const o of this.outbox)if("subscriberId"in o&&o.subscriberId===t&&o.op!=="subscribe")try{this.ws.send(JSON.stringify(o))}catch(n){console.warn("[pane-stream] flushOutboxForSub send failed:",n)}else r.push(o);this.outbox=r}dispatch(t){for(const r of this.subs.values())if(r.agentId===t.agentId)if(this.snapshotPending.has(r.subscriberId)){const o=this.preSubscribeQueue.get(r.subscriberId);o&&o.push({seq:t.seq,data:t.data})}else r.onData(t.data)}}let ve=null;function we(){return ve||(ve=new Pt),ve}function $t(s){const{agentId:t,mode:r}=s,o=a.useRef(null),n=a.useRef({onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone});n.current={onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone},a.useEffect(()=>{const b=we().subscribe({agentId:t,mode:r,onSnapshot:p=>n.current.onSnapshot(p),onData:p=>n.current.onData(p),onError:p=>{var u,h;return(h=(u=n.current).onError)==null?void 0:h.call(u,p)},onSessionGone:()=>{var p,u;return(u=(p=n.current).onSessionGone)==null?void 0:u.call(p)}});return o.current=b.subscriberId,()=>{o.current=null,b.unsubscribe()}},[t,r]);const i=a.useCallback(f=>{const b=o.current;b&&we().send(b,f)},[]),l=a.useCallback((f,b)=>{const p=o.current;p&&we().resize(p,f,b)},[]);return{send:i,resize:l}}const Dt=18,Ot=250,Lt=256*1024,Me="#fdfdfd",_t='ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',Ft={background:Me,foreground:"#474c55",cursor:"#1348dc",cursorAccent:Me,selectionBackground:"#eaf0ff",black:"#0d0d0f",red:"#b91c1c",green:"#15803d",yellow:"#b45309",blue:"#1348dc",magenta:"#9333ea",cyan:"#0e7490",white:"#474c55",brightBlack:"#878e9b",brightRed:"#dc2626",brightGreen:"#16a34a",brightYellow:"#d97706",brightBlue:"#3080ff",brightMagenta:"#a855f7",brightCyan:"#0891b2",brightWhite:"#0d0d0f"},Mt=/\x1b\[(?:\?[\d;]*c|>[\d;]*c|\??\d+;\d+R|\d+n)/g;function zt(s){return s.replace(Mt,"")}function Ee({agentId:s,mode:t,interactive:r=!1,maxLines:o,className:n,autoFocus:i=!0,deferFullUntilFocus:l=!1}){const f=a.useRef(null),b=a.useRef(null),p=a.useRef(null),u=a.useRef(!1),h=a.useRef(""),m=a.useRef([]),x=a.useRef(0),d=a.useRef(null),v=a.useRef(null),c=a.useRef(Promise.resolve()),T=a.useRef(0),[$,N]=a.useState(null),[A,g]=a.useState(!1),R=`${s}\0${t}\0${l?"1":"0"}`,[S,P]=a.useState({key:R,active:!1}),k=S.key===R&&S.active,D=t==="full"&&l,F=D&&!k?"preview":t,I=r&&F==="full",z=(j,L)=>L.length===0?Promise.resolve():new Promise(C=>{try{j.write(L,()=>C())}catch(w){console.warn("[pane-terminal] write failed:",w),C()}}),Q=(j,L)=>{c.current=c.current.then(async()=>{const C=b.current;if(!(!C||L!==T.current))try{await j(C)}catch(w){console.warn("[pane-terminal] terminal task failed:",w)}}).catch(C=>{console.warn("[pane-terminal] write chain failed:",C)})},U=(j,L)=>{Q(C=>z(C,j),L)},J=()=>{d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),v.current!==null&&(clearTimeout(v.current),v.current=null)},Y=()=>{J(),m.current=[],x.current=0},H=()=>{J();const j=m.current;j.length!==0&&(m.current=[],x.current=0,U(j.join(""),T.current))},V=j=>{if(j.length!==0){if(m.current.push(j),x.current+=j.length,x.current>=Lt){H();return}d.current===null&&(d.current=requestAnimationFrame(H)),v.current===null&&(v.current=setTimeout(H,Ot))}},{send:K,resize:te}=$t({agentId:s,mode:F,onSnapshot:({cols:j,rows:L,data:C})=>{if(b.current)try{const y=T.current+1;T.current=y,Y(),Q(async q=>{q.reset(),j>0&&L>0&&q.resize(j,L),await z(q,C)},y)}catch(y){console.warn("[pane-terminal] snapshot write failed:",y)}},onData:j=>{V(j)},onError:j=>N(`${j.code}: ${j.message}`),onSessionGone:()=>g(!0)});a.useEffect(()=>{N(null),g(!1)},[s,F]),a.useEffect(()=>{h.current=""},[R]),a.useEffect(()=>{if(F!=="full")return;const j=h.current;j.length!==0&&(h.current="",K(j))},[K,F]);const G=a.useCallback(()=>{!r||!D||k||(u.current=!0,P({key:R,active:!0}))},[R,k,r,D]);a.useEffect(()=>{const j=f.current;if(!j)return;let L=!1;const C=new dt.Terminal({cursorBlink:r,disableStdin:!r,theme:Ft,fontFamily:_t,fontSize:13,lineHeight:1.4,scrollback:F==="full"?5e3:1e3}),w=new ut.FitAddon;if(C.loadAddon(w),C.open(j),b.current=C,p.current=w,r&&(i||u.current)){u.current=!1;try{C.focus()}catch{}}r&&C.onData(ae=>{const ie=zt(ae);if(ie.length!==0){if(D&&!k){h.current+=ie,G();return}K(ie)}});const y=()=>j.clientWidth>0&&j.clientHeight>0,q=(ae=!1)=>{if(!y())return!1;const ie=C.cols,it=C.rows;try{w.fit()}catch{return!1}return C.cols>0&&C.rows>0&&(ae||C.cols!==ie||C.rows!==it)&&te(C.cols,C.rows),!0};let B=null,ee=null,he=null,at=0;const De=()=>{B||(B=new ResizeObserver(()=>{ee&&clearTimeout(ee),ee=setTimeout(()=>{ee=null,q()},100)}),B.observe(j))},Oe=()=>{he=requestAnimationFrame(()=>{if(he=null,!(L||!I)){if(q(!0)){De();return}if(at++<5){Oe();return}De()}})};return Oe(),()=>{L=!0,he!==null&&cancelAnimationFrame(he),d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),v.current!==null&&(clearTimeout(v.current),v.current=null),T.current++,m.current=[],x.current=0,c.current=Promise.resolve(),ee&&clearTimeout(ee),B==null||B.disconnect(),b.current=null,p.current=null;try{C.dispose()}catch(ae){console.warn("[pane-terminal] dispose failed:",ae)}}},[G,s,i,I,k,r,K,D,F,te]);const E=()=>{var j;if(r){G();try{(j=b.current)==null||j.focus()}catch{}}},M=o&&o>0?{maxHeight:`${o*Dt}px`}:void 0;return e.jsxs("div",{className:n??"flex flex-col h-full w-full min-h-0 bg-[#fdfdfd]",children:[($||A)&&e.jsx("div",{className:"border-b border-[#fecaca] bg-[#fef2f2] px-3 py-1 font-mono text-[11px] text-danger",children:A?"session ended":$}),e.jsx("div",{ref:f,className:"flex-1 min-h-0 overflow-hidden px-2 py-1.5",style:M,onMouseDown:E})]})}const Bt={unknown:{label:"Unknown",cls:"pill pill-idle"},idle:{label:"Idle",cls:"pill pill-idle"},pending:{label:"Pending user",cls:"pill pill-warn"},working:{label:"Working",cls:"pill pill-live"},waiting:{label:"Waiting",cls:"pill pill-review"},error:{label:"Error",cls:"pill pill-warn"}},Qt={present:{label:"Session present",cls:"pill pill-live"},absent:{label:"No session",cls:"pill pill-idle"},unreachable:{label:"Host unreachable",cls:"pill pill-warn"},unknown:{label:"Session unknown",cls:"pill pill-idle"}};function Ut({agent:s,projectId:t,role:r,onDeleted:o,pendingRestart:n=!1,terminalLoading:i=!1,showTaskBinding:l=!0,terminalMode:f="activity-preview"}){var G,E,M,j,L,C,w;const[b,p]=a.useState(!1),[u,h]=a.useState(null),{show:m}=ue(),{flagDirty:x}=ge(),[d,v]=a.useState(!1),[c,T]=a.useState(null),[$,N]=a.useState(!1),[A,g]=a.useState(!1),[R,S]=a.useState(!1),P=(G=s.binding)==null?void 0:G.taskId,k=((E=s.binding)==null?void 0:E.status)==="awaiting_human",D=!!((M=s.binding)!=null&&M.creationToken)&&!((j=s.binding)!=null&&j.paneId)&&!k&&s.reason!=="PENDING_HUMAN",F=D?{label:"Starting",cls:"pill pill-review"}:Bt[s.runtimeStatus],I=D?{label:"Starting session",cls:"pill pill-review"}:Qt[s.tmuxSessionStatus],z=f==="activity-preview"&&!D&&(s.runtimeStatus==="working"||s.runtimeStatus==="pending"),Q=f==="embedded-full",U=i||n||D,J=i?"Agent 状态加载中":n?"重启 baxian server 后可用":"Agent 正在启动",Y=async()=>{p(!0),h(null);try{await O.agents.stop(s.id)}catch(y){h(y instanceof Error?y.message:String(y))}finally{p(!1)}},H=async()=>{if(P&&window.confirm(`请 QA 对 task ${P} 重审?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`)){N(!0);try{const y=await O.tasks.review(P);m({kind:"success",title:`已派 QA 重审 (round ${y.reviewRound})`})}catch(y){m({kind:"error",title:"Review 派发失败",body:y instanceof Error?y.message:String(y)})}finally{N(!1)}}},V=async()=>{S(!0);try{(await O.projects.bootstrap(t)).ok?m({kind:"success",title:"Bootstrap retry 完成",body:"agent 状态将在下一次刷新生效。"}):m({kind:"warn",title:"Bootstrap retry 仍失败",body:"看一下红色错误卡的最新原因,按提示修复后再试。"})}catch(y){m({kind:"error",title:"Bootstrap retry 失败",body:y instanceof Error?y.message:String(y)})}finally{S(!1)}},K=async()=>{if(window.confirm(`确认 Resume Agent ${s.id}?baxian 会清除 awaiting_human 状态,agent 重新可派遣。`)){g(!0);try{const y=await O.projects.resumeAgent(t,s.id);m({kind:"success",title:`Agent ${s.id} 已 Resume`,body:y.releasedBinding?"原任务已释放,agent 可接新任务。":"保留绑定(原任务仍 active)。"})}catch(y){m({kind:"error",title:"Resume 失败",body:y instanceof Error?y.message:String(y)})}finally{g(!1)}}},te=async()=>{if(window.confirm(`确认删除 Agent ${s.id}?此操作不可撤销`)){v(!0),T(null);try{const y=await O.projects.deleteAgent(t,s.id);y!=null&&y.restartRequired&&x();const q=(y==null?void 0:y.removed)??[s.id];if(q.length>1){const B=q.filter(ee=>ee!==s.id).join(", ");m({kind:"warn",title:`已删除 Agent ${s.id}`,body:`配对的 QA Agent ${B} 也被一并移除。`})}else m({kind:"success",title:`Agent ${s.id} 已删除`});o==null||o()}catch(y){T(y instanceof Error?y.message:String(y))}finally{v(!1)}}};return e.jsxs("div",{className:"card flex h-full min-w-0 flex-col p-4",children:[e.jsxs("div",{className:"mb-3 flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx("span",{className:"font-mono text-[11px] font-medium uppercase tracking-[0.05em] text-og-500",children:r}),e.jsx("span",{className:"font-display text-[14px] font-semibold text-og-1000",children:s.id})]}),e.jsxs("div",{className:"flex flex-wrap justify-end gap-1",children:[k&&e.jsx("span",{className:"pill pill-warn",title:((L=s.binding)==null?void 0:L.awaitingReason)??"需人工处理",children:"Held"}),e.jsx("span",{className:F.cls,children:F.label}),e.jsx("span",{className:I.cls,children:I.label}),s.stale&&e.jsx("span",{className:"pill pill-warn",title:s.observedAt?`Last observed at ${s.observedAt}`:void 0,children:"Stale"})]})]}),D&&e.jsx("div",{className:"mb-2 rounded-md border border-accent-soft bg-accent-soft/40 px-2.5 py-2 text-[12px] text-accent",children:"Agent 正在启动,终端可用后会自动刷新。"}),k&&e.jsxs("div",{className:"mb-2 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-2.5 py-2 text-[12px] text-warn",children:[e.jsx("span",{className:"font-mono",children:(C=s.binding)==null?void 0:C.awaitingPhase}),((w=s.binding)==null?void 0:w.awaitingReason)&&e.jsxs("span",{children:[" · ",s.binding.awaitingReason]})]}),!D&&s.runtimeStatus==="pending"&&e.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-2.5 py-2 text-[12px] text-warn",children:[e.jsx("div",{className:"font-medium",children:"等待人工介入"}),e.jsxs("div",{children:["Agent 正在等待人工输入。请打开 ",e.jsx(ce,{to:`/terminal/${s.id}`,className:"text-accent hover:text-accent-hover underline",children:"Terminal"})," 处理; 处理完后状态会随下一次观测刷新。"]})]}),s.latestError&&e.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-[#fecaca] bg-[#fef2f2] px-2.5 py-2 text-[12px] text-danger",children:[e.jsx("div",{className:"break-words font-medium",children:s.latestError.message}),e.jsxs("div",{className:"font-mono text-[11px] opacity-80",children:[s.latestError.reason," · ",s.latestError.occurredAt]})]}),s.latestBootstrapError&&e.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-[#fecaca] bg-[#fef2f2] px-2.5 py-2 text-[12px] text-danger",children:[e.jsx("div",{className:"break-words font-medium",children:s.latestBootstrapError.message}),s.latestBootstrapError.recommendation&&e.jsx("div",{className:"break-words",children:s.latestBootstrapError.recommendation}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"truncate font-mono text-[11px] opacity-80",children:[s.latestBootstrapError.reason," · ",s.latestBootstrapError.occurredAt]}),e.jsx("button",{type:"button",onClick:V,disabled:R,className:"btn-secondary shrink-0 !border-[#fecaca] !text-danger hover:!bg-[#fef2f2] hover:!border-danger hover:!text-danger",children:R?"Retrying…":"Retry bootstrap"})]})]}),l&&P&&e.jsxs("div",{className:"mb-2 text-[12px] text-og-500",children:["Task: ",e.jsx("span",{className:"font-mono text-og-700",children:P})]}),z&&e.jsx("div",{className:"mb-2 overflow-hidden rounded-md border border-hairline bg-surface",children:e.jsx(Ee,{agentId:s.id,mode:"preview",maxLines:6,interactive:!1})}),Q&&e.jsx("div",{className:"mb-2 mt-3 h-80 min-h-0 overflow-hidden rounded-md border border-hairline bg-surface",children:U?e.jsx("div",{className:"flex h-full items-center justify-center px-3 text-[13px] text-og-500",children:J}):e.jsx(Ee,{agentId:s.id,mode:"full",interactive:!0,autoFocus:!1,deferFullUntilFocus:!0})}),n&&e.jsx("div",{className:"mb-2 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-2.5 py-1.5 text-[12px] text-warn",children:"⚠️ 重启 baxian server 后生效"}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[U?e.jsx("span",{className:"cursor-not-allowed text-[13px] text-og-400",title:J,children:"Terminal"}):e.jsx(ce,{to:`/terminal/${s.id}`,className:"btn-secondary",children:"Terminal"}),!n&&s.runtimeStatus==="working"&&e.jsx("button",{onClick:Y,disabled:b,className:"btn-ghost !text-danger hover:!bg-[#fef2f2]",children:b?"Stopping…":"Stop"}),u&&e.jsx("span",{className:"text-[12px] text-danger",children:u}),k&&e.jsx("button",{type:"button",onClick:K,disabled:A,title:"清除 awaiting_human 状态,让 agent 重新可派遣",className:"btn-ghost !text-warn hover:!bg-[#fef3c7]/60",children:A?"Resuming…":"Resume"}),!n&&P&&r==="dev"&&e.jsx("button",{type:"button",onClick:H,disabled:$,title:`让 QA 立即对 task ${P} 跑一轮 review(需要该 task 已有 PR)`,className:"btn-ghost !text-accent hover:!bg-accent-soft",children:$?"Dispatching…":"Request QA review"}),e.jsx("button",{type:"button",onClick:te,disabled:d,className:"btn-ghost ml-auto !text-danger hover:!bg-[#fef2f2]","aria-label":`Delete agent ${s.id}`,children:d?"删除中…":"🗑"}),c&&e.jsx("span",{className:"text-[12px] text-danger",children:c})]})]})}const qt=new Set(["in_progress","review","fixing","approved"]);function et({group:s,projectId:t,agentsById:r,agentsLoaded:o,agentsError:n=!1,tasks:i,onDeleted:l,terminalMode:f="activity-preview"}){const b=s.find(x=>x.role==="dev")??s[0],p=s.find(x=>x.role==="qa"),u=i.filter(x=>Wt(x,b==null?void 0:b.id,p==null?void 0:p.id)),h=`Agent group ${s.map(x=>x.id).join(" / ")}`,m=f==="embedded-full"?s.length<=1?"lg:grid-cols-1":s.length===2?"lg:grid-cols-2":s.length===3?"lg:grid-cols-3":"lg:grid-cols-4":"sm:grid-cols-2";return e.jsxs("div",{role:"group","aria-label":h,className:"min-w-0",children:[u.length>0?e.jsx("div",{className:"card mb-2 max-h-28 overflow-y-auto divide-y divide-hairline",children:u.map(x=>{const d=x.phase==="spec"?x.specReviewRound??0:x.reviewRound;return e.jsxs(ce,{to:`/task/${x.id}`,className:"flex items-center gap-3 px-3 py-2 text-[13px] transition-colors hover:bg-og-50/60",children:[e.jsxs("div",{className:"min-w-0 flex-1 flex items-center gap-2",children:[e.jsx("span",{className:"shrink-0 font-mono text-[11px] text-og-500",children:x.id}),e.jsx("span",{className:"truncate text-og-1000",children:x.title})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[e.jsx("span",{className:"pill",children:x.status}),e.jsxs("span",{"aria-label":`Round ${d}`,className:"pill pill-review",children:["Round ",d]})]})]},x.id)})}):e.jsx("div",{className:"mb-2 rounded-lg border border-dashed border-og-100 bg-surface px-3 py-2 text-[13px] text-og-400","aria-label":`${h} no active task`,children:"暂无任务"}),e.jsx("div",{className:`grid grid-cols-1 ${m} gap-4`,children:s.map(x=>{const d=r.get(x.id),v=d??{id:x.id,projectId:t,runtimeStatus:"unknown",tmuxSessionStatus:"unknown",stale:!0};return e.jsx(Ut,{agent:v,projectId:t,role:x.role,pendingRestart:o&&!d,terminalLoading:!o&&!d&&!n,onDeleted:l,showTaskBinding:!1,terminalMode:f},x.id)})})]})}function Wt(s,t,r){return!(!t||!qt.has(s.status)||!(s.agentId===t||s.preferredAgentId===t)||r&&s.qaAgentId&&s.qaAgentId!==r)}const Gt={sm:"max-w-md",md:"max-w-lg",lg:"max-w-2xl"},ze='input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])';function je({open:s,onClose:t,title:r,children:o,size:n="md"}){const i=a.useRef(null),l=a.useRef(null),f=a.useRef(t);return a.useEffect(()=>{f.current=t},[t]),a.useEffect(()=>{if(!s)return;l.current=document.activeElement;const b=h=>{if(h.key==="Escape"){f.current();return}if(h.key!=="Tab")return;const m=i.current;if(!m)return;const x=Array.from(m.querySelectorAll(ze)).filter(T=>T.offsetParent!==null||T===document.activeElement);if(x.length===0){h.preventDefault();return}const d=x[0],v=x[x.length-1],c=document.activeElement;h.shiftKey&&(c===d||!m.contains(c))?(h.preventDefault(),v.focus()):!h.shiftKey&&(c===v||!m.contains(c))&&(h.preventDefault(),d.focus())};document.addEventListener("keydown",b);const p=document.body.style.overflow;document.body.style.overflow="hidden";const u=i.current;if(u){const h=u.querySelector(ze);h==null||h.focus()}return()=>{var h,m;document.removeEventListener("keydown",b),document.body.style.overflow=p,(m=(h=l.current)==null?void 0:h.focus)==null||m.call(h)}},[s]),s?e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-og-1000/45 px-3 sm:px-4",onClick:()=>f.current(),role:"presentation",children:e.jsxs("div",{ref:i,className:`w-full ${Gt[n]} max-h-[90vh] overflow-auto rounded-lg border border-og-100 bg-surface shadow-modal`,onClick:b=>b.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":r,children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-hairline px-6 py-4",children:[e.jsx("h2",{className:"font-display text-[16px] font-semibold tracking-tight text-og-1000",children:r}),e.jsx("button",{type:"button",onClick:()=>f.current(),className:"text-og-400 transition-colors hover:text-og-800","aria-label":"Close",children:"✕"})]}),e.jsx("div",{className:"px-6 py-5",children:o})]})}):null}const Ht=/^[a-z][a-z0-9-]{1,31}$/,Jt=/^[A-Za-z0-9_-][A-Za-z0-9._-]*\/[A-Za-z0-9_-][A-Za-z0-9._-]*$/,Be="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",ye="mb-1.5 block text-[12px] font-medium text-og-700",Qe="mt-1 text-[12px] text-danger";function Vt({open:s,onClose:t,onCreated:r}){const[o,n]=a.useState(""),[i,l]=a.useState(""),[f,b]=a.useState(null),[p,u]=a.useState(!1),[h,m]=a.useState(null),[x,d]=a.useState({}),[v,c]=a.useState(new Set),T=a.useRef(0),{show:$}=ue(),{flagDirty:N}=ge();a.useEffect(()=>{if(!s)return;T.current+=1;const S=T.current;n(""),l(""),b(null),m(null),d({}),c(new Set),O.config.get().then(P=>{S===T.current&&c(new Set(P.project.map(k=>k.id)))}).catch(()=>{})},[s]);const A=()=>{p||t()},g=()=>{const S={};return o?Ht.test(o)?v.has(o)&&(S.id="该 id 已被占用"):S.id="小写字母开头,只含 a-z 0-9 -,长度 2-32":S.id="必填",i?Jt.test(i)||(S.repo="需为 owner/repo 形式"):S.repo="必填",d(S),Object.keys(S).length===0},R=async S=>{if(S.preventDefault(),!!g()){u(!0),m(null);try{const P=await O.projects.create({id:o,repo:i,merge:f});P.restartRequired&&N(),$({kind:"success",title:`项目 ${P.project.id} 已创建`}),r(P.project.id)}catch(P){m(P instanceof Error?P.message:String(P))}finally{u(!1)}}};return e.jsx(je,{open:s,onClose:A,title:"新建项目",size:"md",children:e.jsxs("form",{onSubmit:R,className:"space-y-4",children:[h&&e.jsx("div",{className:"rounded-md border border-[#fecaca] bg-[#fef2f2] px-3 py-2 text-[13px] text-danger",children:h}),e.jsxs("div",{children:[e.jsx("label",{className:ye,htmlFor:"proj-id",children:"项目 ID"}),e.jsx("input",{id:"proj-id",type:"text",value:o,onChange:S=>n(S.target.value),className:Be,placeholder:"kongkong",disabled:p}),x.id&&e.jsx("div",{className:Qe,children:x.id})]}),e.jsxs("div",{children:[e.jsx("label",{className:ye,htmlFor:"proj-repo",children:"GitHub 仓库"}),e.jsx("input",{id:"proj-repo",type:"text",value:i,onChange:S=>l(S.target.value),className:Be,placeholder:"rockdai/baxian",disabled:p}),x.repo&&e.jsx("div",{className:Qe,children:x.repo})]}),e.jsxs("div",{children:[e.jsx("span",{className:ye,children:"合并策略"}),e.jsxs("label",{className:"mb-1 flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"merge",checked:f===null,onChange:()=>b(null),disabled:p,className:"h-3.5 w-3.5 accent-[#1348dc]"}),e.jsx("span",{className:"text-[13px] text-og-800",children:"人类合并(默认)"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"merge",checked:f==="auto",onChange:()=>b("auto"),disabled:p,className:"h-3.5 w-3.5 accent-[#1348dc]"}),e.jsx("span",{className:"text-[13px] text-og-800",children:"QA Approve 后自动合并"})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-hairline pt-4",children:[e.jsx("button",{type:"button",onClick:A,disabled:p,className:"btn-secondary",children:"取消"}),e.jsx("button",{type:"submit",disabled:p,className:"btn-primary",children:p?"创建中…":"创建"})]})]})})}const Ue=/^[a-z][a-z0-9-]{1,31}$/,Kt=500,ne="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",X="mb-1.5 block text-[12px] font-medium text-og-700",qe="mt-1 text-[12px] text-danger",Ne="mt-1 text-[12px] text-og-500",re="h-3.5 w-3.5 accent-[#1348dc]",We={id:"",role:"dev",pairWith:"",mode:"local",hostname:"",user:"",runtime:"",workdir:"",yolo:!0,model:"",addDirs:""};function tt({open:s,onClose:t,projectId:r,onCreated:o}){var G;const[n,i]=a.useState(We),[l,f]=a.useState(null),[b,p]=a.useState(new Set),[u,h]=a.useState(null),[m,x]=a.useState(!1),[d,v]=a.useState(!1),[c,T]=a.useState(null),$=a.useRef(null),N=a.useRef(null),A=a.useRef(0),{show:g}=ue(),{flagDirty:R}=ge();a.useEffect(()=>{if(!s)return;A.current+=1;const E=A.current;i(We),f(null),p(new Set),h(null),x(!1),T(null),O.config.get().then(M=>{if(E!==A.current)return;const j=M.project.find(C=>C.id===r)??null;f(j);const L=new Set;M.project.forEach(C=>C.agent.forEach(w=>w.forEach(y=>L.add(y.id)))),p(L)}).catch(()=>{})},[s,r]);const S=()=>{d||t()},P=a.useCallback(()=>{$.current&&$.current.abort();const E=new AbortController;$.current=E,x(!0),T(null);const M=n.mode==="remote"?{hostname:n.hostname,user:n.user||void 0}:void 0;O.agents.probe(n.mode,M,{signal:E.signal}).then(j=>{E.signal.aborted||(h(j),T(null))}).catch(j=>{E.signal.aborted||(h(null),T(j instanceof Error?j.message:String(j)))}).finally(()=>{$.current===E&&x(!1)})},[n.mode,n.hostname,n.user]);a.useEffect(()=>{if(s&&(h(null),$.current&&$.current.abort(),!(n.mode==="remote"&&!n.hostname)))return N.current&&clearTimeout(N.current),N.current=setTimeout(P,Kt),()=>{N.current&&clearTimeout(N.current)}},[s,n.mode,n.hostname,n.user,P]),a.useEffect(()=>{s||$.current&&$.current.abort()},[s]),a.useEffect(()=>()=>{$.current&&$.current.abort(),N.current&&clearTimeout(N.current)},[]);const k=(l==null?void 0:l.agent.filter(E=>E.length===1&&E[0].role==="dev").map(E=>E[0]))??[],D=k.length>0,F=Ue.test(n.id)&&!b.has(n.id),I=n.mode==="local"||n.mode==="remote"&&n.hostname.length>0,z=n.runtime!==""&&(n.runtime==="claude-code"?!!(u!=null&&u.runtimes["claude-code"].ok):!!(u!=null&&u.runtimes.codex.ok)),Q=!!(u!=null&&u.tmux.ok),U=n.mode==="local"||!!((G=u==null?void 0:u.ssh)!=null&&G.ok),J=n.role==="dev"||n.role==="qa"&&n.pairWith!=="",Y=!d&&F&&I&&J&&z&&Q&&U,H=async E=>{if(E.preventDefault(),!!Y){v(!0),T(null);try{const M=n.addDirs.split(`
2
- `).map(C=>C.trim()).filter(C=>C.length>0),j={id:n.id,role:n.role,runtime:n.runtime,mode:n.mode,...n.mode==="remote"?{host:{hostname:n.hostname,...n.user?{user:n.user}:{}}}:{},...n.workdir?{workdir:n.workdir}:{},yolo:n.yolo,...n.model.trim()?{model:n.model.trim()}:{},...M.length>0?{addDirs:M}:{},...n.role==="qa"?{pairWith:n.pairWith}:{}},L=await O.projects.addAgent(r,j);L.restartRequired&&R(),g({kind:"success",title:`Agent ${L.agent.id} 已添加到 ${r}`}),o(),t()}catch(M){T(M instanceof Error?M.message:String(M))}finally{v(!1)}}},V=({rt:E})=>{if(n.mode==="remote"&&!n.hostname)return e.jsx("span",{className:"ml-2 text-[12px] text-og-400",children:"(请先填写 hostname)"});if(m)return e.jsx("span",{className:"ml-2 text-[12px] text-og-400",children:"…探测中"});if(!u)return e.jsx("span",{className:"ml-2 text-[12px] text-og-400",children:"?"});const j=u.runtimes[E];return j.ok?e.jsxs("span",{className:"ml-2 text-[12px] text-success",children:["✓ ",j.path??""]}):e.jsxs("span",{className:"ml-2 text-[12px] text-danger",title:j.message,children:["⨯ ",j.message]})},K=()=>n.mode==="remote"&&!n.hostname?null:m?e.jsx("div",{className:"text-[12px] text-og-400",children:"tmux: …探测中"}):u?u.tmux.ok?e.jsxs("div",{className:"text-[12px] text-success",children:["tmux: ✓ ",u.tmux.path??""]}):e.jsxs("div",{className:"text-[12px] text-danger",children:["tmux: ⨯ ",u.tmux.message]}):null,te=()=>n.mode!=="remote"||!n.hostname||!(u!=null&&u.ssh)?null:u.ssh.ok?e.jsxs("div",{className:"text-[12px] text-success",children:["SSH: ✓ ",u.ssh.message]}):e.jsxs("div",{className:"text-[12px] text-danger",children:["SSH: ⨯ ",u.ssh.message]});return e.jsx(je,{open:s,onClose:S,title:`添加 Agent 到 ${r}`,size:"lg",children:e.jsxs("form",{onSubmit:H,className:"space-y-4",children:[c&&e.jsx("div",{className:"rounded-md border border-[#fecaca] bg-[#fef2f2] px-3 py-2 text-[13px] text-danger",children:c}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"agent-id",children:"Agent ID"}),e.jsx("input",{id:"agent-id",type:"text",value:n.id,onChange:E=>i({...n,id:E.target.value}),className:ne,placeholder:"kk-cc",disabled:d}),n.id&&!Ue.test(n.id)&&e.jsx("div",{className:qe,children:"小写字母开头,只含 a-z 0-9 -,长度 2-32"}),n.id&&b.has(n.id)&&e.jsx("div",{className:qe,children:"该 id 已被占用(全局唯一)"})]}),e.jsxs("div",{children:[e.jsx("span",{className:X,children:"角色"}),e.jsxs("label",{className:"mr-4 inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"role",checked:n.role==="dev",className:re,onChange:()=>i({...n,role:"dev",pairWith:""}),disabled:d}),e.jsx("span",{className:"text-[13px] text-og-800",children:"Dev"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",title:D?"":"请先创建一个 Dev Agent",children:[e.jsx("input",{type:"radio",name:"role",checked:n.role==="qa",className:re,onChange:()=>i({...n,role:"qa"}),disabled:d||!D}),e.jsx("span",{className:`text-[13px] ${D?"text-og-800":"text-og-400"}`,children:"QA"})]})]}),n.role==="qa"&&e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"pair-with",children:"配对 Dev Agent"}),e.jsxs("select",{id:"pair-with",value:n.pairWith,onChange:E=>i({...n,pairWith:E.target.value}),className:ne,disabled:d,children:[e.jsx("option",{value:"",children:"请选择"}),k.map(E=>e.jsxs("option",{value:E.id,children:[E.id," (dev, ",E.mode,")"]},E.id))]})]}),e.jsxs("div",{children:[e.jsx("span",{className:X,children:"运行模式"}),e.jsxs("label",{className:"mr-4 inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"mode",checked:n.mode==="local",className:re,onChange:()=>i({...n,mode:"local",hostname:"",user:""}),disabled:d}),e.jsx("span",{className:"text-[13px] text-og-800",children:"本机"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"mode",checked:n.mode==="remote",className:re,onChange:()=>i({...n,mode:"remote"}),disabled:d}),e.jsx("span",{className:"text-[13px] text-og-800",children:"远程 (SSH)"})]})]}),n.mode==="remote"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"hostname",children:"Hostname"}),e.jsx("input",{id:"hostname",type:"text",value:n.hostname,onChange:E=>i({...n,hostname:E.target.value}),className:ne,placeholder:"macmini-2026",disabled:d}),e.jsx("div",{className:Ne,children:"端口/私钥/跳板机请配 ~/.ssh/config"})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"user",children:"User(可选)"}),e.jsx("input",{id:"user",type:"text",value:n.user,onChange:E=>i({...n,user:E.target.value}),className:ne,placeholder:"留空则读 ~/.ssh/config 的 User",disabled:d})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-1.5 flex items-center justify-between",children:[e.jsx("span",{className:"text-[12px] font-medium text-og-700",children:"运行时"}),e.jsx("button",{type:"button",onClick:P,className:"text-[12px] text-accent transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",disabled:d||m||n.mode==="remote"&&!n.hostname,children:"↻ 重新探测"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"runtime",checked:n.runtime==="claude-code",className:re,onChange:()=>i({...n,runtime:"claude-code"}),disabled:d||(u?!u.runtimes["claude-code"].ok:!1)}),e.jsx("span",{className:"text-[13px] text-og-800",children:"Claude Code"}),e.jsx(V,{rt:"claude-code"})]}),e.jsxs("label",{className:"mt-1 flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"runtime",checked:n.runtime==="codex",className:re,onChange:()=>i({...n,runtime:"codex"}),disabled:d||(u?!u.runtimes.codex.ok:!1)}),e.jsx("span",{className:"text-[13px] text-og-800",children:"Codex"}),e.jsx(V,{rt:"codex"})]}),e.jsx("div",{className:"mt-2",children:e.jsx(K,{})}),e.jsx("div",{children:e.jsx(te,{})})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"workdir",children:"Workdir(可选)"}),e.jsx("input",{id:"workdir",type:"text",value:n.workdir,onChange:E=>i({...n,workdir:E.target.value}),className:ne,placeholder:"留空时自动 clone 到 ~/.baxian/repos/<owner>/<repo>",disabled:d})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"model",children:"Model(可选)"}),e.jsx("input",{id:"model",type:"text",value:n.model,onChange:E=>i({...n,model:E.target.value}),className:ne,placeholder:n.runtime==="codex"?"例: o3 / gpt-4o(留空走 default)":"例: sonnet / opus / claude-sonnet-4-6(留空走 default)",disabled:d}),e.jsx("div",{className:Ne,children:"透传到 launch 命令的 --model 参数;留空跟随 CLI 默认。"})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"addDirs",children:"Additional Dirs(可选)"}),e.jsx("textarea",{id:"addDirs",value:n.addDirs,onChange:E=>i({...n,addDirs:E.target.value}),className:`${ne} font-mono text-[12px]`,rows:3,placeholder:`每行一个绝对路径,例:
3
- /Users/me/shared-libs
4
- /Users/me/extra-repo`,disabled:d}),e.jsx("div",{className:Ne,children:"透传到 --add-dir。当前 YOLO 模式下不影响权限拦截,主要用于让 CLI 把额外目录纳入工作根。"})]}),e.jsx("div",{className:"rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-3 py-2.5",children:e.jsxs("label",{className:"flex cursor-pointer items-start gap-2",children:[e.jsx("input",{type:"checkbox",className:"mt-1 h-3.5 w-3.5 accent-[#1348dc]",checked:n.yolo,onChange:E=>i({...n,yolo:E.target.checked}),disabled:d}),e.jsxs("div",{className:"text-[13px] text-og-800",children:[e.jsx("div",{className:"font-medium",children:"YOLO 模式(推荐开启)"}),e.jsxs("div",{className:"mt-1 text-[12px] text-warn",children:["Agent 自主执行所有命令、文件改动,无需逐条确认。开启后体验更顺滑, 但",e.jsx("strong",{className:"font-semibold",children:"请确认在受控环境(容器、隔离 worktree)中运行"}),"。"]})]})]})}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-hairline pt-4",children:[e.jsx("button",{type:"button",onClick:S,disabled:d,className:"btn-secondary",children:"取消"}),e.jsx("button",{type:"submit",disabled:!Y,className:"btn-primary",children:d?"添加中…":"添加 Agent"})]})]})})}const Ge=200,He=16e3,fe="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",xe="mb-1.5 block text-[12px] font-medium text-og-700",Je="mt-1 text-right text-[12px] text-og-400";function Pe(s){const t=s.mode==="edit",r=Ae(),{show:o}=ue(),n=t?s.task.projectId:s.projectId,i=t?s.task.title:"",l=t?s.task.description:"",f=t?s.task.preferredAgentId:"",[b,p]=a.useState([]),[u,h]=a.useState([]),[m,x]=a.useState(n??""),[d,v]=a.useState(f),[c,T]=a.useState(i),[$,N]=a.useState(l),[A,g]=a.useState(!1),[R,S]=a.useState(null),P=a.useRef(0);a.useEffect(()=>{if(!s.open)return;P.current+=1;const w=P.current;p([]),h([]),x(n??""),v(f),T(i),N(l),S(null),g(!1),Promise.all([O.projects.list(),O.agents.list()]).then(([y,q])=>{w===P.current&&(p(y),h(q))}).catch(y=>{w===P.current&&S(y instanceof Error?y.message:String(y))})},[s.open,n,i,l,f]);const k=a.useMemo(()=>b.find(w=>w.id===m)??null,[b,m]),D=a.useMemo(()=>k?k.agent.flat().filter(w=>w.role==="dev"):[],[k]),F=a.useMemo(()=>new Set(u.map(w=>w.id)),[u]),I=a.useMemo(()=>D.filter(w=>F.has(w.id)),[D,F]),z=a.useMemo(()=>D.filter(w=>!F.has(w.id)),[D,F]);a.useEffect(()=>{if(!t){if(I.length===0){d!==""&&v("");return}I.find(w=>w.id===d)||v(I[0].id)}},[I,d,t]);const Q=!t||I.find(w=>w.id===d),U=t&&!Q&&!!d,J=U&&z.some(w=>w.id===d),Y=J?`当前 dev "${d}" 在 baxian.json 中存在但 runtime 未加载,可能是手动编辑过配置文件;重启 server 可拉起`:U?`当前 dev "${d}" 不在 runtime(可能已从 project 配置移除);保存可能失败,请确认或选择新 dev`:!m||I.length>0?null:z.length>0?"baxian.json 里有 dev agent 但 runtime 未加载(可能是手动编辑过配置);重启 server 后生效":"请先为项目添加 dev agent",H=c.trim(),V=$.trim(),K=I.length>0||U,G=!!m&&K&&!!d&&H.length>0&&V.length>0&&!A,E=()=>{A||s.onClose()},M=async w=>{var y,q;if(w.preventDefault(),!!G){g(!0),S(null);try{if(s.mode==="edit"){const B=await O.tasks.update(s.task.id,{title:H,description:V,preferredAgentId:d});o({kind:"success",title:"任务已更新"}),(y=s.onUpdated)==null||y.call(s,B),s.onClose()}else{const B=await O.tasks.create({projectId:m,title:H,description:V,preferredAgentId:d});o({kind:"success",title:"任务已创建"}),(q=s.onCreated)==null||q.call(s,B),s.onClose(),r(`/task/${B.id}`)}}catch(B){S(B instanceof Error?B.message:String(B))}finally{g(!1)}}},j=t?"编辑 Task":"新建 Task",L=t?A?"保存中…":"保存":A?"创建中…":"创建",C=!t&&!n;return e.jsx(je,{open:s.open,onClose:E,title:j,size:"md",children:e.jsxs("form",{onSubmit:M,className:"space-y-4",children:[R&&e.jsx("div",{className:"rounded-md border border-[#fecaca] bg-[#fef2f2] px-3 py-2 text-[13px] text-danger",children:R}),C&&e.jsxs("div",{children:[e.jsx("label",{className:xe,htmlFor:"task-project",children:"Project"}),e.jsxs("select",{id:"task-project",value:m,onChange:w=>x(w.target.value),className:fe,disabled:A,required:!0,children:[e.jsx("option",{value:"",disabled:!0,children:"选择项目"}),b.map(w=>e.jsx("option",{value:w.id,children:w.id},w.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:xe,htmlFor:"task-dev",children:"Dev Agent"}),e.jsxs("select",{id:"task-dev",value:d,onChange:w=>v(w.target.value),className:fe,disabled:A||I.length===0&&!U||I.length===1&&I[0].id===d&&!U,required:!0,children:[I.length===0&&!U&&e.jsx("option",{value:"",disabled:!0,children:"无可用 dev"}),U&&e.jsxs("option",{value:d,children:[d," ",J?"(待重启)":"(不在 runtime)"]}),I.map(w=>e.jsx("option",{value:w.id,children:w.id},w.id))]}),Y&&e.jsx("div",{className:"mt-1 text-[12px] text-warn",children:Y})]}),e.jsxs("div",{children:[e.jsx("label",{className:xe,htmlFor:"task-title",children:"Title"}),e.jsx("input",{id:"task-title",type:"text",value:c,onChange:w=>T(w.target.value),maxLength:Ge,className:fe,placeholder:"一句话描述要做什么",disabled:A,required:!0}),e.jsxs("div",{className:Je,children:[c.length," / ",Ge]})]}),e.jsxs("div",{children:[e.jsx("label",{className:xe,htmlFor:"task-description",children:"Description"}),e.jsx("textarea",{id:"task-description",value:$,onChange:w=>N(w.target.value),maxLength:He,rows:8,className:`${fe} font-mono text-[12px]`,placeholder:"详细描述任务,支持 markdown",disabled:A,required:!0}),e.jsxs("div",{className:Je,children:[$.length," / ",He]})]}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-hairline pt-4",children:[e.jsx("button",{type:"button",onClick:E,disabled:A,className:"btn-secondary",children:"取消"}),e.jsx("button",{type:"submit",disabled:!G,className:"btn-primary",children:L})]})]})})}function Yt(s){return Array.from(new TextEncoder().encode(s)).map(t=>t.toString(16).padStart(2,"0")).join("")}function Zt(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/realtime`}const Xt=(s,t)=>t&&t.length>0?new WebSocket(s,t):new WebSocket(s);class es{constructor(t={}){_(this,"wsUrl");_(this,"wsFactory");_(this,"tokenProvider");_(this,"ws",null);_(this,"topics",new Map);_(this,"cache",new Map);_(this,"outbox",[]);_(this,"reconnectScheduler");_(this,"explicitlyClosed",!1);this.wsUrl=t.wsUrl??Zt(),this.wsFactory=t.wsFactory??Xt,this.tokenProvider=t.tokenProvider??Ie,this.reconnectScheduler=new Xe({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.topics.size>0})}subscribe(t,r,o){let n=this.topics.get(t);const i=!n;return n||(n={data:new Set,error:new Set},this.topics.set(t,n)),n.data.add(r),o&&n.error.add(o),i?(this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",topic:t})):this.cache.has(t)&&queueMicrotask(()=>{var l;(l=this.topics.get(t))!=null&&l.data.has(r)&&this.cache.has(t)&&r(this.cache.get(t))}),()=>this.unsubscribe(t,r,o)}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.topics.clear(),this.cache.clear(),this.outbox=[]}unsubscribe(t,r,o){const n=this.topics.get(t);n&&(n.data.delete(r),o&&n.error.delete(o),n.data.size===0&&n.error.size===0&&(this.topics.delete(t),this.cache.delete(t),this.wsSendOrQueue({op:"unsubscribe",topic:t}),this.topics.size===0&&this.teardownSocket()))}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const t=this.tokenProvider(),r=t?[`baxian.token.${Yt(t)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,r)}catch(i){console.warn("[events-client] WebSocket constructor threw:",i),this.broadcastConnectionError({code:"connection_failed",message:i instanceof Error?i.message:"WebSocket constructor threw"}),this.scheduleReconnect();return}this.ws=o;let n=!1;o.onopen=()=>{if(o!==this.ws)return;n=!0,this.reconnectScheduler.reset();for(const l of this.topics.keys())try{o.send(JSON.stringify({op:"subscribe",topic:l}))}catch(f){console.warn("[events-client] resubscribe send failed:",f)}const i=this.outbox;this.outbox=[];for(const l of i)if(!(l.op==="subscribe"||l.op==="unsubscribe"))try{o.send(JSON.stringify(l))}catch(f){console.warn("[events-client] outbox flush failed:",f)}},o.onmessage=i=>{if(o!==this.ws)return;let l;try{const f=typeof i.data=="string"?i.data:String(i.data);l=JSON.parse(f)}catch{return}this.handleMessage(l)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&(n||this.broadcastConnectionError({code:"connection_failed",message:"WebSocket failed to connect (auth, network, or proxy issue)"}),this.topics.size!==0&&this.scheduleReconnect()))},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}broadcastConnectionError(t){for(const r of this.topics.values())for(const o of[...r.error])try{o(t)}catch(n){console.error("[events-client] error handler threw on connection error:",n)}}wsSendOrQueue(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(t));return}catch(r){console.warn("[events-client] send failed, will queue:",r)}this.outbox.push(t)}handleMessage(t){switch(t.type){case"data":{const r=this.topics.get(t.topic);if(this.cache.set(t.topic,t.data),!r)return;for(const o of[...r.data])try{o(t.data)}catch(n){console.error(`[events-client] handler threw on ${t.topic}:`,n)}break}case"error":{const r={code:t.code,message:t.message};if(t.topic){const o=this.topics.get(t.topic);if(o)for(const n of[...o.error])try{n(r)}catch(i){console.error(`[events-client] error handler threw on ${t.topic}:`,i)}}else console.warn("[events-client] connection-level error:",t.code,t.message);break}}}}let Se=null;function $e(){return Se||(Se=new es),Se}function st(){const[s,t]=a.useState(null),[r,o]=a.useState(!1),[n,i]=a.useState(null);return a.useEffect(()=>$e().subscribe("agents",f=>{i(null),t(f),o(!0)},f=>i(f)),[]),{data:s,loaded:r,error:n}}function ts(s){const[t,r]=a.useState(null),[o,n]=a.useState(!1),[i,l]=a.useState(null);return a.useEffect(()=>(r(null),n(!1),l(null),$e().subscribe(`task:${s}`,b=>{l(null),r(b),n(!0)},b=>l(b))),[s]),{data:t,loaded:o,error:i}}function ss(s){const[t,r]=a.useState(null),[o,n]=a.useState(!1),[i,l]=a.useState(null);return a.useEffect(()=>{if(!s){r(null),n(!1),l(null);return}r(null),n(!1),l(null);let f=!1,b=!1,p=!1;const u=$e().subscribe(`project-tasks:${s}`,h=>{f||(b=!0,l(null),r(h),n(!0))},h=>{f||(l(h),!(b||p)&&(p=!0,O.tasks.list(s).then(m=>{f||b||(r(m),n(!0))},m=>{console.warn(`[useProjectTasks] REST fallback failed for ${s}:`,m)})))});return()=>{f=!0,u()}},[s]),{data:t,loaded:o,error:i}}function ns(){const[s,t]=a.useState([]),[r,o]=a.useState([]),[n,i]=a.useState(!1),[l,f]=a.useState(null),[b,p]=a.useState(null),[u,h]=a.useState(!1),[m,x]=a.useState(!1),[d,v]=a.useState({kind:"closed"}),c=a.useRef(0),{data:T,loaded:$,error:N}=st(),A=(N==null?void 0:N.message)??null,g=new Map((T??[]).map(k=>[k.id,k])),R=l??A??b,S=async()=>{const k=++c.current;try{const D=await O.projects.list();if(k!==c.current)return;t(D),f(null)}catch(D){if(k!==c.current)return;f(D instanceof Error?D.message:String(D))}finally{k===c.current&&i(!0)}},P=async()=>{try{const k=await O.tasks.list();o(k),p(null)}catch(k){p(k instanceof Error?k.message:String(k))}};return a.useEffect(()=>{S(),P()},[]),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-6 flex flex-wrap items-end justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"font-display text-2xl font-semibold tracking-tight text-og-1000",children:"Dashboard"}),e.jsx("p",{className:"mt-0.5 text-[13px] text-og-500",children:"Active agent workspaces across all configured repos."})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("button",{onClick:()=>h(!0),className:"btn-primary",children:"+ 新建项目"}),e.jsx("button",{onClick:()=>x(!0),disabled:s.length===0,"aria-describedby":s.length===0?"create-task-hint":void 0,className:"btn-secondary",children:"+ 新建 Task"}),s.length===0&&e.jsx("span",{id:"create-task-hint",className:"self-center text-[12px] text-og-500",children:"请先创建项目"})]})]}),R&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",R]}),n&&s.length===0&&!l&&e.jsx("div",{className:"rounded-lg border border-dashed border-og-100 bg-surface py-12 text-center text-[13px] text-og-500",children:'还没有项目。点击右上角"+ 新建项目"开始。'}),s.map(k=>e.jsxs("div",{className:"mb-10",children:[e.jsxs("div",{className:"mb-3 flex flex-wrap items-baseline gap-x-3 gap-y-1",children:[e.jsx("h2",{className:"font-display text-[17px] font-semibold tracking-tight text-og-1000",children:k.id}),e.jsx("span",{className:"min-w-0 break-words font-mono text-[12px] text-og-500",children:k.repo}),e.jsx(ce,{to:`/project/${k.id}`,className:"ml-auto text-[13px] text-accent hover:text-accent-hover",children:"Details →"})]}),k.agent.flat().length===0?e.jsx("div",{className:"rounded-lg border border-dashed border-og-100 bg-surface py-6 text-center text-[13px] text-og-500",children:"还没有 Agent。进入 Details 添加。"}):e.jsx("div",{className:"grid grid-cols-1 gap-3 xl:grid-cols-2",children:k.agent.map((D,F)=>e.jsx(et,{group:D,projectId:k.id,agentsById:g,agentsLoaded:$,agentsError:!!N,tasks:r.filter(I=>I.projectId===k.id),onDeleted:()=>{S(),P()}},D.map(I=>I.id).join(":")||F))})]},k.id)),e.jsx(Vt,{open:u,onClose:()=>h(!1),onCreated:k=>{h(!1),S(),v({kind:"asking",projectId:k})}}),e.jsx(je,{open:d.kind==="asking",onClose:()=>v({kind:"closed"}),title:"项目已创建",size:"sm",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-[13px] text-og-700",children:"现在添加第一个 Agent,还是稍后再加?"}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:()=>v({kind:"closed"}),className:"btn-secondary",children:"稍后再加"}),e.jsx("button",{type:"button",onClick:()=>{d.kind==="asking"&&v({kind:"addingAgent",projectId:d.projectId})},className:"btn-primary",children:"继续添加 Agent"})]})]})}),d.kind==="addingAgent"&&e.jsx(tt,{open:!0,projectId:d.projectId,onClose:()=>v({kind:"closed"}),onCreated:()=>{S()}}),e.jsx(Pe,{open:m,onClose:()=>x(!1),onCreated:()=>{P()}})]})}function nt({tasks:s}){const t=Ae();return s.length===0?e.jsx("div",{className:"rounded-lg border border-dashed border-og-100 bg-surface px-4 py-8 text-center text-[13px] text-og-400",children:"No tasks"}):e.jsx("div",{className:"overflow-hidden rounded-lg border border-hairline bg-surface",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-[13px]",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-hairline bg-og-50/40 text-left font-mono text-[11px] uppercase tracking-[0.05em] text-og-500",children:[e.jsx("th",{className:"px-4 py-2 font-medium",children:"ID"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Title"}),e.jsx("th",{className:"hidden px-4 py-2 font-medium sm:table-cell",children:"Agent"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Status"}),e.jsx("th",{className:"hidden px-4 py-2 font-medium sm:table-cell",children:"Round"})]})}),e.jsx("tbody",{children:s.map(r=>e.jsxs("tr",{className:"cursor-pointer border-t border-hairline transition-colors hover:bg-og-50/40",onClick:()=>t(`/task/${r.id}`),children:[e.jsx("td",{className:"whitespace-nowrap px-4 py-2.5 font-mono text-[12px]",children:e.jsx(ce,{to:`/task/${r.id}`,className:"text-accent hover:text-accent-hover",onClick:o=>o.stopPropagation(),children:r.id})}),e.jsx("td",{className:"px-4 py-2.5 break-words text-og-1000",children:r.title}),e.jsx("td",{className:"hidden whitespace-nowrap px-4 py-2.5 font-mono text-[12px] sm:table-cell",children:r.agentId?e.jsx("span",{className:"text-og-700",children:r.agentId}):r.preferredAgentId?e.jsx("span",{className:"italic text-og-500",children:r.preferredAgentId}):e.jsx("span",{className:"text-og-400",children:"—"})}),e.jsxs("td",{className:"whitespace-nowrap px-4 py-2.5",children:[e.jsx("span",{className:"pill",children:r.status}),r.phase==="spec"&&e.jsx("span",{className:"ml-1 pill pill-review",children:"spec"})]}),e.jsx("td",{className:"hidden whitespace-nowrap px-4 py-2.5 text-[12px] text-og-500 sm:table-cell",children:r.phase==="spec"?r.specReviewRound??0:r.reviewRound})]},r.id))})]})})})}function rs(){const{id:s}=Ce(),[t,r]=a.useState(null),[o,n]=a.useState(null),[i,l]=a.useState(!1),[f,b]=a.useState(!1),p=a.useRef(0),{data:u,loaded:h,error:m}=st(),{data:x,error:d}=ss(s),v=(m==null?void 0:m.message)??null,c=(d==null?void 0:d.message)??null,T=x??[],$=new Map((u??[]).map(g=>[g.id,g])),N=o??v??c,A=a.useCallback(async g=>{const R=++p.current;try{const S=await O.projects.get(g);if(R!==p.current)return;r(S),n(null)}catch(S){if(R!==p.current)return;n(S instanceof Error?S.message:String(S))}},[]);return a.useEffect(()=>{s&&(r(null),n(null),A(s))},[s,A]),t?e.jsxs("div",{children:[N&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",N]}),e.jsxs("div",{className:"mb-6",children:[e.jsx("h1",{className:"break-words font-display text-2xl font-semibold tracking-tight text-og-1000",children:t.id}),e.jsx("p",{className:"mt-1 break-words font-mono text-[12px] text-og-500",children:t.repo})]}),e.jsxs("div",{className:"mb-3 flex flex-wrap items-baseline justify-between gap-2 border-t border-hairline pt-6",children:[e.jsx("h2",{className:"font-display text-[12px] font-semibold uppercase tracking-[0.06em] text-og-500",children:"Agents"}),e.jsx("button",{onClick:()=>l(!0),className:"btn-ghost",children:"+ 添加 Agent"})]}),t.agent.flat().length===0?e.jsx("div",{className:"mb-8 rounded-lg border border-dashed border-og-100 bg-surface py-6 text-center text-[13px] text-og-500",children:"还没有 Agent,点击右上角添加。"}):e.jsx("div",{className:"mb-8 space-y-5",children:t.agent.map((g,R)=>e.jsx(et,{group:g,projectId:t.id,agentsById:$,agentsLoaded:h,agentsError:!!m,tasks:T,onDeleted:()=>{A(t.id)},terminalMode:"embedded-full"},g.map(S=>S.id).join(":")||R))}),e.jsxs("div",{className:"mb-3 flex flex-wrap items-baseline justify-between gap-2 border-t border-hairline pt-6",children:[e.jsx("h2",{className:"font-display text-[12px] font-semibold uppercase tracking-[0.06em] text-og-500",children:"Tasks"}),e.jsx("button",{onClick:()=>b(!0),className:"btn-ghost",children:"+ 新建 Task"})]}),e.jsx(nt,{tasks:T}),e.jsx(tt,{open:i,projectId:t.id,onClose:()=>l(!1),onCreated:()=>{A(t.id)}}),e.jsx(Pe,{open:f,projectId:t.id,onClose:()=>b(!1)})]}):o?e.jsxs("div",{className:"text-[13px] text-danger",children:["Error: ",o]}):e.jsx("div",{className:"text-[13px] text-og-500",children:"Loading…"})}function as(){const{agentId:s}=Ce();return s?e.jsxs("div",{className:"flex min-h-0 flex-1 flex-col overflow-hidden rounded-lg border border-hairline bg-surface",children:[e.jsxs("div",{className:"flex h-8 flex-none select-none items-center gap-3 border-b border-hairline bg-page px-3 font-mono text-[11px] text-og-500",children:[e.jsx("span",{"aria-hidden":!0,className:"block h-1.5 w-1.5 rounded-full bg-success"}),e.jsx("span",{className:"text-og-700",children:s})]}),e.jsx("div",{className:"min-h-0 flex-1",children:e.jsx(Ee,{agentId:s,mode:"full",interactive:!0})})]}):e.jsx("div",{className:"text-[13px] text-danger",children:"No agent specified"})}function is(){const[s,t]=a.useState([]),[r,o]=a.useState(null);return a.useEffect(()=>{let n=!1;return(async()=>{try{const i=await O.tasks.list();n||t(i)}catch(i){n||o(i instanceof Error?i.message:String(i))}})(),()=>{n=!0}},[]),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-6",children:[e.jsx("h1",{className:"font-display text-2xl font-semibold tracking-tight text-og-1000",children:"Tasks"}),e.jsx("p",{className:"mt-0.5 text-[13px] text-og-500",children:"Every task across all projects."})]}),r&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",r]}),e.jsx(nt,{tasks:s})]})}const rt=new Set(["merged","failed","max_rounds","cancelled"]),Ve=rt,os={pending:"pill",in_progress:"pill pill-live",review:"pill pill-review",fixing:"pill pill-warn",approved:"pill pill-live",merged:"pill pill-live",failed:"pill pill-warn",max_rounds:"pill pill-warn",cancelled:"pill"};function cs(){const{id:s}=Ce(),t=Ae(),{show:r}=ue(),[o,n]=a.useState(!1),[i,l]=a.useState(!1),[f,b]=a.useState(!1),[p,u]=a.useState(!1),[h,m]=a.useState(null),{data:x,loaded:d,error:v}=ts(s??""),c=h??x,T=(v==null?void 0:v.message)??null;a.useEffect(()=>{m(null)},[s]),a.useEffect(()=>{h&&x&&x.updatedAt>=h.updatedAt&&m(null)},[h,x]);const $=I=>{m(I)};if(!s)return e.jsx("div",{className:"text-[13px] text-danger",children:"Task ID required"});if(T&&!c)return e.jsxs("div",{className:"text-[13px] text-danger",children:["Error: ",T]});if(d&&!c)return e.jsxs("div",{className:"text-[13px] text-danger",children:["Task not found: ",s]});if(!c)return e.jsx("div",{className:"text-[13px] text-og-500",children:"Loading…"});const N=c.status==="pending",A=c.status==="pending"||c.status==="in_progress",g=Ve.has(c.status)&&!!c.preferredAgentId,R=!!c.prNumber,S=c.preferredAgentId==="",P=c.status==="approved"&&c.prNumber!==void 0,k=async()=>{if(confirm(`确定取消 task ${c.id}?`)){l(!0);try{const I=await O.tasks.update(c.id,{status:"cancelled"});$(I),r({kind:"success",title:"任务已取消"})}catch(I){r({kind:"error",title:"取消失败",body:I instanceof Error?I.message:String(I)})}finally{l(!1)}}},D=async()=>{const z=rt.has(c.status)?`task ${c.id} 已是 ${c.status} 状态。手动请 QA 重审会再跑一轮 review,但状态机不会把 QA 结果带回主流程。继续?`:`请 QA 重审 task ${c.id}?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`;if(confirm(z)){u(!0);try{const Q=await O.tasks.review(c.id);$(Q),r({kind:"success",title:`已派 QA 重审 (round ${Q.reviewRound})`})}catch(Q){r({kind:"error",title:"Review 派发失败",body:Q instanceof Error?Q.message:String(Q)})}finally{u(!1)}}},F=async()=>{const I=c.status==="merged"?`task ${c.id} 已 merged。Retry 会用同样的标题/描述新建一个 task 从头跑,确定继续?`:`Retry task ${c.id}?这会新建一个 task 从头开始,旧 task 保留为历史。`;if(confirm(I)){b(!0);try{const z=await O.tasks.retry(c.id);r({kind:"success",title:`已新建 task ${z.id}`}),t(`/task/${z.id}`)}catch(z){r({kind:"error",title:"Retry 失败",body:z instanceof Error?z.message:String(z)})}finally{b(!1)}}};return e.jsxs("div",{className:"mx-auto max-w-4xl",children:[T&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",T]}),S&&e.jsx("div",{className:"mb-4 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-3 py-2.5 text-[12px] text-warn",children:c.status==="pending"?e.jsxs(e.Fragment,{children:["This task has no preferred dev (legacy). Click ",e.jsx("b",{className:"font-semibold",children:"Edit"})," to assign one."]}):e.jsxs(e.Fragment,{children:["This is a legacy task with no preferred dev (read-only in status ",e.jsx("b",{className:"font-semibold",children:c.status}),")."]})}),e.jsxs("div",{className:"mb-2 flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:"font-mono text-[13px] text-og-500",children:c.id}),e.jsx("span",{className:os[c.status],children:c.status}),c.phase==="spec"&&e.jsx("span",{className:"pill pill-review",children:"spec phase"}),e.jsxs("span",{className:"text-[12px] text-og-500",children:["created ",c.createdAt]}),e.jsxs("span",{className:"text-[12px] text-og-500",children:["updated ",c.updatedAt]})]}),e.jsx("h1",{className:"mb-5 break-words font-display text-2xl font-semibold tracking-tight text-og-1000",children:c.title}),P&&e.jsxs("div",{className:"mb-5 rounded-lg border border-[#bbf7d0] bg-[#f0fdf4] p-4 text-[13px] text-success",children:[e.jsx("div",{className:"font-semibold",children:"QA approved · awaiting PR merge"}),e.jsx("div",{className:"mt-1 text-og-700",children:"Dev keeps the task reserved while it checks whether all human or agent feedback has been handled."}),c.prUrl&&e.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"btn-secondary mt-3 !border-[#bbf7d0] !text-success hover:!bg-[#dcfce7] hover:!border-success",children:["Open PR #",c.prNumber]})]}),e.jsx("pre",{className:"card mb-6 whitespace-pre-wrap p-4 text-[13px] text-og-800",children:c.description}),e.jsxs("div",{className:"card mb-6 grid grid-cols-1 gap-x-6 gap-y-2 p-4 text-[13px] md:grid-cols-2",children:[e.jsxs("div",{className:"text-og-500",children:["Project: ",e.jsx("span",{className:"font-mono text-og-800",children:c.projectId})]}),e.jsxs("div",{className:"text-og-500",children:["Dev: ",e.jsx("span",{className:"font-mono text-og-800",children:c.agentId||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["Preferred: ",e.jsx("span",{className:"font-mono text-og-800",children:c.preferredAgentId||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["QA: ",e.jsx("span",{className:"font-mono text-og-800",children:c.qaAgentId||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["PR:"," ",c.prNumber?c.prUrl?e.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"text-accent hover:text-accent-hover",children:["#",c.prNumber]}):e.jsxs("span",{className:"font-mono text-og-800",children:["#",c.prNumber]}):e.jsx("span",{className:"text-og-400",children:"—"})]}),e.jsxs("div",{className:"text-og-500",children:["Branch: ",e.jsx("span",{className:"font-mono text-og-800",children:c.branch||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["Round: ",e.jsx("span",{className:"font-mono text-og-800",children:c.reviewRound}),c.specReviewRound!==void 0&&c.specReviewRound>0&&e.jsxs("span",{className:"ml-2 text-[12px] text-accent",children:["spec: ",c.specReviewRound]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",disabled:!N,onClick:()=>n(!0),className:"btn-secondary",children:"Edit"}),e.jsx("button",{type:"button",disabled:!A||i,onClick:k,className:"btn-secondary !border-[#fecaca] !text-danger hover:!bg-[#fef2f2] hover:!border-danger",children:i?"Cancelling…":"Cancel"}),e.jsx("button",{type:"button",disabled:!g||f,onClick:F,title:Ve.has(c.status)?S?"Legacy task has no preferred dev to retry against":"新建一个 task 从头跑,丢弃当前 worktree/branch":`Cannot retry in status ${c.status}`,className:"btn-secondary",children:f?"Retrying…":"Retry"}),e.jsx("button",{type:"button",disabled:!R||p,onClick:D,title:c.prNumber?"让 QA agent 立即开始新一轮 review(reviewRound +1)":"该 task 还没有 PR,无法派 review",className:"btn-secondary !border-accent-soft !text-accent hover:!bg-accent-soft hover:!border-accent",children:p?"Dispatching…":"Request QA review"})]}),e.jsx(Pe,{mode:"edit",open:o,onClose:()=>n(!1),task:c,onUpdated:$})]})}function ls(){const[s,t]=a.useState(!1);return e.jsx("button",{type:"button",onClick:()=>t(r=>!r),"aria-label":s?"切换为 logo 图片":"切换为文字 baxian",className:"flex items-center font-display text-[15px] font-semibold tracking-tight text-og-1000",children:s?e.jsx("span",{children:"baxian"}):e.jsx("img",{src:"/baxian-logo.png",alt:"baxian",width:24,height:24,className:"block h-6 w-6"})})}function ds(){const{phase:s,count:t,error:r,triggerRestart:o}=ge();return s==="idle"?null:s==="failed"?e.jsxs("div",{className:"flex items-center justify-between border-b border-[#fecaca] bg-[#fef2f2] px-4 py-2",children:[e.jsxs("div",{className:"text-[13px] text-danger",children:["❌ 重启失败:",r]}),e.jsx("button",{onClick:()=>{o()},className:"btn-ghost !text-danger hover:!bg-[#fef2f2]",children:"重试"})]}):s==="restarting"?e.jsx("div",{className:"border-b border-accent-soft bg-accent-soft/40 px-4 py-2 text-[13px] text-accent",children:"🔄 重启中…"}):e.jsxs("div",{className:"flex items-center justify-between border-b border-[#fde68a] bg-[#fef3c7]/60 px-4 py-2",children:[e.jsxs("div",{className:"text-[13px] text-warn",children:["⚠️ 有 ",t," 项配置变更待重启 baxian server 才生效"]}),e.jsx("button",{onClick:()=>{o()},className:"btn-secondary !border-warn !text-warn hover:!bg-[#fef3c7] hover:!border-warn hover:!text-warn",children:"现在重启"})]})}const Ke=({isActive:s})=>["rounded-md px-2.5 py-1 text-[13px] transition-colors",s?"bg-og-50 text-og-1000":"text-og-500 hover:bg-og-50 hover:text-og-800"].join(" ");function us(){return e.jsx(ht,{children:e.jsxs("div",{className:"flex h-screen flex-col bg-page",children:[e.jsxs("nav",{className:"flex h-12 flex-none items-center gap-4 border-b border-hairline bg-surface px-6",children:[e.jsx(ls,{}),e.jsx(Le,{to:"/",end:!0,className:Ke,children:"Dashboard"}),e.jsx(Le,{to:"/tasks",className:Ke,children:"Tasks"})]}),e.jsx(ds,{}),e.jsx("main",{className:"flex min-h-0 flex-1 flex-col overflow-y-auto p-6",children:e.jsxs(ft,{children:[e.jsx(oe,{path:"/",element:e.jsx(ns,{})}),e.jsx(oe,{path:"/project/:id",element:e.jsx(rs,{})}),e.jsx(oe,{path:"/terminal/:agentId",element:e.jsx(as,{})}),e.jsx(oe,{path:"/tasks",element:e.jsx(is,{})}),e.jsx(oe,{path:"/task/:id",element:e.jsx(cs,{})})]})})]})})}function hs({children:s}){const[t,r]=a.useState({kind:"probing"}),o=a.useRef(t);a.useEffect(()=>{o.current=t},[t]);const n=a.useCallback(async()=>{r({kind:"probing"});try{await O.config.get(),r({kind:"authorized"})}catch(i){if(i instanceof me&&i.status===401){r({kind:"unauthorized"});return}const l=i instanceof Error?i.message:"无法连接服务器";r({kind:"error",message:l})}},[]);return a.useEffect(()=>{n()},[n]),a.useEffect(()=>{const i=()=>{o.current.kind!=="probing"&&r({kind:"unauthorized",message:"登录已失效,请重新输入令牌"})};return window.addEventListener(ke,i),()=>window.removeEventListener(ke,i)},[]),t.kind==="authorized"?e.jsx(e.Fragment,{children:s}):t.kind==="error"?e.jsxs(Re,{title:"无法连接服务器",children:[e.jsx("p",{className:"text-[13px] text-og-600",children:t.message}),e.jsx("button",{type:"button",onClick:()=>{n()},className:"btn-primary mt-4 w-full",children:"重试"})]}):t.kind==="probing"?e.jsx(Re,{title:"加载中",children:e.jsx("p",{className:"text-[13px] text-og-500",children:"正在检查登录状态…"})}):e.jsx(fs,{message:t.message,onSubmit:async i=>{xt(i);try{await O.config.get(),r({kind:"authorized"})}catch(l){if(mt(),l instanceof me&&l.status===401){r({kind:"unauthorized",message:"令牌无效,请重试"});return}const f=l instanceof Error?l.message:"登录失败";r({kind:"error",message:f})}}})}function Re({title:s,children:t}){return e.jsx("div",{className:"flex min-h-screen items-center justify-center bg-page px-4",children:e.jsxs("div",{className:"w-full max-w-sm rounded-lg border border-hairline bg-surface px-6 py-6",children:[e.jsx("h1",{className:"mb-3 font-display text-[16px] font-semibold tracking-tight text-og-1000",children:s}),t]})})}function fs({message:s,onSubmit:t}){const[r,o]=a.useState(""),[n,i]=a.useState(!1),[l,f]=a.useState(void 0),b=async u=>{u.preventDefault();const h=r.trim();if(!h){f("请输入访问令牌");return}f(void 0),i(!0);try{await t(h)}finally{i(!1)}},p=l??s;return e.jsxs(Re,{title:"登录 baxian",children:[e.jsx("p",{className:"mb-4 text-[13px] text-og-600",children:"服务器开启了访问鉴权,请输入访问令牌继续。"}),e.jsxs("form",{onSubmit:u=>{b(u)},children:[e.jsx("label",{className:"mb-1.5 block text-[12px] font-medium text-og-700",htmlFor:"baxian-token",children:"访问令牌"}),e.jsx("input",{id:"baxian-token",type:"password",autoComplete:"current-password",autoFocus:!0,value:r,onChange:u=>o(u.target.value),className:"w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 font-mono text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",placeholder:"请输入服务器配置的 token",disabled:n}),p&&e.jsx("p",{role:"alert",className:"mt-2 text-[12px] text-danger",children:p}),e.jsx("button",{type:"submit",disabled:n,className:"btn-primary mt-4 w-full",children:n?"登录中…":"登录"})]})]})}lt.createRoot(document.getElementById("root")).render(e.jsx(a.StrictMode,{children:e.jsx(Et,{children:e.jsx(wt,{children:e.jsx(hs,{children:e.jsx(us,{})})})})}));
@@ -1 +0,0 @@
1
- @font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-regular.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-italic.woff2) format("woff2");font-weight:400;font-style:italic;font-display:swap}@font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-bold.woff2) format("woff2");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-bolditalic.woff2) format("woff2");font-weight:700;font-style:italic;font-display:swap}@font-face{font-family:Lilex;src:url(/fonts/lilex-variable.woff2) format("woff2-variations");font-weight:200 700;font-style:normal;font-display:swap}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:iA Writer Quattro S,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}body{--tw-bg-opacity: 1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1));font-family:iA Writer Quattro S,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1));font-size:14px;line-height:1.55;-webkit-font-smoothing:antialiased;text-rendering:geometricprecision}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.btn-primary{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;border-radius:6px;--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1));padding:.375rem .75rem;font-size:13px;font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.btn-primary:hover{--tw-bg-opacity: 1;background-color:rgb(15 59 184 / var(--tw-bg-opacity, 1))}.btn-primary:disabled{cursor:not-allowed;opacity:.5}.btn-secondary{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;border-radius:6px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(206 209 214 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));padding:.375rem .75rem;font-size:13px;font-weight:500;--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.btn-secondary:hover{--tw-border-opacity: 1;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(19 72 220 / var(--tw-text-opacity, 1))}.btn-secondary:disabled{cursor:not-allowed;opacity:.5}.btn-ghost{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;border-radius:6px;background-color:transparent;padding:.375rem .75rem;font-size:13px;font-weight:500;--tw-text-opacity: 1;color:rgb(109 116 132 / var(--tw-text-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.btn-ghost:hover{--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1))}.btn-ghost:disabled{cursor:not-allowed;opacity:.5}.pill{display:inline-flex;align-items:center;gap:.375rem;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1));padding:.125rem .5rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:11px;line-height:1.4;--tw-text-opacity: 1;color:rgb(83 89 100 / var(--tw-text-opacity, 1))}.pill:before{content:"";display:inline-block;height:.375rem;width:.375rem;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(171 175 184 / var(--tw-bg-opacity, 1))}.pill-live{--tw-bg-opacity: 1;background-color:rgb(230 244 236 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.pill-live:before{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.pill-warn{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.pill-warn:before{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.pill-review{--tw-bg-opacity: 1;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(19 72 220 / var(--tw-text-opacity, 1))}.pill-review:before{--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1))}.card{border-radius:8px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(232 233 236 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.card:hover{--tw-border-opacity: 1;border-color:rgb(206 209 214 / var(--tw-border-opacity, 1))}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.fixed{position:fixed}.inset-0{top:0;right:0;bottom:0;left:0}.right-4{right:1rem}.top-4{top:1rem}.z-50{z-index:50}.z-\[60\]{z-index:60}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-10{margin-bottom:2.5rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-4{margin-right:1rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-12{height:3rem}.h-3\.5{height:.875rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-80{height:20rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-28{max-height:7rem}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0px}.min-h-screen{min-height:100vh}.w-1\.5{width:.375rem}.w-3\.5{width:.875rem}.w-6{width:1.5rem}.w-80{width:20rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-none{flex:none}.shrink-0{flex-shrink:0}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-1{row-gap:.25rem}.gap-y-2{row-gap:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-hairline>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(232 233 236 / var(--tw-divide-opacity, 1))}.self-center{align-self:center}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:8px}.rounded-md{border-radius:6px}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.\!border-\[\#bbf7d0\]{--tw-border-opacity: 1 !important;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))!important}.\!border-\[\#fecaca\]{--tw-border-opacity: 1 !important;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))!important}.\!border-accent-soft{--tw-border-opacity: 1 !important;border-color:rgb(234 240 255 / var(--tw-border-opacity, 1))!important}.\!border-warn{--tw-border-opacity: 1 !important;border-color:rgb(180 83 9 / var(--tw-border-opacity, 1))!important}.border-\[\#bbf7d0\]{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-\[\#fde68a\]{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-\[\#fecaca\]{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-accent-soft{--tw-border-opacity: 1;border-color:rgb(234 240 255 / var(--tw-border-opacity, 1))}.border-hairline{--tw-border-opacity: 1;border-color:rgb(232 233 236 / var(--tw-border-opacity, 1))}.border-og-100{--tw-border-opacity: 1;border-color:rgb(206 209 214 / var(--tw-border-opacity, 1))}.bg-\[\#f0fdf4\]{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-\[\#fdfdfd\]{--tw-bg-opacity: 1;background-color:rgb(253 253 253 / var(--tw-bg-opacity, 1))}.bg-\[\#fef2f2\]{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-\[\#fef3c7\]{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-\[\#fef3c7\]\/60{background-color:#fef3c799}.bg-accent-soft\/40{background-color:#eaf0ff66}.bg-og-1000\/45{background-color:#0d0d0f73}.bg-og-50{--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1))}.bg-og-50\/40{background-color:#e3e4e766}.bg-page{--tw-bg-opacity: 1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1))}.bg-success{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.bg-surface{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-display{font-family:Lilex,iA Writer Quattro S,ui-sans-serif,system-ui,sans-serif}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tracking-\[0\.05em\]{letter-spacing:.05em}.tracking-\[0\.06em\]{letter-spacing:.06em}.tracking-tight{letter-spacing:-.025em}.\!text-accent{--tw-text-opacity: 1 !important;color:rgb(19 72 220 / var(--tw-text-opacity, 1))!important}.\!text-danger{--tw-text-opacity: 1 !important;color:rgb(185 28 28 / var(--tw-text-opacity, 1))!important}.\!text-success{--tw-text-opacity: 1 !important;color:rgb(21 128 61 / var(--tw-text-opacity, 1))!important}.\!text-warn{--tw-text-opacity: 1 !important;color:rgb(180 83 9 / var(--tw-text-opacity, 1))!important}.text-accent{--tw-text-opacity: 1;color:rgb(19 72 220 / var(--tw-text-opacity, 1))}.text-current{color:currentColor}.text-danger{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-og-1000{--tw-text-opacity: 1;color:rgb(13 13 15 / var(--tw-text-opacity, 1))}.text-og-400{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.text-og-500{--tw-text-opacity: 1;color:rgb(109 116 132 / var(--tw-text-opacity, 1))}.text-og-600{--tw-text-opacity: 1;color:rgb(98 105 118 / var(--tw-text-opacity, 1))}.text-og-700{--tw-text-opacity: 1;color:rgb(83 89 100 / var(--tw-text-opacity, 1))}.text-og-800{--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1))}.text-success{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-warn{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.accent-\[\#1348dc\]{accent-color:#1348dc}.opacity-50{opacity:.5}.opacity-80{opacity:.8}.shadow-modal{--tw-shadow: 0 12px 32px rgba(15, 23, 42, .12);--tw-shadow-colored: 0 12px 32px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-toast{--tw-shadow: 0 4px 12px rgba(15, 23, 42, .08);--tw-shadow-colored: 0 4px 12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.placeholder\:text-og-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.placeholder\:text-og-400::placeholder{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.hover\:\!border-accent:hover{--tw-border-opacity: 1 !important;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1))!important}.hover\:\!border-danger:hover{--tw-border-opacity: 1 !important;border-color:rgb(185 28 28 / var(--tw-border-opacity, 1))!important}.hover\:\!border-success:hover{--tw-border-opacity: 1 !important;border-color:rgb(21 128 61 / var(--tw-border-opacity, 1))!important}.hover\:\!border-warn:hover{--tw-border-opacity: 1 !important;border-color:rgb(180 83 9 / var(--tw-border-opacity, 1))!important}.hover\:\!bg-\[\#dcfce7\]:hover{--tw-bg-opacity: 1 !important;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))!important}.hover\:\!bg-\[\#fef2f2\]:hover{--tw-bg-opacity: 1 !important;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))!important}.hover\:\!bg-\[\#fef3c7\]:hover{--tw-bg-opacity: 1 !important;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))!important}.hover\:\!bg-\[\#fef3c7\]\/60:hover{background-color:#fef3c799!important}.hover\:\!bg-accent-soft:hover{--tw-bg-opacity: 1 !important;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1))!important}.hover\:bg-og-50:hover{--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1))}.hover\:bg-og-50\/40:hover{background-color:#e3e4e766}.hover\:bg-og-50\/60:hover{background-color:#e3e4e799}.hover\:\!text-danger:hover{--tw-text-opacity: 1 !important;color:rgb(185 28 28 / var(--tw-text-opacity, 1))!important}.hover\:\!text-warn:hover{--tw-text-opacity: 1 !important;color:rgb(180 83 9 / var(--tw-text-opacity, 1))!important}.hover\:text-accent-hover:hover{--tw-text-opacity: 1;color:rgb(15 59 184 / var(--tw-text-opacity, 1))}.hover\:text-og-800:hover{--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1))}.hover\:opacity-100:hover{opacity:1}.focus\:border-accent:focus{--tw-border-opacity: 1;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-\[3px\]:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-accent-soft:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(234 240 255 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:640px){.sm\:table-cell{display:table-cell}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-4{padding-left:1rem;padding-right:1rem}}@media(min-width:768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(min-width:1280px){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}