baxian 0.6.0 → 0.7.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 @@
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:.625rem;width:.625rem;flex-shrink:0;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(171 175 184 / var(--tw-bg-opacity, 1))}.status-dot--healthy{--tw-bg-opacity: 1;background-color:rgb(21 128 61 / var(--tw-bg-opacity, 1))}.status-dot--warn{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1));animation:breathe 1.8s ease-in-out infinite}.status-dot--danger{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1));animation:breathe 1.8s ease-in-out infinite}.status-dot--info{--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1));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-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}.leading-none{line-height:1}.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))}}
@@ -1,4 +1,4 @@
1
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
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
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,{})})})})}));
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-center font-display text-[15px] font-semibold tracking-tight text-og-1000",children:t?e.jsx("span",{className:"inline-flex h-6 items-center leading-none",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,{})})})})}));
@@ -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-NBPoRVS-.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-CJjiHZTd.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
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-xOQlV4Ki.css">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-0_vl9XaN.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.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "AI agent orchestration",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -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))}.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))}}