baxian 0.2.0 → 0.3.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))}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.fixed{position:fixed}.inset-0{top:0;right:0;bottom:0;left:0}.right-4{right:1rem}.top-4{top:1rem}.z-50{z-index:50}.z-\[60\]{z-index:60}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-10{margin-bottom:2.5rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-4{margin-right:1rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-12{height:3rem}.h-2\.5{height:.625rem}.h-3\.5{height:.875rem}.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-2\.5{width:.625rem}.w-3\.5{width:.875rem}.w-80{width:20rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-none{flex:none}.shrink-0{flex-shrink:0}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-1{row-gap:.25rem}.gap-y-2{row-gap:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-hairline>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(232 233 236 / var(--tw-divide-opacity, 1))}.self-center{align-self:center}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:8px}.rounded-md{border-radius:6px}.rounded-sm{border-radius:4px}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.\!border-\[\#bbf7d0\]{--tw-border-opacity: 1 !important;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))!important}.\!border-\[\#fecaca\]{--tw-border-opacity: 1 !important;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))!important}.\!border-accent-soft{--tw-border-opacity: 1 !important;border-color:rgb(234 240 255 / var(--tw-border-opacity, 1))!important}.\!border-warn{--tw-border-opacity: 1 !important;border-color:rgb(180 83 9 / var(--tw-border-opacity, 1))!important}.border-\[\#bbf7d0\]{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-\[\#fde68a\]{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-\[\#fecaca\]{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-accent-soft{--tw-border-opacity: 1;border-color:rgb(234 240 255 / var(--tw-border-opacity, 1))}.border-hairline{--tw-border-opacity: 1;border-color:rgb(232 233 236 / var(--tw-border-opacity, 1))}.border-og-100{--tw-border-opacity: 1;border-color:rgb(206 209 214 / var(--tw-border-opacity, 1))}.bg-\[\#f0fdf4\]{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-\[\#fdfdfd\]{--tw-bg-opacity: 1;background-color:rgb(253 253 253 / var(--tw-bg-opacity, 1))}.bg-\[\#fef2f2\]{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-\[\#fef3c7\]{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-\[\#fef3c7\]\/60{background-color:#fef3c799}.bg-accent{--tw-bg-opacity: 1;background-color:rgb(19 72 220 / 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}.placeholder\:text-og-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.placeholder\:text-og-400::placeholder{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.hover\:\!border-accent:hover{--tw-border-opacity: 1 !important;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1))!important}.hover\:\!border-danger:hover{--tw-border-opacity: 1 !important;border-color:rgb(185 28 28 / var(--tw-border-opacity, 1))!important}.hover\:\!border-success:hover{--tw-border-opacity: 1 !important;border-color:rgb(21 128 61 / var(--tw-border-opacity, 1))!important}.hover\:\!border-warn:hover{--tw-border-opacity: 1 !important;border-color:rgb(180 83 9 / var(--tw-border-opacity, 1))!important}.hover\:\!bg-\[\#dcfce7\]:hover{--tw-bg-opacity: 1 !important;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))!important}.hover\:\!bg-\[\#fef2f2\]:hover{--tw-bg-opacity: 1 !important;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))!important}.hover\:\!bg-\[\#fef3c7\]:hover{--tw-bg-opacity: 1 !important;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))!important}.hover\:\!bg-\[\#fef3c7\]\/60:hover{background-color:#fef3c799!important}.hover\:\!bg-accent-soft:hover{--tw-bg-opacity: 1 !important;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1))!important}.hover\:bg-og-50:hover{--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1))}.hover\:bg-og-50\/40:hover{background-color:#e3e4e766}.hover\:bg-og-50\/60:hover{background-color:#e3e4e799}.hover\:\!text-danger:hover{--tw-text-opacity: 1 !important;color:rgb(185 28 28 / var(--tw-text-opacity, 1))!important}.hover\:\!text-warn:hover{--tw-text-opacity: 1 !important;color:rgb(180 83 9 / var(--tw-text-opacity, 1))!important}.hover\:text-accent-hover:hover{--tw-text-opacity: 1;color:rgb(15 59 184 / var(--tw-text-opacity, 1))}.hover\:text-og-800:hover{--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1))}.hover\:opacity-100:hover{opacity:1}.focus\:border-accent:focus{--tw-border-opacity: 1;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-\[3px\]:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-accent-soft:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(234 240 255 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:640px){.sm\:table-cell{display:table-cell}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-4{padding-left:1rem;padding-right:1rem}}@media(min-width:768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(min-width:1280px){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
@@ -0,0 +1,4 @@
1
+ var ot=Object.defineProperty;var ct=(s,t,r)=>t in s?ot(s,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[t]=r;var _=(s,t,r)=>ct(s,typeof t!="symbol"?t+"":t,r);import{r as a,j as e,c as lt}from"./react-BG4Iuztk.js";import{x as dt,a as ut}from"./xterm-D5X2JljJ.js";import{L as ce,u as Ce,a as Te,B as ht,N as ve,R as ft,b as oe}from"./router-BVggVFlO.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))o(n);new MutationObserver(n=>{for(const i of n)if(i.type==="childList")for(const l of i.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&o(l)}).observe(document,{childList:!0,subtree:!0});function r(n){const i={};return n.integrity&&(i.integrity=n.integrity),n.referrerPolicy&&(i.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?i.credentials="include":n.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(n){if(n.ep)return;n.ep=!0;const i=r(n);fetch(n.href,i)}})();const be="/api",Ie="baxian.token",Ee="baxian:unauthorized";function Pe(){try{return typeof localStorage<"u"?localStorage.getItem(Ie):null}catch{return null}}function xt(s){try{localStorage.setItem(Ie,s)}catch(t){console.error("Failed to save auth token to localStorage",t)}}function mt(){try{localStorage.removeItem(Ie)}catch(s){console.error("Failed to clear auth token from localStorage",s)}}function le(s){const t=Pe();return{...s??{},...t?{Authorization:`Bearer ${t}`}:{}}}class me extends Error{constructor(t,r,o){super(r),this.status=t,this.details=o,this.name="ApiError"}}async function de(s){const t=await s.text();let r=t||`HTTP ${s.status}`,o;try{const n=JSON.parse(t);typeof n.error=="string"&&(r=n.error),Array.isArray(n.details)&&(o=n.details)}catch{}throw s.status===401&&typeof window<"u"&&window.dispatchEvent(new CustomEvent(Ee)),new me(s.status,r,o)}async function se(s){const t=await fetch(`${be}${s}`,{headers:le()});return t.ok||await de(t),t.json()}async function pt(){const s=await fetch("/health");return s.ok||await de(s),s.json()}async function Z(s,t,r){const o=t!==void 0,n=await fetch(`${be}${s}`,{method:"POST",headers:o?le({"Content-Type":"application/json"}):le(),body:o?JSON.stringify(t):void 0,signal:r==null?void 0:r.signal});return n.ok||await de(n),n.json()}async function bt(s,t,r){const o=await fetch(`${be}${s}`,{method:"PATCH",headers:le({"Content-Type":"application/json"}),body:t?JSON.stringify(t):void 0,signal:r==null?void 0:r.signal});if(o.ok||await de(o),o.status===204)return;const n=await o.text();if(n)return JSON.parse(n)}async function _e(s){const t=await fetch(`${be}${s}`,{method:"DELETE",headers:le()});if(t.ok||await de(t),t.status===204)return;const r=await t.text();if(r)return JSON.parse(r)}const W=encodeURIComponent,O={agents:{list:()=>se("/agents"),get:s=>se(`/agents/${W(s)}`),stop:s=>_e(`/agents/${W(s)}/session`),probe:(s,t,r)=>Z("/agents/probe",{mode:s,host:t},r)},tasks:{list:s=>se(`/tasks${s?`?projectId=${W(s)}`:""}`),get:s=>se(`/tasks/${W(s)}`),create:s=>Z("/tasks",s),update:(s,t)=>bt(`/tasks/${W(s)}`,t),retry:s=>Z(`/tasks/${W(s)}/retry`),review:s=>Z(`/tasks/${W(s)}/review`)},projects:{list:()=>se("/projects"),get:s=>se(`/projects/${W(s)}`),create:s=>Z("/projects",s),addAgent:(s,t)=>Z(`/projects/${W(s)}/agents`,t),deleteAgent:(s,t)=>_e(`/projects/${W(s)}/agents/${W(t)}`),resumeAgent:(s,t)=>Z(`/projects/${W(s)}/agents/${W(t)}/resume`),bootstrap:s=>Z(`/projects/${W(s)}/bootstrap`)},config:{get:()=>se("/config")},health:{get:pt},server:{restart:()=>Z("/restart")}},Ye=a.createContext(null),gt={success:"border-[#bbf7d0] bg-[#f0fdf4] text-success",warn:"border-[#fde68a] bg-[#fef3c7] text-warn",error:"border-[#fecaca] bg-[#fef2f2] text-danger"},jt={success:"✅",warn:"⚠️",error:"❌"};let vt=1;function wt({children:s}){const[t,r]=a.useState([]),o=a.useCallback(i=>{r(l=>l.filter(f=>f.id!==i))},[]),n=a.useCallback(i=>{const l=vt++,f=i.durationMs??3e3;r(b=>[...b,{...i,id:l}]),setTimeout(()=>o(l),f)},[o]);return e.jsxs(Ye.Provider,{value:{show:n},children:[s,e.jsx("div",{className:"pointer-events-none fixed right-4 top-4 z-[60] flex flex-col gap-2",children:t.map(i=>e.jsx("div",{className:`pointer-events-auto w-80 rounded-lg border px-4 py-3 shadow-toast ${gt[i.kind]}`,role:"status",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{"aria-hidden":!0,className:"text-[14px]",children:jt[i.kind]}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"text-[13px] font-semibold",children:i.title}),i.body&&e.jsx("div",{className:"mt-1 whitespace-pre-line text-[12px] text-og-700",children:i.body})]}),e.jsx("button",{type:"button",onClick:()=>o(i.id),className:"text-current opacity-50 transition-opacity hover:opacity-100","aria-label":"Dismiss",children:"✕"})]})},i.id))})]})}function ue(){const s=a.useContext(Ye);if(!s)throw new Error("useToast must be inside <ToastProvider>");return s}const pe="baxian.pendingRestart",yt=500,Nt=3e4,Ze=a.createContext(null);function St(){try{const s=localStorage.getItem(pe);if(!s)return{count:0,baselineStartedAt:null};const t=JSON.parse(s);return{count:typeof t.count=="number"?t.count:0,baselineStartedAt:typeof t.baselineStartedAt=="string"?t.baselineStartedAt:null}}catch{return{count:0,baselineStartedAt:null}}}function kt(s){try{s.count<=0?localStorage.removeItem(pe):localStorage.setItem(pe,JSON.stringify(s))}catch{}}function Et({children:s}){const t=St(),[r,o]=a.useState(t.count),[n,i]=a.useState(t.baselineStartedAt),[l,f]=a.useState(t.count>0?"pending":"idle"),[b,p]=a.useState(),u=a.useRef(t.count),h=a.useRef(t.count>0?"pending":"idle"),m=a.useRef(0),x=a.useCallback(N=>{u.current=N,o(N)},[]),d=a.useCallback(N=>{o(A=>{const g=N(A);return u.current=g,g})},[]),v=a.useCallback(N=>{h.current=N,f(N)},[]);a.useEffect(()=>{kt({count:r,baselineStartedAt:n})},[r,n]),a.useEffect(()=>{let N=!1;(async()=>{try{const g=await O.health.get();if(N)return;i(R=>R!==null&&g.startedAt!==R?(x(0),v("idle"),null):R)}catch{}})();const A=g=>{if(g.key===pe){if(g.newValue===null){if(h.current==="restarting"&&m.current>0){x(m.current),i(null);return}x(0),i(null),h.current!=="restarting"&&v("idle");return}try{const R=JSON.parse(g.newValue);typeof R.count=="number"&&(h.current==="restarting"&&R.count>u.current&&(m.current+=R.count-u.current),x(R.count),h.current!=="restarting"&&v(R.count>0?"pending":"idle")),typeof R.baselineStartedAt=="string"?i(R.baselineStartedAt):R.baselineStartedAt===null&&i(null)}catch{}}};return window.addEventListener("storage",A),()=>{N=!0,window.removeEventListener("storage",A)}},[x,v]);const c=a.useRef(!1),T=a.useCallback(()=>{d(N=>N+1),h.current==="restarting"?m.current+=1:v("pending"),i(N=>(N!==null||c.current||(c.current=!0,(async()=>{try{const A=await O.health.get();i(g=>g??A.startedAt)}catch{}finally{c.current=!1}})()),N))},[v,d]),$=a.useCallback(async()=>{m.current=0,p(void 0),v("restarting");let N;try{N=(await O.health.get()).startedAt}catch(g){v("failed"),p(`获取重启前 startedAt 失败: ${g instanceof Error?g.message:String(g)}`);return}try{await O.server.restart()}catch(g){if(!(g instanceof me&&g.status===409)){v("failed"),p(`触发重启失败: ${g instanceof Error?g.message:String(g)}`);return}}const A=Date.now();for(;Date.now()-A<Nt;){await new Promise(g=>setTimeout(g,yt));try{const g=await O.health.get();if(g.startedAt!==N){const R=m.current;m.current=0,i(R>0?g.startedAt:null),x(R),v(R>0?"pending":"idle");return}}catch{}}v("failed"),p("重启超时(30s 未恢复)。请检查日志或手动 baxian start -c <path>")},[x,v]);return e.jsx(Ze.Provider,{value:{phase:l,count:r,error:b,flagDirty:T,triggerRestart:$},children:s})}function ge(){const s=a.useContext(Ze);if(!s)throw new Error("usePendingRestart must be used inside PendingRestartProvider");return s}const Rt=[500,1e3,2e3,4e3,8e3,15e3,3e4];class Xe{constructor(t){_(this,"attempts",0);_(this,"timer",null);_(this,"delaysMs");this.opts=t,this.delaysMs=t.delaysMs??Rt}schedule(){if(this.timer||!this.shouldReconnect())return;const t=this.delaysMs[Math.min(this.attempts,this.delaysMs.length-1)];this.attempts+=1,this.timer=setTimeout(()=>{this.timer=null,this.shouldReconnect()&&this.opts.reconnect()},t)}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null)}reset(){this.attempts=0}shouldReconnect(){return this.opts.shouldReconnect?this.opts.shouldReconnect():!0}}let Fe=0;function At(){Fe++;const s=Math.random().toString(36).slice(2,8);return`sub-${Date.now().toString(36)}-${Fe}-${s}`}function Ct(s){return Array.from(new TextEncoder().encode(s)).map(t=>t.toString(16).padStart(2,"0")).join("")}function Tt(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/stream`}const It=(s,t)=>t&&t.length>0?new WebSocket(s,t):new WebSocket(s);class Pt{constructor(t={}){_(this,"wsUrl");_(this,"wsFactory");_(this,"tokenProvider");_(this,"ws",null);_(this,"subs",new Map);_(this,"snapshotPending",new Set);_(this,"preSubscribeQueue",new Map);_(this,"outbox",[]);_(this,"reconnectScheduler");_(this,"explicitlyClosed",!1);this.wsUrl=t.wsUrl??Tt(),this.wsFactory=t.wsFactory??It,this.tokenProvider=t.tokenProvider??Pe,this.reconnectScheduler=new Xe({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.subs.size>0})}subscribe(t){const r=At(),o={subscriberId:r,agentId:t.agentId,mode:t.mode,onSnapshot:t.onSnapshot,onData:t.onData,onError:t.onError,onSessionGone:t.onSessionGone};return this.subs.set(r,o),this.snapshotPending.add(r),this.preSubscribeQueue.set(r,[]),this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",subscriberId:r,agentId:t.agentId,mode:t.mode}),{subscriberId:r,unsubscribe:()=>this.unsubscribe(r)}}send(t,r){if(this.subs.has(t)){if(this.snapshotPending.has(t)){this.outbox.push({op:"input",subscriberId:t,data:r});return}this.wsSendOrQueue({op:"input",subscriberId:t,data:r})}}resize(t,r,o){const n=this.subs.get(t);n&&(n.lastSize={cols:r,rows:o},!this.snapshotPending.has(t)&&this.wsSendOrQueue({op:"resize",subscriberId:t,cols:r,rows:o}))}ping(){this.wsSendOrQueue({op:"ping"})}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.subs.clear(),this.snapshotPending.clear(),this.preSubscribeQueue.clear(),this.outbox=[]}unsubscribe(t){this.subs.has(t)&&(this.subs.delete(t),this.snapshotPending.delete(t),this.preSubscribeQueue.delete(t),this.wsSendOrQueue({op:"unsubscribe",subscriberId:t}),this.subs.size===0&&this.teardownSocket())}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const t=this.tokenProvider(),r=t?[`baxian.token.${Ct(t)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,r)}catch(n){console.warn("[pane-stream] WebSocket constructor threw:",n),this.scheduleReconnect();return}this.ws=o,o.onopen=()=>{if(o!==this.ws)return;this.reconnectScheduler.reset();for(const i of this.subs.values()){this.snapshotPending.add(i.subscriberId),this.preSubscribeQueue.set(i.subscriberId,[]),i.snapshotSeq=void 0;try{o.send(JSON.stringify({op:"subscribe",subscriberId:i.subscriberId,agentId:i.agentId,mode:i.mode}))}catch(l){console.warn("[pane-stream] resubscribe send failed:",l)}}const n=this.outbox;this.outbox=[];for(const i of n)if(i.op!=="subscribe"){if("subscriberId"in i&&i.subscriberId){if(!this.subs.has(i.subscriberId))continue;if(this.snapshotPending.has(i.subscriberId)&&i.op!=="unsubscribe"){this.outbox.push(i);continue}}try{o.send(JSON.stringify(i))}catch(l){console.warn("[pane-stream] outbox flush failed:",l)}}},o.onmessage=n=>{if(o!==this.ws)return;let i;try{const l=typeof n.data=="string"?n.data:String(n.data);i=JSON.parse(l)}catch{return}this.handleMessage(i)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&this.subs.size!==0&&this.scheduleReconnect())},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}wsSendOrQueue(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(t));return}catch(r){console.warn("[pane-stream] send failed, will queue:",r)}this.outbox.push(t)}handleMessage(t){var r,o;switch(t.type){case"snapshot":this.handleSnapshot(t);break;case"subscribed":this.handleSubscribed(t);break;case"data":this.dispatch(t);break;case"session_gone":for(const n of[...this.subs.values()])n.agentId===t.agentId&&((r=n.onSessionGone)==null||r.call(n));break;case"error":{if(t.subscriberId){const n=this.subs.get(t.subscriberId);(o=n==null?void 0:n.onError)==null||o.call(n,{code:t.code,message:t.message})}else console.warn("[pane-stream] connection-level error:",t.code,t.message);break}}}handleSnapshot(t){const r=this.subs.get(t.subscriberId);r&&r.onSnapshot({cols:t.cols,rows:t.rows,data:t.data})}handleSubscribed(t){const r=this.subs.get(t.subscriberId);if(!r)return;r.snapshotSeq=t.snapshotSeq,r.lastSize||(r.lastSize={cols:t.cols,rows:t.rows}),this.snapshotPending.delete(t.subscriberId);const o=this.preSubscribeQueue.get(t.subscriberId);if(this.preSubscribeQueue.delete(t.subscriberId),o)for(const n of o)n.seq>t.snapshotSeq&&r.onData(n.data);r.mode==="full"&&r.lastSize&&this.wsSendOrQueue({op:"resize",subscriberId:r.subscriberId,cols:r.lastSize.cols,rows:r.lastSize.rows}),this.flushOutboxForSub(t.subscriberId)}flushOutboxForSub(t){if(this.outbox.length===0||!this.ws||this.ws.readyState!==WebSocket.OPEN)return;const r=[];for(const o of this.outbox)if("subscriberId"in o&&o.subscriberId===t&&o.op!=="subscribe")try{this.ws.send(JSON.stringify(o))}catch(n){console.warn("[pane-stream] flushOutboxForSub send failed:",n)}else r.push(o);this.outbox=r}dispatch(t){for(const r of this.subs.values())if(r.agentId===t.agentId)if(this.snapshotPending.has(r.subscriberId)){const o=this.preSubscribeQueue.get(r.subscriberId);o&&o.push({seq:t.seq,data:t.data})}else r.onData(t.data)}}let we=null;function ye(){return we||(we=new Pt),we}function $t(s){const{agentId:t,mode:r}=s,o=a.useRef(null),n=a.useRef({onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone});n.current={onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone},a.useEffect(()=>{const b=ye().subscribe({agentId:t,mode:r,onSnapshot:p=>n.current.onSnapshot(p),onData:p=>n.current.onData(p),onError:p=>{var u,h;return(h=(u=n.current).onError)==null?void 0:h.call(u,p)},onSessionGone:()=>{var p,u;return(u=(p=n.current).onSessionGone)==null?void 0:u.call(p)}});return o.current=b.subscriberId,()=>{o.current=null,b.unsubscribe()}},[t,r]);const i=a.useCallback(f=>{const b=o.current;b&&ye().send(b,f)},[]),l=a.useCallback((f,b)=>{const p=o.current;p&&ye().resize(p,f,b)},[]);return{send:i,resize:l}}const Dt=18,Ot=250,Lt=256*1024,Me="#fdfdfd",_t='ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',Ft={background:Me,foreground:"#474c55",cursor:"#1348dc",cursorAccent:Me,selectionBackground:"#eaf0ff",black:"#0d0d0f",red:"#b91c1c",green:"#15803d",yellow:"#b45309",blue:"#1348dc",magenta:"#9333ea",cyan:"#0e7490",white:"#474c55",brightBlack:"#878e9b",brightRed:"#dc2626",brightGreen:"#16a34a",brightYellow:"#d97706",brightBlue:"#3080ff",brightMagenta:"#a855f7",brightCyan:"#0891b2",brightWhite:"#0d0d0f"},Mt=/\x1b\[(?:\?[\d;]*c|>[\d;]*c|\??\d+;\d+R|\d+n)/g;function zt(s){return s.replace(Mt,"")}function Re({agentId:s,mode:t,interactive:r=!1,maxLines:o,className:n,autoFocus:i=!0,deferFullUntilFocus:l=!1}){const f=a.useRef(null),b=a.useRef(null),p=a.useRef(null),u=a.useRef(!1),h=a.useRef(""),m=a.useRef([]),x=a.useRef(0),d=a.useRef(null),v=a.useRef(null),c=a.useRef(Promise.resolve()),T=a.useRef(0),[$,N]=a.useState(null),[A,g]=a.useState(!1),R=`${s}\0${t}\0${l?"1":"0"}`,[S,P]=a.useState({key:R,active:!1}),k=S.key===R&&S.active,D=t==="full"&&l,F=D&&!k?"preview":t,I=r&&F==="full",z=(j,L)=>L.length===0?Promise.resolve():new Promise(C=>{try{j.write(L,()=>C())}catch(w){console.warn("[pane-terminal] write failed:",w),C()}}),Q=(j,L)=>{c.current=c.current.then(async()=>{const C=b.current;if(!(!C||L!==T.current))try{await j(C)}catch(w){console.warn("[pane-terminal] terminal task failed:",w)}}).catch(C=>{console.warn("[pane-terminal] write chain failed:",C)})},U=(j,L)=>{Q(C=>z(C,j),L)},J=()=>{d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),v.current!==null&&(clearTimeout(v.current),v.current=null)},Y=()=>{J(),m.current=[],x.current=0},H=()=>{J();const j=m.current;j.length!==0&&(m.current=[],x.current=0,U(j.join(""),T.current))},V=j=>{if(j.length!==0){if(m.current.push(j),x.current+=j.length,x.current>=Lt){H();return}d.current===null&&(d.current=requestAnimationFrame(H)),v.current===null&&(v.current=setTimeout(H,Ot))}},{send:K,resize:te}=$t({agentId:s,mode:F,onSnapshot:({cols:j,rows:L,data:C})=>{if(b.current)try{const y=T.current+1;T.current=y,Y(),Q(async q=>{q.reset(),j>0&&L>0&&q.resize(j,L),await z(q,C)},y)}catch(y){console.warn("[pane-terminal] snapshot write failed:",y)}},onData:j=>{V(j)},onError:j=>N(`${j.code}: ${j.message}`),onSessionGone:()=>g(!0)});a.useEffect(()=>{N(null),g(!1)},[s,F]),a.useEffect(()=>{h.current=""},[R]),a.useEffect(()=>{if(F!=="full")return;const j=h.current;j.length!==0&&(h.current="",K(j))},[K,F]);const G=a.useCallback(()=>{!r||!D||k||(u.current=!0,P({key:R,active:!0}))},[R,k,r,D]);a.useEffect(()=>{const j=f.current;if(!j)return;let L=!1;const C=new dt.Terminal({cursorBlink:r,disableStdin:!r,theme:Ft,fontFamily:_t,fontSize:13,lineHeight:1.4,scrollback:F==="full"?5e3:1e3}),w=new ut.FitAddon;if(C.loadAddon(w),C.open(j),b.current=C,p.current=w,r&&(i||u.current)){u.current=!1;try{C.focus()}catch{}}r&&C.onData(ae=>{const ie=zt(ae);if(ie.length!==0){if(D&&!k){h.current+=ie,G();return}K(ie)}});const y=()=>j.clientWidth>0&&j.clientHeight>0,q=(ae=!1)=>{if(!y())return!1;const ie=C.cols,it=C.rows;try{w.fit()}catch{return!1}return C.cols>0&&C.rows>0&&(ae||C.cols!==ie||C.rows!==it)&&te(C.cols,C.rows),!0};let B=null,ee=null,he=null,at=0;const Oe=()=>{B||(B=new ResizeObserver(()=>{ee&&clearTimeout(ee),ee=setTimeout(()=>{ee=null,q()},100)}),B.observe(j))},Le=()=>{he=requestAnimationFrame(()=>{if(he=null,!(L||!I)){if(q(!0)){Oe();return}if(at++<5){Le();return}Oe()}})};return Le(),()=>{L=!0,he!==null&&cancelAnimationFrame(he),d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),v.current!==null&&(clearTimeout(v.current),v.current=null),T.current++,m.current=[],x.current=0,c.current=Promise.resolve(),ee&&clearTimeout(ee),B==null||B.disconnect(),b.current=null,p.current=null;try{C.dispose()}catch(ae){console.warn("[pane-terminal] dispose failed:",ae)}}},[G,s,i,I,k,r,K,D,F,te]);const E=()=>{var j;if(r){G();try{(j=b.current)==null||j.focus()}catch{}}},M=o&&o>0?{maxHeight:`${o*Dt}px`}:void 0;return e.jsxs("div",{className:n??"flex flex-col h-full w-full min-h-0 bg-[#fdfdfd]",children:[($||A)&&e.jsx("div",{className:"border-b border-[#fecaca] bg-[#fef2f2] px-3 py-1 font-mono text-[11px] text-danger",children:A?"session ended":$}),e.jsx("div",{ref:f,className:"flex-1 min-h-0 overflow-hidden px-2 py-1.5",style:M,onMouseDown:E})]})}const Bt={unknown:{label:"Unknown",cls:"pill pill-idle"},idle:{label:"Idle",cls:"pill pill-idle"},pending:{label:"Pending user",cls:"pill pill-warn"},working:{label:"Working",cls:"pill pill-live"},waiting:{label:"Waiting",cls:"pill pill-review"},error:{label:"Error",cls:"pill pill-warn"}},Qt={present:{label:"Session present",cls:"pill pill-live"},absent:{label:"No session",cls:"pill pill-idle"},unreachable:{label:"Host unreachable",cls:"pill pill-warn"},unknown:{label:"Session unknown",cls:"pill pill-idle"}};function Ut({agent:s,projectId:t,role:r,onDeleted:o,pendingRestart:n=!1,terminalLoading:i=!1,showTaskBinding:l=!0,terminalMode:f="activity-preview"}){var G,E,M,j,L,C,w;const[b,p]=a.useState(!1),[u,h]=a.useState(null),{show:m}=ue(),{flagDirty:x}=ge(),[d,v]=a.useState(!1),[c,T]=a.useState(null),[$,N]=a.useState(!1),[A,g]=a.useState(!1),[R,S]=a.useState(!1),P=(G=s.binding)==null?void 0:G.taskId,k=((E=s.binding)==null?void 0:E.status)==="awaiting_human",D=!!((M=s.binding)!=null&&M.creationToken)&&!((j=s.binding)!=null&&j.paneId)&&!k&&s.reason!=="PENDING_HUMAN",F=D?{label:"Starting",cls:"pill pill-review"}:Bt[s.runtimeStatus],I=D?{label:"Starting session",cls:"pill pill-review"}:Qt[s.tmuxSessionStatus],z=f==="activity-preview"&&!D&&(s.runtimeStatus==="working"||s.runtimeStatus==="pending"),Q=f==="embedded-full",U=i||n||D,J=i?"Agent 状态加载中":n?"重启 baxian server 后可用":"Agent 正在启动",Y=async()=>{p(!0),h(null);try{await O.agents.stop(s.id)}catch(y){h(y instanceof Error?y.message:String(y))}finally{p(!1)}},H=async()=>{if(P&&window.confirm(`请 QA 对 task ${P} 重审?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`)){N(!0);try{const y=await O.tasks.review(P);m({kind:"success",title:`已派 QA 重审 (round ${y.reviewRound})`})}catch(y){m({kind:"error",title:"Review 派发失败",body:y instanceof Error?y.message:String(y)})}finally{N(!1)}}},V=async()=>{S(!0);try{(await O.projects.bootstrap(t)).ok?m({kind:"success",title:"Bootstrap retry 完成",body:"agent 状态将在下一次刷新生效。"}):m({kind:"warn",title:"Bootstrap retry 仍失败",body:"看一下红色错误卡的最新原因,按提示修复后再试。"})}catch(y){m({kind:"error",title:"Bootstrap retry 失败",body:y instanceof Error?y.message:String(y)})}finally{S(!1)}},K=async()=>{if(window.confirm(`确认 Resume Agent ${s.id}?baxian 会清除 awaiting_human 状态,agent 重新可派遣。`)){g(!0);try{const y=await O.projects.resumeAgent(t,s.id);m({kind:"success",title:`Agent ${s.id} 已 Resume`,body:y.releasedBinding?"原任务已释放,agent 可接新任务。":"保留绑定(原任务仍 active)。"})}catch(y){m({kind:"error",title:"Resume 失败",body:y instanceof Error?y.message:String(y)})}finally{g(!1)}}},te=async()=>{if(window.confirm(`确认删除 Agent ${s.id}?此操作不可撤销`)){v(!0),T(null);try{const y=await O.projects.deleteAgent(t,s.id);y!=null&&y.restartRequired&&x();const q=(y==null?void 0:y.removed)??[s.id];if(q.length>1){const B=q.filter(ee=>ee!==s.id).join(", ");m({kind:"warn",title:`已删除 Agent ${s.id}`,body:`配对的 QA Agent ${B} 也被一并移除。`})}else m({kind:"success",title:`Agent ${s.id} 已删除`});o==null||o()}catch(y){T(y instanceof Error?y.message:String(y))}finally{v(!1)}}};return e.jsxs("div",{className:"card flex h-full min-w-0 flex-col p-4",children:[e.jsxs("div",{className:"mb-3 flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx("span",{className:"font-mono text-[11px] font-medium uppercase tracking-[0.05em] text-og-500",children:r}),e.jsx("span",{className:"font-display text-[14px] font-semibold text-og-1000",children:s.id})]}),e.jsxs("div",{className:"flex flex-wrap justify-end gap-1",children:[k&&e.jsx("span",{className:"pill pill-warn",title:((L=s.binding)==null?void 0:L.awaitingReason)??"需人工处理",children:"Held"}),e.jsx("span",{className:F.cls,children:F.label}),e.jsx("span",{className:I.cls,children:I.label}),s.stale&&e.jsx("span",{className:"pill pill-warn",title:s.observedAt?`Last observed at ${s.observedAt}`:void 0,children:"Stale"})]})]}),D&&e.jsx("div",{className:"mb-2 rounded-md border border-accent-soft bg-accent-soft/40 px-2.5 py-2 text-[12px] text-accent",children:"Agent 正在启动,终端可用后会自动刷新。"}),k&&e.jsxs("div",{className:"mb-2 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-2.5 py-2 text-[12px] text-warn",children:[e.jsx("span",{className:"font-mono",children:(C=s.binding)==null?void 0:C.awaitingPhase}),((w=s.binding)==null?void 0:w.awaitingReason)&&e.jsxs("span",{children:[" · ",s.binding.awaitingReason]})]}),!D&&s.runtimeStatus==="pending"&&e.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-2.5 py-2 text-[12px] text-warn",children:[e.jsx("div",{className:"font-medium",children:"等待人工介入"}),e.jsxs("div",{children:["Agent 正在等待人工输入。请打开 ",e.jsx(ce,{to:`/terminal/${s.id}`,className:"text-accent hover:text-accent-hover underline",children:"Terminal"})," 处理; 处理完后状态会随下一次观测刷新。"]})]}),s.latestError&&e.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-[#fecaca] bg-[#fef2f2] px-2.5 py-2 text-[12px] text-danger",children:[e.jsx("div",{className:"break-words font-medium",children:s.latestError.message}),e.jsxs("div",{className:"font-mono text-[11px] opacity-80",children:[s.latestError.reason," · ",s.latestError.occurredAt]})]}),s.latestBootstrapError&&e.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-[#fecaca] bg-[#fef2f2] px-2.5 py-2 text-[12px] text-danger",children:[e.jsx("div",{className:"break-words font-medium",children:s.latestBootstrapError.message}),s.latestBootstrapError.recommendation&&e.jsx("div",{className:"break-words",children:s.latestBootstrapError.recommendation}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"truncate font-mono text-[11px] opacity-80",children:[s.latestBootstrapError.reason," · ",s.latestBootstrapError.occurredAt]}),e.jsx("button",{type:"button",onClick:V,disabled:R,className:"btn-secondary shrink-0 !border-[#fecaca] !text-danger hover:!bg-[#fef2f2] hover:!border-danger hover:!text-danger",children:R?"Retrying…":"Retry bootstrap"})]})]}),l&&P&&e.jsxs("div",{className:"mb-2 text-[12px] text-og-500",children:["Task: ",e.jsx("span",{className:"font-mono text-og-700",children:P})]}),z&&e.jsx("div",{className:"mb-2 overflow-hidden rounded-md border border-hairline bg-surface",children:e.jsx(Re,{agentId:s.id,mode:"preview",maxLines:6,interactive:!1})}),Q&&e.jsx("div",{className:"mb-2 mt-3 h-80 min-h-0 overflow-hidden rounded-md border border-hairline bg-surface",children:U?e.jsx("div",{className:"flex h-full items-center justify-center px-3 text-[13px] text-og-500",children:J}):e.jsx(Re,{agentId:s.id,mode:"full",interactive:!0,autoFocus:!1,deferFullUntilFocus:!0})}),n&&e.jsx("div",{className:"mb-2 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-2.5 py-1.5 text-[12px] text-warn",children:"⚠️ 重启 baxian server 后生效"}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[U?e.jsx("span",{className:"cursor-not-allowed text-[13px] text-og-400",title:J,children:"Terminal"}):e.jsx(ce,{to:`/terminal/${s.id}`,className:"btn-secondary",children:"Terminal"}),!n&&s.runtimeStatus==="working"&&e.jsx("button",{onClick:Y,disabled:b,className:"btn-ghost !text-danger hover:!bg-[#fef2f2]",children:b?"Stopping…":"Stop"}),u&&e.jsx("span",{className:"text-[12px] text-danger",children:u}),k&&e.jsx("button",{type:"button",onClick:K,disabled:A,title:"清除 awaiting_human 状态,让 agent 重新可派遣",className:"btn-ghost !text-warn hover:!bg-[#fef3c7]/60",children:A?"Resuming…":"Resume"}),!n&&P&&r==="dev"&&e.jsx("button",{type:"button",onClick:H,disabled:$,title:`让 QA 立即对 task ${P} 跑一轮 review(需要该 task 已有 PR)`,className:"btn-ghost !text-accent hover:!bg-accent-soft",children:$?"Dispatching…":"Request QA review"}),e.jsx("button",{type:"button",onClick:te,disabled:d,className:"btn-ghost ml-auto !text-danger hover:!bg-[#fef2f2]","aria-label":`Delete agent ${s.id}`,children:d?"删除中…":"🗑"}),c&&e.jsx("span",{className:"text-[12px] text-danger",children:c})]})]})}const qt=new Set(["in_progress","review","fixing","approved"]);function et({group:s,projectId:t,agentsById:r,agentsLoaded:o,agentsError:n=!1,tasks:i,onDeleted:l,terminalMode:f="activity-preview"}){const b=s.find(x=>x.role==="dev")??s[0],p=s.find(x=>x.role==="qa"),u=i.filter(x=>Wt(x,b==null?void 0:b.id,p==null?void 0:p.id)),h=`Agent group ${s.map(x=>x.id).join(" / ")}`,m=f==="embedded-full"?s.length<=1?"lg:grid-cols-1":s.length===2?"lg:grid-cols-2":s.length===3?"lg:grid-cols-3":"lg:grid-cols-4":"sm:grid-cols-2";return e.jsxs("div",{role:"group","aria-label":h,className:"min-w-0",children:[u.length>0?e.jsx("div",{className:"card mb-2 max-h-28 overflow-y-auto divide-y divide-hairline",children:u.map(x=>{const d=x.phase==="spec"?x.specReviewRound??0:x.reviewRound;return e.jsxs(ce,{to:`/task/${x.id}`,className:"flex items-center gap-3 px-3 py-2 text-[13px] transition-colors hover:bg-og-50/60",children:[e.jsxs("div",{className:"min-w-0 flex-1 flex items-center gap-2",children:[e.jsx("span",{className:"shrink-0 font-mono text-[11px] text-og-500",children:x.id}),e.jsx("span",{className:"truncate text-og-1000",children:x.title})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[e.jsx("span",{className:"pill",children:x.status}),e.jsxs("span",{"aria-label":`Round ${d}`,className:"pill pill-review",children:["Round ",d]})]})]},x.id)})}):e.jsx("div",{className:"mb-2 rounded-lg border border-dashed border-og-100 bg-surface px-3 py-2 text-[13px] text-og-400","aria-label":`${h} no active task`,children:"暂无任务"}),e.jsx("div",{className:`grid grid-cols-1 ${m} gap-4`,children:s.map(x=>{const d=r.get(x.id),v=d??{id:x.id,projectId:t,runtimeStatus:"unknown",tmuxSessionStatus:"unknown",stale:!0};return e.jsx(Ut,{agent:v,projectId:t,role:x.role,pendingRestart:o&&!d,terminalLoading:!o&&!d&&!n,onDeleted:l,showTaskBinding:!1,terminalMode:f},x.id)})})]})}function Wt(s,t,r){return!(!t||!qt.has(s.status)||!(s.agentId===t||s.preferredAgentId===t)||r&&s.qaAgentId&&s.qaAgentId!==r)}const Gt={sm:"max-w-md",md:"max-w-lg",lg:"max-w-2xl"},ze='input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])';function je({open:s,onClose:t,title:r,children:o,size:n="md"}){const i=a.useRef(null),l=a.useRef(null),f=a.useRef(t);return a.useEffect(()=>{f.current=t},[t]),a.useEffect(()=>{if(!s)return;l.current=document.activeElement;const b=h=>{if(h.key==="Escape"){f.current();return}if(h.key!=="Tab")return;const m=i.current;if(!m)return;const x=Array.from(m.querySelectorAll(ze)).filter(T=>T.offsetParent!==null||T===document.activeElement);if(x.length===0){h.preventDefault();return}const d=x[0],v=x[x.length-1],c=document.activeElement;h.shiftKey&&(c===d||!m.contains(c))?(h.preventDefault(),v.focus()):!h.shiftKey&&(c===v||!m.contains(c))&&(h.preventDefault(),d.focus())};document.addEventListener("keydown",b);const p=document.body.style.overflow;document.body.style.overflow="hidden";const u=i.current;if(u){const h=u.querySelector(ze);h==null||h.focus()}return()=>{var h,m;document.removeEventListener("keydown",b),document.body.style.overflow=p,(m=(h=l.current)==null?void 0:h.focus)==null||m.call(h)}},[s]),s?e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-og-1000/45 px-3 sm:px-4",onClick:()=>f.current(),role:"presentation",children:e.jsxs("div",{ref:i,className:`w-full ${Gt[n]} max-h-[90vh] overflow-auto rounded-lg border border-og-100 bg-surface shadow-modal`,onClick:b=>b.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":r,children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-hairline px-6 py-4",children:[e.jsx("h2",{className:"font-display text-[16px] font-semibold tracking-tight text-og-1000",children:r}),e.jsx("button",{type:"button",onClick:()=>f.current(),className:"text-og-400 transition-colors hover:text-og-800","aria-label":"Close",children:"✕"})]}),e.jsx("div",{className:"px-6 py-5",children:o})]})}):null}const Ht=/^[a-z][a-z0-9-]{1,31}$/,Jt=/^[A-Za-z0-9_-][A-Za-z0-9._-]*\/[A-Za-z0-9_-][A-Za-z0-9._-]*$/,Be="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",Ne="mb-1.5 block text-[12px] font-medium text-og-700",Qe="mt-1 text-[12px] text-danger";function Vt({open:s,onClose:t,onCreated:r}){const[o,n]=a.useState(""),[i,l]=a.useState(""),[f,b]=a.useState(null),[p,u]=a.useState(!1),[h,m]=a.useState(null),[x,d]=a.useState({}),[v,c]=a.useState(new Set),T=a.useRef(0),{show:$}=ue(),{flagDirty:N}=ge();a.useEffect(()=>{if(!s)return;T.current+=1;const S=T.current;n(""),l(""),b(null),m(null),d({}),c(new Set),O.config.get().then(P=>{S===T.current&&c(new Set(P.project.map(k=>k.id)))}).catch(()=>{})},[s]);const A=()=>{p||t()},g=()=>{const S={};return o?Ht.test(o)?v.has(o)&&(S.id="该 id 已被占用"):S.id="小写字母开头,只含 a-z 0-9 -,长度 2-32":S.id="必填",i?Jt.test(i)||(S.repo="需为 owner/repo 形式"):S.repo="必填",d(S),Object.keys(S).length===0},R=async S=>{if(S.preventDefault(),!!g()){u(!0),m(null);try{const P=await O.projects.create({id:o,repo:i,merge:f});P.restartRequired&&N(),$({kind:"success",title:`项目 ${P.project.id} 已创建`}),r(P.project.id)}catch(P){m(P instanceof Error?P.message:String(P))}finally{u(!1)}}};return e.jsx(je,{open:s,onClose:A,title:"新建项目",size:"md",children:e.jsxs("form",{onSubmit:R,className:"space-y-4",children:[h&&e.jsx("div",{className:"rounded-md border border-[#fecaca] bg-[#fef2f2] px-3 py-2 text-[13px] text-danger",children:h}),e.jsxs("div",{children:[e.jsx("label",{className:Ne,htmlFor:"proj-id",children:"项目 ID"}),e.jsx("input",{id:"proj-id",type:"text",value:o,onChange:S=>n(S.target.value),className:Be,placeholder:"kongkong",disabled:p}),x.id&&e.jsx("div",{className:Qe,children:x.id})]}),e.jsxs("div",{children:[e.jsx("label",{className:Ne,htmlFor:"proj-repo",children:"GitHub 仓库"}),e.jsx("input",{id:"proj-repo",type:"text",value:i,onChange:S=>l(S.target.value),className:Be,placeholder:"rockdai/baxian",disabled:p}),x.repo&&e.jsx("div",{className:Qe,children:x.repo})]}),e.jsxs("div",{children:[e.jsx("span",{className:Ne,children:"合并策略"}),e.jsxs("label",{className:"mb-1 flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"merge",checked:f===null,onChange:()=>b(null),disabled:p,className:"h-3.5 w-3.5 accent-[#1348dc]"}),e.jsx("span",{className:"text-[13px] text-og-800",children:"人类合并(默认)"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"merge",checked:f==="auto",onChange:()=>b("auto"),disabled:p,className:"h-3.5 w-3.5 accent-[#1348dc]"}),e.jsx("span",{className:"text-[13px] text-og-800",children:"QA Approve 后自动合并"})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-hairline pt-4",children:[e.jsx("button",{type:"button",onClick:A,disabled:p,className:"btn-secondary",children:"取消"}),e.jsx("button",{type:"submit",disabled:p,className:"btn-primary",children:p?"创建中…":"创建"})]})]})})}const Ue=/^[a-z][a-z0-9-]{1,31}$/,Kt=500,ne="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",X="mb-1.5 block text-[12px] font-medium text-og-700",qe="mt-1 text-[12px] text-danger",Se="mt-1 text-[12px] text-og-500",re="h-3.5 w-3.5 accent-[#1348dc]",We={id:"",role:"dev",pairWith:"",mode:"local",hostname:"",user:"",runtime:"",workdir:"",yolo:!0,model:"",addDirs:""};function tt({open:s,onClose:t,projectId:r,onCreated:o}){var G;const[n,i]=a.useState(We),[l,f]=a.useState(null),[b,p]=a.useState(new Set),[u,h]=a.useState(null),[m,x]=a.useState(!1),[d,v]=a.useState(!1),[c,T]=a.useState(null),$=a.useRef(null),N=a.useRef(null),A=a.useRef(0),{show:g}=ue(),{flagDirty:R}=ge();a.useEffect(()=>{if(!s)return;A.current+=1;const E=A.current;i(We),f(null),p(new Set),h(null),x(!1),T(null),O.config.get().then(M=>{if(E!==A.current)return;const j=M.project.find(C=>C.id===r)??null;f(j);const L=new Set;M.project.forEach(C=>C.agent.forEach(w=>w.forEach(y=>L.add(y.id)))),p(L)}).catch(()=>{})},[s,r]);const S=()=>{d||t()},P=a.useCallback(()=>{$.current&&$.current.abort();const E=new AbortController;$.current=E,x(!0),T(null);const M=n.mode==="remote"?{hostname:n.hostname,user:n.user||void 0}:void 0;O.agents.probe(n.mode,M,{signal:E.signal}).then(j=>{E.signal.aborted||(h(j),T(null))}).catch(j=>{E.signal.aborted||(h(null),T(j instanceof Error?j.message:String(j)))}).finally(()=>{$.current===E&&x(!1)})},[n.mode,n.hostname,n.user]);a.useEffect(()=>{if(s&&(h(null),$.current&&$.current.abort(),!(n.mode==="remote"&&!n.hostname)))return N.current&&clearTimeout(N.current),N.current=setTimeout(P,Kt),()=>{N.current&&clearTimeout(N.current)}},[s,n.mode,n.hostname,n.user,P]),a.useEffect(()=>{s||$.current&&$.current.abort()},[s]),a.useEffect(()=>()=>{$.current&&$.current.abort(),N.current&&clearTimeout(N.current)},[]);const k=(l==null?void 0:l.agent.filter(E=>E.length===1&&E[0].role==="dev").map(E=>E[0]))??[],D=k.length>0,F=Ue.test(n.id)&&!b.has(n.id),I=n.mode==="local"||n.mode==="remote"&&n.hostname.length>0,z=n.runtime!==""&&(n.runtime==="claude-code"?!!(u!=null&&u.runtimes["claude-code"].ok):!!(u!=null&&u.runtimes.codex.ok)),Q=!!(u!=null&&u.tmux.ok),U=n.mode==="local"||!!((G=u==null?void 0:u.ssh)!=null&&G.ok),J=n.role==="dev"||n.role==="qa"&&n.pairWith!=="",Y=!d&&F&&I&&J&&z&&Q&&U,H=async E=>{if(E.preventDefault(),!!Y){v(!0),T(null);try{const M=n.addDirs.split(`
2
+ `).map(C=>C.trim()).filter(C=>C.length>0),j={id:n.id,role:n.role,runtime:n.runtime,mode:n.mode,...n.mode==="remote"?{host:{hostname:n.hostname,...n.user?{user:n.user}:{}}}:{},...n.workdir?{workdir:n.workdir}:{},yolo:n.yolo,...n.model.trim()?{model:n.model.trim()}:{},...M.length>0?{addDirs:M}:{},...n.role==="qa"?{pairWith:n.pairWith}:{}},L=await O.projects.addAgent(r,j);L.restartRequired&&R(),g({kind:"success",title:`Agent ${L.agent.id} 已添加到 ${r}`}),o(),t()}catch(M){T(M instanceof Error?M.message:String(M))}finally{v(!1)}}},V=({rt:E})=>{if(n.mode==="remote"&&!n.hostname)return e.jsx("span",{className:"ml-2 text-[12px] text-og-400",children:"(请先填写 hostname)"});if(m)return e.jsx("span",{className:"ml-2 text-[12px] text-og-400",children:"…探测中"});if(!u)return e.jsx("span",{className:"ml-2 text-[12px] text-og-400",children:"?"});const j=u.runtimes[E];return j.ok?e.jsxs("span",{className:"ml-2 text-[12px] text-success",children:["✓ ",j.path??""]}):e.jsxs("span",{className:"ml-2 text-[12px] text-danger",title:j.message,children:["⨯ ",j.message]})},K=()=>n.mode==="remote"&&!n.hostname?null:m?e.jsx("div",{className:"text-[12px] text-og-400",children:"tmux: …探测中"}):u?u.tmux.ok?e.jsxs("div",{className:"text-[12px] text-success",children:["tmux: ✓ ",u.tmux.path??""]}):e.jsxs("div",{className:"text-[12px] text-danger",children:["tmux: ⨯ ",u.tmux.message]}):null,te=()=>n.mode!=="remote"||!n.hostname||!(u!=null&&u.ssh)?null:u.ssh.ok?e.jsxs("div",{className:"text-[12px] text-success",children:["SSH: ✓ ",u.ssh.message]}):e.jsxs("div",{className:"text-[12px] text-danger",children:["SSH: ⨯ ",u.ssh.message]});return e.jsx(je,{open:s,onClose:S,title:`添加 Agent 到 ${r}`,size:"lg",children:e.jsxs("form",{onSubmit:H,className:"space-y-4",children:[c&&e.jsx("div",{className:"rounded-md border border-[#fecaca] bg-[#fef2f2] px-3 py-2 text-[13px] text-danger",children:c}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"agent-id",children:"Agent ID"}),e.jsx("input",{id:"agent-id",type:"text",value:n.id,onChange:E=>i({...n,id:E.target.value}),className:ne,placeholder:"kk-cc",disabled:d}),n.id&&!Ue.test(n.id)&&e.jsx("div",{className:qe,children:"小写字母开头,只含 a-z 0-9 -,长度 2-32"}),n.id&&b.has(n.id)&&e.jsx("div",{className:qe,children:"该 id 已被占用(全局唯一)"})]}),e.jsxs("div",{children:[e.jsx("span",{className:X,children:"角色"}),e.jsxs("label",{className:"mr-4 inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"role",checked:n.role==="dev",className:re,onChange:()=>i({...n,role:"dev",pairWith:""}),disabled:d}),e.jsx("span",{className:"text-[13px] text-og-800",children:"Dev"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",title:D?"":"请先创建一个 Dev Agent",children:[e.jsx("input",{type:"radio",name:"role",checked:n.role==="qa",className:re,onChange:()=>i({...n,role:"qa"}),disabled:d||!D}),e.jsx("span",{className:`text-[13px] ${D?"text-og-800":"text-og-400"}`,children:"QA"})]})]}),n.role==="qa"&&e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"pair-with",children:"配对 Dev Agent"}),e.jsxs("select",{id:"pair-with",value:n.pairWith,onChange:E=>i({...n,pairWith:E.target.value}),className:ne,disabled:d,children:[e.jsx("option",{value:"",children:"请选择"}),k.map(E=>e.jsxs("option",{value:E.id,children:[E.id," (dev, ",E.mode,")"]},E.id))]})]}),e.jsxs("div",{children:[e.jsx("span",{className:X,children:"运行模式"}),e.jsxs("label",{className:"mr-4 inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"mode",checked:n.mode==="local",className:re,onChange:()=>i({...n,mode:"local",hostname:"",user:""}),disabled:d}),e.jsx("span",{className:"text-[13px] text-og-800",children:"本机"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"mode",checked:n.mode==="remote",className:re,onChange:()=>i({...n,mode:"remote"}),disabled:d}),e.jsx("span",{className:"text-[13px] text-og-800",children:"远程 (SSH)"})]})]}),n.mode==="remote"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"hostname",children:"Hostname"}),e.jsx("input",{id:"hostname",type:"text",value:n.hostname,onChange:E=>i({...n,hostname:E.target.value}),className:ne,placeholder:"macmini-2026",disabled:d}),e.jsx("div",{className:Se,children:"端口/私钥/跳板机请配 ~/.ssh/config"})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"user",children:"User(可选)"}),e.jsx("input",{id:"user",type:"text",value:n.user,onChange:E=>i({...n,user:E.target.value}),className:ne,placeholder:"留空则读 ~/.ssh/config 的 User",disabled:d})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-1.5 flex items-center justify-between",children:[e.jsx("span",{className:"text-[12px] font-medium text-og-700",children:"运行时"}),e.jsx("button",{type:"button",onClick:P,className:"text-[12px] text-accent transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",disabled:d||m||n.mode==="remote"&&!n.hostname,children:"↻ 重新探测"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"runtime",checked:n.runtime==="claude-code",className:re,onChange:()=>i({...n,runtime:"claude-code"}),disabled:d||(u?!u.runtimes["claude-code"].ok:!1)}),e.jsx("span",{className:"text-[13px] text-og-800",children:"Claude Code"}),e.jsx(V,{rt:"claude-code"})]}),e.jsxs("label",{className:"mt-1 flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"runtime",checked:n.runtime==="codex",className:re,onChange:()=>i({...n,runtime:"codex"}),disabled:d||(u?!u.runtimes.codex.ok:!1)}),e.jsx("span",{className:"text-[13px] text-og-800",children:"Codex"}),e.jsx(V,{rt:"codex"})]}),e.jsx("div",{className:"mt-2",children:e.jsx(K,{})}),e.jsx("div",{children:e.jsx(te,{})})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"workdir",children:"Workdir(可选)"}),e.jsx("input",{id:"workdir",type:"text",value:n.workdir,onChange:E=>i({...n,workdir:E.target.value}),className:ne,placeholder:"留空时自动 clone 到 ~/.baxian/repos/<owner>/<repo>",disabled:d})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"model",children:"Model(可选)"}),e.jsx("input",{id:"model",type:"text",value:n.model,onChange:E=>i({...n,model:E.target.value}),className:ne,placeholder:n.runtime==="codex"?"例: o3 / gpt-4o(留空走 default)":"例: sonnet / opus / claude-sonnet-4-6(留空走 default)",disabled:d}),e.jsx("div",{className:Se,children:"透传到 launch 命令的 --model 参数;留空跟随 CLI 默认。"})]}),e.jsxs("div",{children:[e.jsx("label",{className:X,htmlFor:"addDirs",children:"Additional Dirs(可选)"}),e.jsx("textarea",{id:"addDirs",value:n.addDirs,onChange:E=>i({...n,addDirs:E.target.value}),className:`${ne} font-mono text-[12px]`,rows:3,placeholder:`每行一个绝对路径,例:
3
+ /Users/me/shared-libs
4
+ /Users/me/extra-repo`,disabled:d}),e.jsx("div",{className:Se,children:"透传到 --add-dir。当前 YOLO 模式下不影响权限拦截,主要用于让 CLI 把额外目录纳入工作根。"})]}),e.jsx("div",{className:"rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-3 py-2.5",children:e.jsxs("label",{className:"flex cursor-pointer items-start gap-2",children:[e.jsx("input",{type:"checkbox",className:"mt-1 h-3.5 w-3.5 accent-[#1348dc]",checked:n.yolo,onChange:E=>i({...n,yolo:E.target.checked}),disabled:d}),e.jsxs("div",{className:"text-[13px] text-og-800",children:[e.jsx("div",{className:"font-medium",children:"YOLO 模式(推荐开启)"}),e.jsxs("div",{className:"mt-1 text-[12px] text-warn",children:["Agent 自主执行所有命令、文件改动,无需逐条确认。开启后体验更顺滑, 但",e.jsx("strong",{className:"font-semibold",children:"请确认在受控环境(容器、隔离 worktree)中运行"}),"。"]})]})]})}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-hairline pt-4",children:[e.jsx("button",{type:"button",onClick:S,disabled:d,className:"btn-secondary",children:"取消"}),e.jsx("button",{type:"submit",disabled:!Y,className:"btn-primary",children:d?"添加中…":"添加 Agent"})]})]})})}const Ge=200,He=16e3,fe="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",xe="mb-1.5 block text-[12px] font-medium text-og-700",Je="mt-1 text-right text-[12px] text-og-400";function $e(s){const t=s.mode==="edit",r=Ce(),{show:o}=ue(),n=t?s.task.projectId:s.projectId,i=t?s.task.title:"",l=t?s.task.description:"",f=t?s.task.preferredAgentId:"",[b,p]=a.useState([]),[u,h]=a.useState([]),[m,x]=a.useState(n??""),[d,v]=a.useState(f),[c,T]=a.useState(i),[$,N]=a.useState(l),[A,g]=a.useState(!1),[R,S]=a.useState(null),P=a.useRef(0);a.useEffect(()=>{if(!s.open)return;P.current+=1;const w=P.current;p([]),h([]),x(n??""),v(f),T(i),N(l),S(null),g(!1),Promise.all([O.projects.list(),O.agents.list()]).then(([y,q])=>{w===P.current&&(p(y),h(q))}).catch(y=>{w===P.current&&S(y instanceof Error?y.message:String(y))})},[s.open,n,i,l,f]);const k=a.useMemo(()=>b.find(w=>w.id===m)??null,[b,m]),D=a.useMemo(()=>k?k.agent.flat().filter(w=>w.role==="dev"):[],[k]),F=a.useMemo(()=>new Set(u.map(w=>w.id)),[u]),I=a.useMemo(()=>D.filter(w=>F.has(w.id)),[D,F]),z=a.useMemo(()=>D.filter(w=>!F.has(w.id)),[D,F]);a.useEffect(()=>{if(!t){if(I.length===0){d!==""&&v("");return}I.find(w=>w.id===d)||v(I[0].id)}},[I,d,t]);const Q=!t||I.find(w=>w.id===d),U=t&&!Q&&!!d,J=U&&z.some(w=>w.id===d),Y=J?`当前 dev "${d}" 在 baxian.json 中存在但 runtime 未加载,可能是手动编辑过配置文件;重启 server 可拉起`:U?`当前 dev "${d}" 不在 runtime(可能已从 project 配置移除);保存可能失败,请确认或选择新 dev`:!m||I.length>0?null:z.length>0?"baxian.json 里有 dev agent 但 runtime 未加载(可能是手动编辑过配置);重启 server 后生效":"请先为项目添加 dev agent",H=c.trim(),V=$.trim(),K=I.length>0||U,G=!!m&&K&&!!d&&H.length>0&&V.length>0&&!A,E=()=>{A||s.onClose()},M=async w=>{var y,q;if(w.preventDefault(),!!G){g(!0),S(null);try{if(s.mode==="edit"){const B=await O.tasks.update(s.task.id,{title:H,description:V,preferredAgentId:d});o({kind:"success",title:"任务已更新"}),(y=s.onUpdated)==null||y.call(s,B),s.onClose()}else{const B=await O.tasks.create({projectId:m,title:H,description:V,preferredAgentId:d});o({kind:"success",title:"任务已创建"}),(q=s.onCreated)==null||q.call(s,B),s.onClose(),r(`/task/${B.id}`)}}catch(B){S(B instanceof Error?B.message:String(B))}finally{g(!1)}}},j=t?"编辑 Task":"新建 Task",L=t?A?"保存中…":"保存":A?"创建中…":"创建",C=!t&&!n;return e.jsx(je,{open:s.open,onClose:E,title:j,size:"md",children:e.jsxs("form",{onSubmit:M,className:"space-y-4",children:[R&&e.jsx("div",{className:"rounded-md border border-[#fecaca] bg-[#fef2f2] px-3 py-2 text-[13px] text-danger",children:R}),C&&e.jsxs("div",{children:[e.jsx("label",{className:xe,htmlFor:"task-project",children:"Project"}),e.jsxs("select",{id:"task-project",value:m,onChange:w=>x(w.target.value),className:fe,disabled:A,required:!0,children:[e.jsx("option",{value:"",disabled:!0,children:"选择项目"}),b.map(w=>e.jsx("option",{value:w.id,children:w.id},w.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:xe,htmlFor:"task-dev",children:"Dev Agent"}),e.jsxs("select",{id:"task-dev",value:d,onChange:w=>v(w.target.value),className:fe,disabled:A||I.length===0&&!U||I.length===1&&I[0].id===d&&!U,required:!0,children:[I.length===0&&!U&&e.jsx("option",{value:"",disabled:!0,children:"无可用 dev"}),U&&e.jsxs("option",{value:d,children:[d," ",J?"(待重启)":"(不在 runtime)"]}),I.map(w=>e.jsx("option",{value:w.id,children:w.id},w.id))]}),Y&&e.jsx("div",{className:"mt-1 text-[12px] text-warn",children:Y})]}),e.jsxs("div",{children:[e.jsx("label",{className:xe,htmlFor:"task-title",children:"Title"}),e.jsx("input",{id:"task-title",type:"text",value:c,onChange:w=>T(w.target.value),maxLength:Ge,className:fe,placeholder:"一句话描述要做什么",disabled:A,required:!0}),e.jsxs("div",{className:Je,children:[c.length," / ",Ge]})]}),e.jsxs("div",{children:[e.jsx("label",{className:xe,htmlFor:"task-description",children:"Description"}),e.jsx("textarea",{id:"task-description",value:$,onChange:w=>N(w.target.value),maxLength:He,rows:8,className:`${fe} font-mono text-[12px]`,placeholder:"详细描述任务,支持 markdown",disabled:A,required:!0}),e.jsxs("div",{className:Je,children:[$.length," / ",He]})]}),e.jsxs("div",{className:"flex justify-end gap-2 border-t border-hairline pt-4",children:[e.jsx("button",{type:"button",onClick:E,disabled:A,className:"btn-secondary",children:"取消"}),e.jsx("button",{type:"submit",disabled:!G,className:"btn-primary",children:L})]})]})})}function Yt(s){return Array.from(new TextEncoder().encode(s)).map(t=>t.toString(16).padStart(2,"0")).join("")}function Zt(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/realtime`}const Xt=(s,t)=>t&&t.length>0?new WebSocket(s,t):new WebSocket(s);class es{constructor(t={}){_(this,"wsUrl");_(this,"wsFactory");_(this,"tokenProvider");_(this,"ws",null);_(this,"topics",new Map);_(this,"cache",new Map);_(this,"outbox",[]);_(this,"reconnectScheduler");_(this,"explicitlyClosed",!1);this.wsUrl=t.wsUrl??Zt(),this.wsFactory=t.wsFactory??Xt,this.tokenProvider=t.tokenProvider??Pe,this.reconnectScheduler=new Xe({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.topics.size>0})}subscribe(t,r,o){let n=this.topics.get(t);const i=!n;return n||(n={data:new Set,error:new Set},this.topics.set(t,n)),n.data.add(r),o&&n.error.add(o),i?(this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",topic:t})):this.cache.has(t)&&queueMicrotask(()=>{var l;(l=this.topics.get(t))!=null&&l.data.has(r)&&this.cache.has(t)&&r(this.cache.get(t))}),()=>this.unsubscribe(t,r,o)}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.topics.clear(),this.cache.clear(),this.outbox=[]}unsubscribe(t,r,o){const n=this.topics.get(t);n&&(n.data.delete(r),o&&n.error.delete(o),n.data.size===0&&n.error.size===0&&(this.topics.delete(t),this.cache.delete(t),this.wsSendOrQueue({op:"unsubscribe",topic:t}),this.topics.size===0&&this.teardownSocket()))}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const t=this.tokenProvider(),r=t?[`baxian.token.${Yt(t)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,r)}catch(i){console.warn("[events-client] WebSocket constructor threw:",i),this.broadcastConnectionError({code:"connection_failed",message:i instanceof Error?i.message:"WebSocket constructor threw"}),this.scheduleReconnect();return}this.ws=o;let n=!1;o.onopen=()=>{if(o!==this.ws)return;n=!0,this.reconnectScheduler.reset();for(const l of this.topics.keys())try{o.send(JSON.stringify({op:"subscribe",topic:l}))}catch(f){console.warn("[events-client] resubscribe send failed:",f)}const i=this.outbox;this.outbox=[];for(const l of i)if(!(l.op==="subscribe"||l.op==="unsubscribe"))try{o.send(JSON.stringify(l))}catch(f){console.warn("[events-client] outbox flush failed:",f)}},o.onmessage=i=>{if(o!==this.ws)return;let l;try{const f=typeof i.data=="string"?i.data:String(i.data);l=JSON.parse(f)}catch{return}this.handleMessage(l)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&(n||this.broadcastConnectionError({code:"connection_failed",message:"WebSocket failed to connect (auth, network, or proxy issue)"}),this.topics.size!==0&&this.scheduleReconnect()))},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}broadcastConnectionError(t){for(const r of this.topics.values())for(const o of[...r.error])try{o(t)}catch(n){console.error("[events-client] error handler threw on connection error:",n)}}wsSendOrQueue(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(t));return}catch(r){console.warn("[events-client] send failed, will queue:",r)}this.outbox.push(t)}handleMessage(t){switch(t.type){case"data":{const r=this.topics.get(t.topic);if(this.cache.set(t.topic,t.data),!r)return;for(const o of[...r.data])try{o(t.data)}catch(n){console.error(`[events-client] handler threw on ${t.topic}:`,n)}break}case"error":{const r={code:t.code,message:t.message};if(t.topic){const o=this.topics.get(t.topic);if(o)for(const n of[...o.error])try{n(r)}catch(i){console.error(`[events-client] error handler threw on ${t.topic}:`,i)}}else console.warn("[events-client] connection-level error:",t.code,t.message);break}}}}let ke=null;function De(){return ke||(ke=new es),ke}function st(){const[s,t]=a.useState(null),[r,o]=a.useState(!1),[n,i]=a.useState(null);return a.useEffect(()=>De().subscribe("agents",f=>{i(null),t(f),o(!0)},f=>i(f)),[]),{data:s,loaded:r,error:n}}function ts(s){const[t,r]=a.useState(null),[o,n]=a.useState(!1),[i,l]=a.useState(null);return a.useEffect(()=>(r(null),n(!1),l(null),De().subscribe(`task:${s}`,b=>{l(null),r(b),n(!0)},b=>l(b))),[s]),{data:t,loaded:o,error:i}}function ss(s){const[t,r]=a.useState(null),[o,n]=a.useState(!1),[i,l]=a.useState(null);return a.useEffect(()=>{if(!s){r(null),n(!1),l(null);return}r(null),n(!1),l(null);let f=!1,b=!1,p=!1;const u=De().subscribe(`project-tasks:${s}`,h=>{f||(b=!0,l(null),r(h),n(!0))},h=>{f||(l(h),!(b||p)&&(p=!0,O.tasks.list(s).then(m=>{f||b||(r(m),n(!0))},m=>{console.warn(`[useProjectTasks] REST fallback failed for ${s}:`,m)})))});return()=>{f=!0,u()}},[s]),{data:t,loaded:o,error:i}}function ns(){const[s,t]=a.useState([]),[r,o]=a.useState([]),[n,i]=a.useState(!1),[l,f]=a.useState(null),[b,p]=a.useState(null),[u,h]=a.useState(!1),[m,x]=a.useState(!1),[d,v]=a.useState({kind:"closed"}),c=a.useRef(0),{data:T,loaded:$,error:N}=st(),A=(N==null?void 0:N.message)??null,g=new Map((T??[]).map(k=>[k.id,k])),R=l??A??b,S=async()=>{const k=++c.current;try{const D=await O.projects.list();if(k!==c.current)return;t(D),f(null)}catch(D){if(k!==c.current)return;f(D instanceof Error?D.message:String(D))}finally{k===c.current&&i(!0)}},P=async()=>{try{const k=await O.tasks.list();o(k),p(null)}catch(k){p(k instanceof Error?k.message:String(k))}};return a.useEffect(()=>{S(),P()},[]),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-6 flex flex-wrap items-end justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"font-display text-2xl font-semibold tracking-tight text-og-1000",children:"Dashboard"}),e.jsx("p",{className:"mt-0.5 text-[13px] text-og-500",children:"Active agent workspaces across all configured repos."})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("button",{onClick:()=>h(!0),className:"btn-primary",children:"+ 新建项目"}),e.jsx("button",{onClick:()=>x(!0),disabled:s.length===0,"aria-describedby":s.length===0?"create-task-hint":void 0,className:"btn-secondary",children:"+ 新建 Task"}),s.length===0&&e.jsx("span",{id:"create-task-hint",className:"self-center text-[12px] text-og-500",children:"请先创建项目"})]})]}),R&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",R]}),n&&s.length===0&&!l&&e.jsx("div",{className:"rounded-lg border border-dashed border-og-100 bg-surface py-12 text-center text-[13px] text-og-500",children:'还没有项目。点击右上角"+ 新建项目"开始。'}),s.map(k=>e.jsxs("div",{className:"mb-10",children:[e.jsxs("div",{className:"mb-3 flex flex-wrap items-baseline gap-x-3 gap-y-1",children:[e.jsx("h2",{className:"font-display text-[17px] font-semibold tracking-tight text-og-1000",children:k.id}),e.jsx("span",{className:"min-w-0 break-words font-mono text-[12px] text-og-500",children:k.repo}),e.jsx(ce,{to:`/project/${k.id}`,className:"ml-auto text-[13px] text-accent hover:text-accent-hover",children:"Details →"})]}),k.agent.flat().length===0?e.jsx("div",{className:"rounded-lg border border-dashed border-og-100 bg-surface py-6 text-center text-[13px] text-og-500",children:"还没有 Agent。进入 Details 添加。"}):e.jsx("div",{className:"grid grid-cols-1 gap-3 xl:grid-cols-2",children:k.agent.map((D,F)=>e.jsx(et,{group:D,projectId:k.id,agentsById:g,agentsLoaded:$,agentsError:!!N,tasks:r.filter(I=>I.projectId===k.id),onDeleted:()=>{S(),P()}},D.map(I=>I.id).join(":")||F))})]},k.id)),e.jsx(Vt,{open:u,onClose:()=>h(!1),onCreated:k=>{h(!1),S(),v({kind:"asking",projectId:k})}}),e.jsx(je,{open:d.kind==="asking",onClose:()=>v({kind:"closed"}),title:"项目已创建",size:"sm",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-[13px] text-og-700",children:"现在添加第一个 Agent,还是稍后再加?"}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:()=>v({kind:"closed"}),className:"btn-secondary",children:"稍后再加"}),e.jsx("button",{type:"button",onClick:()=>{d.kind==="asking"&&v({kind:"addingAgent",projectId:d.projectId})},className:"btn-primary",children:"继续添加 Agent"})]})]})}),d.kind==="addingAgent"&&e.jsx(tt,{open:!0,projectId:d.projectId,onClose:()=>v({kind:"closed"}),onCreated:()=>{S()}}),e.jsx($e,{open:m,onClose:()=>x(!1),onCreated:()=>{P()}})]})}function nt({tasks:s}){const t=Ce();return s.length===0?e.jsx("div",{className:"rounded-lg border border-dashed border-og-100 bg-surface px-4 py-8 text-center text-[13px] text-og-400",children:"No tasks"}):e.jsx("div",{className:"overflow-hidden rounded-lg border border-hairline bg-surface",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-[13px]",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-hairline bg-og-50/40 text-left font-mono text-[11px] uppercase tracking-[0.05em] text-og-500",children:[e.jsx("th",{className:"px-4 py-2 font-medium",children:"ID"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Title"}),e.jsx("th",{className:"hidden px-4 py-2 font-medium sm:table-cell",children:"Agent"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Status"}),e.jsx("th",{className:"hidden px-4 py-2 font-medium sm:table-cell",children:"Round"})]})}),e.jsx("tbody",{children:s.map(r=>e.jsxs("tr",{className:"cursor-pointer border-t border-hairline transition-colors hover:bg-og-50/40",onClick:()=>t(`/task/${r.id}`),children:[e.jsx("td",{className:"whitespace-nowrap px-4 py-2.5 font-mono text-[12px]",children:e.jsx(ce,{to:`/task/${r.id}`,className:"text-accent hover:text-accent-hover",onClick:o=>o.stopPropagation(),children:r.id})}),e.jsx("td",{className:"px-4 py-2.5 break-words text-og-1000",children:r.title}),e.jsx("td",{className:"hidden whitespace-nowrap px-4 py-2.5 font-mono text-[12px] sm:table-cell",children:r.agentId?e.jsx("span",{className:"text-og-700",children:r.agentId}):r.preferredAgentId?e.jsx("span",{className:"italic text-og-500",children:r.preferredAgentId}):e.jsx("span",{className:"text-og-400",children:"—"})}),e.jsxs("td",{className:"whitespace-nowrap px-4 py-2.5",children:[e.jsx("span",{className:"pill",children:r.status}),r.phase==="spec"&&e.jsx("span",{className:"ml-1 pill pill-review",children:"spec"})]}),e.jsx("td",{className:"hidden whitespace-nowrap px-4 py-2.5 text-[12px] text-og-500 sm:table-cell",children:r.phase==="spec"?r.specReviewRound??0:r.reviewRound})]},r.id))})]})})})}function rs(){const{id:s}=Te(),[t,r]=a.useState(null),[o,n]=a.useState(null),[i,l]=a.useState(!1),[f,b]=a.useState(!1),p=a.useRef(0),{data:u,loaded:h,error:m}=st(),{data:x,error:d}=ss(s),v=(m==null?void 0:m.message)??null,c=(d==null?void 0:d.message)??null,T=x??[],$=new Map((u??[]).map(g=>[g.id,g])),N=o??v??c,A=a.useCallback(async g=>{const R=++p.current;try{const S=await O.projects.get(g);if(R!==p.current)return;r(S),n(null)}catch(S){if(R!==p.current)return;n(S instanceof Error?S.message:String(S))}},[]);return a.useEffect(()=>{s&&(r(null),n(null),A(s))},[s,A]),t?e.jsxs("div",{children:[N&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",N]}),e.jsxs("div",{className:"mb-6",children:[e.jsx("h1",{className:"break-words font-display text-2xl font-semibold tracking-tight text-og-1000",children:t.id}),e.jsx("p",{className:"mt-1 break-words font-mono text-[12px] text-og-500",children:t.repo})]}),e.jsxs("div",{className:"mb-3 flex flex-wrap items-baseline justify-between gap-2 border-t border-hairline pt-6",children:[e.jsx("h2",{className:"font-display text-[12px] font-semibold uppercase tracking-[0.06em] text-og-500",children:"Agents"}),e.jsx("button",{onClick:()=>l(!0),className:"btn-ghost",children:"+ 添加 Agent"})]}),t.agent.flat().length===0?e.jsx("div",{className:"mb-8 rounded-lg border border-dashed border-og-100 bg-surface py-6 text-center text-[13px] text-og-500",children:"还没有 Agent,点击右上角添加。"}):e.jsx("div",{className:"mb-8 space-y-5",children:t.agent.map((g,R)=>e.jsx(et,{group:g,projectId:t.id,agentsById:$,agentsLoaded:h,agentsError:!!m,tasks:T,onDeleted:()=>{A(t.id)},terminalMode:"embedded-full"},g.map(S=>S.id).join(":")||R))}),e.jsxs("div",{className:"mb-3 flex flex-wrap items-baseline justify-between gap-2 border-t border-hairline pt-6",children:[e.jsx("h2",{className:"font-display text-[12px] font-semibold uppercase tracking-[0.06em] text-og-500",children:"Tasks"}),e.jsx("button",{onClick:()=>b(!0),className:"btn-ghost",children:"+ 新建 Task"})]}),e.jsx(nt,{tasks:T}),e.jsx(tt,{open:i,projectId:t.id,onClose:()=>l(!1),onCreated:()=>{A(t.id)}}),e.jsx($e,{open:f,projectId:t.id,onClose:()=>b(!1)})]}):o?e.jsxs("div",{className:"text-[13px] text-danger",children:["Error: ",o]}):e.jsx("div",{className:"text-[13px] text-og-500",children:"Loading…"})}function as(){const{agentId:s}=Te();return s?e.jsxs("div",{className:"flex min-h-0 flex-1 flex-col overflow-hidden rounded-lg border border-hairline bg-surface",children:[e.jsxs("div",{className:"flex h-8 flex-none select-none items-center gap-3 border-b border-hairline bg-page px-3 font-mono text-[11px] text-og-500",children:[e.jsx("span",{"aria-hidden":!0,className:"block h-1.5 w-1.5 rounded-full bg-success"}),e.jsx("span",{className:"text-og-700",children:s})]}),e.jsx("div",{className:"min-h-0 flex-1",children:e.jsx(Re,{agentId:s,mode:"full",interactive:!0})})]}):e.jsx("div",{className:"text-[13px] text-danger",children:"No agent specified"})}function is(){const[s,t]=a.useState([]),[r,o]=a.useState(null);return a.useEffect(()=>{let n=!1;return(async()=>{try{const i=await O.tasks.list();n||t(i)}catch(i){n||o(i instanceof Error?i.message:String(i))}})(),()=>{n=!0}},[]),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-6",children:[e.jsx("h1",{className:"font-display text-2xl font-semibold tracking-tight text-og-1000",children:"Tasks"}),e.jsx("p",{className:"mt-0.5 text-[13px] text-og-500",children:"Every task across all projects."})]}),r&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",r]}),e.jsx(nt,{tasks:s})]})}const rt=new Set(["merged","failed","max_rounds","cancelled"]),Ve=rt,os={pending:"pill",in_progress:"pill pill-live",review:"pill pill-review",fixing:"pill pill-warn",approved:"pill pill-live",merged:"pill pill-live",failed:"pill pill-warn",max_rounds:"pill pill-warn",cancelled:"pill"};function cs(){const{id:s}=Te(),t=Ce(),{show:r}=ue(),[o,n]=a.useState(!1),[i,l]=a.useState(!1),[f,b]=a.useState(!1),[p,u]=a.useState(!1),[h,m]=a.useState(null),{data:x,loaded:d,error:v}=ts(s??""),c=h??x,T=(v==null?void 0:v.message)??null;a.useEffect(()=>{m(null)},[s]),a.useEffect(()=>{h&&x&&x.updatedAt>=h.updatedAt&&m(null)},[h,x]);const $=I=>{m(I)};if(!s)return e.jsx("div",{className:"text-[13px] text-danger",children:"Task ID required"});if(T&&!c)return e.jsxs("div",{className:"text-[13px] text-danger",children:["Error: ",T]});if(d&&!c)return e.jsxs("div",{className:"text-[13px] text-danger",children:["Task not found: ",s]});if(!c)return e.jsx("div",{className:"text-[13px] text-og-500",children:"Loading…"});const N=c.status==="pending",A=c.status==="pending"||c.status==="in_progress",g=Ve.has(c.status)&&!!c.preferredAgentId,R=!!c.prNumber,S=c.preferredAgentId==="",P=c.status==="approved"&&c.prNumber!==void 0,k=async()=>{if(confirm(`确定取消 task ${c.id}?`)){l(!0);try{const I=await O.tasks.update(c.id,{status:"cancelled"});$(I),r({kind:"success",title:"任务已取消"})}catch(I){r({kind:"error",title:"取消失败",body:I instanceof Error?I.message:String(I)})}finally{l(!1)}}},D=async()=>{const z=rt.has(c.status)?`task ${c.id} 已是 ${c.status} 状态。手动请 QA 重审会再跑一轮 review,但状态机不会把 QA 结果带回主流程。继续?`:`请 QA 重审 task ${c.id}?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`;if(confirm(z)){u(!0);try{const Q=await O.tasks.review(c.id);$(Q),r({kind:"success",title:`已派 QA 重审 (round ${Q.reviewRound})`})}catch(Q){r({kind:"error",title:"Review 派发失败",body:Q instanceof Error?Q.message:String(Q)})}finally{u(!1)}}},F=async()=>{const I=c.status==="merged"?`task ${c.id} 已 merged。Retry 会用同样的标题/描述新建一个 task 从头跑,确定继续?`:`Retry task ${c.id}?这会新建一个 task 从头开始,旧 task 保留为历史。`;if(confirm(I)){b(!0);try{const z=await O.tasks.retry(c.id);r({kind:"success",title:`已新建 task ${z.id}`}),t(`/task/${z.id}`)}catch(z){r({kind:"error",title:"Retry 失败",body:z instanceof Error?z.message:String(z)})}finally{b(!1)}}};return e.jsxs("div",{className:"mx-auto max-w-4xl",children:[T&&e.jsxs("div",{className:"mb-4 text-[13px] text-danger",children:["Error: ",T]}),S&&e.jsx("div",{className:"mb-4 rounded-md border border-[#fde68a] bg-[#fef3c7]/60 px-3 py-2.5 text-[12px] text-warn",children:c.status==="pending"?e.jsxs(e.Fragment,{children:["This task has no preferred dev (legacy). Click ",e.jsx("b",{className:"font-semibold",children:"Edit"})," to assign one."]}):e.jsxs(e.Fragment,{children:["This is a legacy task with no preferred dev (read-only in status ",e.jsx("b",{className:"font-semibold",children:c.status}),")."]})}),e.jsxs("div",{className:"mb-2 flex flex-wrap items-center gap-3",children:[e.jsx("span",{className:"font-mono text-[13px] text-og-500",children:c.id}),e.jsx("span",{className:os[c.status],children:c.status}),c.phase==="spec"&&e.jsx("span",{className:"pill pill-review",children:"spec phase"}),e.jsxs("span",{className:"text-[12px] text-og-500",children:["created ",c.createdAt]}),e.jsxs("span",{className:"text-[12px] text-og-500",children:["updated ",c.updatedAt]})]}),e.jsx("h1",{className:"mb-5 break-words font-display text-2xl font-semibold tracking-tight text-og-1000",children:c.title}),P&&e.jsxs("div",{className:"mb-5 rounded-lg border border-[#bbf7d0] bg-[#f0fdf4] p-4 text-[13px] text-success",children:[e.jsx("div",{className:"font-semibold",children:"QA approved · awaiting PR merge"}),e.jsx("div",{className:"mt-1 text-og-700",children:"Dev keeps the task reserved while it checks whether all human or agent feedback has been handled."}),c.prUrl&&e.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"btn-secondary mt-3 !border-[#bbf7d0] !text-success hover:!bg-[#dcfce7] hover:!border-success",children:["Open PR #",c.prNumber]})]}),e.jsx("pre",{className:"card mb-6 whitespace-pre-wrap p-4 text-[13px] text-og-800",children:c.description}),e.jsxs("div",{className:"card mb-6 grid grid-cols-1 gap-x-6 gap-y-2 p-4 text-[13px] md:grid-cols-2",children:[e.jsxs("div",{className:"text-og-500",children:["Project: ",e.jsx("span",{className:"font-mono text-og-800",children:c.projectId})]}),e.jsxs("div",{className:"text-og-500",children:["Dev: ",e.jsx("span",{className:"font-mono text-og-800",children:c.agentId||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["Preferred: ",e.jsx("span",{className:"font-mono text-og-800",children:c.preferredAgentId||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["QA: ",e.jsx("span",{className:"font-mono text-og-800",children:c.qaAgentId||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["PR:"," ",c.prNumber?c.prUrl?e.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"text-accent hover:text-accent-hover",children:["#",c.prNumber]}):e.jsxs("span",{className:"font-mono text-og-800",children:["#",c.prNumber]}):e.jsx("span",{className:"text-og-400",children:"—"})]}),e.jsxs("div",{className:"text-og-500",children:["Branch: ",e.jsx("span",{className:"font-mono text-og-800",children:c.branch||"—"})]}),e.jsxs("div",{className:"text-og-500",children:["Round: ",e.jsx("span",{className:"font-mono text-og-800",children:c.reviewRound}),c.specReviewRound!==void 0&&c.specReviewRound>0&&e.jsxs("span",{className:"ml-2 text-[12px] text-accent",children:["spec: ",c.specReviewRound]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",disabled:!N,onClick:()=>n(!0),className:"btn-secondary",children:"Edit"}),e.jsx("button",{type:"button",disabled:!A||i,onClick:k,className:"btn-secondary !border-[#fecaca] !text-danger hover:!bg-[#fef2f2] hover:!border-danger",children:i?"Cancelling…":"Cancel"}),e.jsx("button",{type:"button",disabled:!g||f,onClick:F,title:Ve.has(c.status)?S?"Legacy task has no preferred dev to retry against":"新建一个 task 从头跑,丢弃当前 worktree/branch":`Cannot retry in status ${c.status}`,className:"btn-secondary",children:f?"Retrying…":"Retry"}),e.jsx("button",{type:"button",disabled:!R||p,onClick:D,title:c.prNumber?"让 QA agent 立即开始新一轮 review(reviewRound +1)":"该 task 还没有 PR,无法派 review",className:"btn-secondary !border-accent-soft !text-accent hover:!bg-accent-soft hover:!border-accent",children:p?"Dispatching…":"Request QA review"})]}),e.jsx($e,{mode:"edit",open:o,onClose:()=>n(!1),task:c,onUpdated:$})]})}function ls(){const{phase:s,count:t,error:r,triggerRestart:o}=ge();return s==="idle"?null:s==="failed"?e.jsxs("div",{className:"flex items-center justify-between border-b border-[#fecaca] bg-[#fef2f2] px-4 py-2",children:[e.jsxs("div",{className:"text-[13px] text-danger",children:["❌ 重启失败:",r]}),e.jsx("button",{onClick:()=>{o()},className:"btn-ghost !text-danger hover:!bg-[#fef2f2]",children:"重试"})]}):s==="restarting"?e.jsx("div",{className:"border-b border-accent-soft bg-accent-soft/40 px-4 py-2 text-[13px] text-accent",children:"🔄 重启中…"}):e.jsxs("div",{className:"flex items-center justify-between border-b border-[#fde68a] bg-[#fef3c7]/60 px-4 py-2",children:[e.jsxs("div",{className:"text-[13px] text-warn",children:["⚠️ 有 ",t," 项配置变更待重启 baxian server 才生效"]}),e.jsx("button",{onClick:()=>{o()},className:"btn-secondary !border-warn !text-warn hover:!bg-[#fef3c7] hover:!border-warn hover:!text-warn",children:"现在重启"})]})}const Ke=({isActive:s})=>["rounded-md px-2.5 py-1 text-[13px] transition-colors",s?"bg-og-50 text-og-1000":"text-og-500 hover:bg-og-50 hover:text-og-800"].join(" ");function ds(){return e.jsx(ht,{children:e.jsxs("div",{className:"flex h-screen flex-col bg-page",children:[e.jsxs("nav",{className:"flex h-12 flex-none items-center gap-4 border-b border-hairline bg-surface px-6",children:[e.jsxs(ve,{to:"/",end:!0,className:"flex items-center gap-2 font-display text-[15px] font-semibold tracking-tight text-og-1000",children:[e.jsx("span",{"aria-hidden":!0,className:"block h-2.5 w-2.5 rounded-sm bg-accent"}),"baxian"]}),e.jsx(ve,{to:"/",end:!0,className:Ke,children:"Dashboard"}),e.jsx(ve,{to:"/tasks",className:Ke,children:"Tasks"})]}),e.jsx(ls,{}),e.jsx("main",{className:"flex min-h-0 flex-1 flex-col overflow-y-auto p-6",children:e.jsxs(ft,{children:[e.jsx(oe,{path:"/",element:e.jsx(ns,{})}),e.jsx(oe,{path:"/project/:id",element:e.jsx(rs,{})}),e.jsx(oe,{path:"/terminal/:agentId",element:e.jsx(as,{})}),e.jsx(oe,{path:"/tasks",element:e.jsx(is,{})}),e.jsx(oe,{path:"/task/:id",element:e.jsx(cs,{})})]})})]})})}function us({children:s}){const[t,r]=a.useState({kind:"probing"}),o=a.useRef(t);a.useEffect(()=>{o.current=t},[t]);const n=a.useCallback(async()=>{r({kind:"probing"});try{await O.config.get(),r({kind:"authorized"})}catch(i){if(i instanceof me&&i.status===401){r({kind:"unauthorized"});return}const l=i instanceof Error?i.message:"无法连接服务器";r({kind:"error",message:l})}},[]);return a.useEffect(()=>{n()},[n]),a.useEffect(()=>{const i=()=>{o.current.kind!=="probing"&&r({kind:"unauthorized",message:"登录已失效,请重新输入令牌"})};return window.addEventListener(Ee,i),()=>window.removeEventListener(Ee,i)},[]),t.kind==="authorized"?e.jsx(e.Fragment,{children:s}):t.kind==="error"?e.jsxs(Ae,{title:"无法连接服务器",children:[e.jsx("p",{className:"text-[13px] text-og-600",children:t.message}),e.jsx("button",{type:"button",onClick:()=>{n()},className:"btn-primary mt-4 w-full",children:"重试"})]}):t.kind==="probing"?e.jsx(Ae,{title:"加载中",children:e.jsx("p",{className:"text-[13px] text-og-500",children:"正在检查登录状态…"})}):e.jsx(hs,{message:t.message,onSubmit:async i=>{xt(i);try{await O.config.get(),r({kind:"authorized"})}catch(l){if(mt(),l instanceof me&&l.status===401){r({kind:"unauthorized",message:"令牌无效,请重试"});return}const f=l instanceof Error?l.message:"登录失败";r({kind:"error",message:f})}}})}function Ae({title:s,children:t}){return e.jsx("div",{className:"flex min-h-screen items-center justify-center bg-page px-4",children:e.jsxs("div",{className:"w-full max-w-sm rounded-lg border border-hairline bg-surface px-6 py-6",children:[e.jsx("h1",{className:"mb-3 font-display text-[16px] font-semibold tracking-tight text-og-1000",children:s}),t]})})}function hs({message:s,onSubmit:t}){const[r,o]=a.useState(""),[n,i]=a.useState(!1),[l,f]=a.useState(void 0),b=async u=>{u.preventDefault();const h=r.trim();if(!h){f("请输入访问令牌");return}f(void 0),i(!0);try{await t(h)}finally{i(!1)}},p=l??s;return e.jsxs(Ae,{title:"登录 baxian",children:[e.jsx("p",{className:"mb-4 text-[13px] text-og-600",children:"服务器开启了访问鉴权,请输入访问令牌继续。"}),e.jsxs("form",{onSubmit:u=>{b(u)},children:[e.jsx("label",{className:"mb-1.5 block text-[12px] font-medium text-og-700",htmlFor:"baxian-token",children:"访问令牌"}),e.jsx("input",{id:"baxian-token",type:"password",autoComplete:"current-password",autoFocus:!0,value:r,onChange:u=>o(u.target.value),className:"w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 font-mono text-[13px] text-og-800 placeholder:text-og-400 focus:border-accent focus:outline-none focus:ring-[3px] focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-50",placeholder:"请输入服务器配置的 token",disabled:n}),p&&e.jsx("p",{role:"alert",className:"mt-2 text-[12px] text-danger",children:p}),e.jsx("button",{type:"submit",disabled:n,className:"btn-primary mt-4 w-full",children:n?"登录中…":"登录"})]})]})}lt.createRoot(document.getElementById("root")).render(e.jsx(a.StrictMode,{children:e.jsx(Et,{children:e.jsx(wt,{children:e.jsx(us,{children:e.jsx(ds,{})})})})}));
@@ -9,4 +9,4 @@ import{r as i}from"./react-BG4Iuztk.js";/**
9
9
  * @license MIT
10
10
  */var fe="popstate";function de(e){return typeof e=="object"&&e!=null&&"pathname"in e&&"search"in e&&"hash"in e&&"state"in e&&"key"in e}function Ue(e={}){function t(r,a){var c;let o=(c=a.state)==null?void 0:c.masked,{pathname:l,search:s,hash:u}=o||r.location;return Z("",{pathname:l,search:s,hash:u},a.state&&a.state.usr||null,a.state&&a.state.key||"default",o?{pathname:r.location.pathname,search:r.location.search,hash:r.location.hash}:void 0)}function n(r,a){return typeof a=="string"?a:O(a)}return He(t,n,null,e)}function E(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function L(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function We(){return Math.random().toString(36).substring(2,10)}function he(e,t){return{usr:e.state,key:e.key,idx:t,masked:e.unstable_mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function Z(e,t,n=null,r,a){return{pathname:typeof e=="string"?e:e.pathname,search:"",hash:"",...typeof t=="string"?N(t):t,state:n,key:t&&t.key||r||We(),unstable_mask:a}}function O({pathname:e="/",search:t="",hash:n=""}){return t&&t!=="?"&&(e+=t.charAt(0)==="?"?t:"?"+t),n&&n!=="#"&&(e+=n.charAt(0)==="#"?n:"#"+n),e}function N(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substring(n),e=e.substring(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substring(r),e=e.substring(0,r)),e&&(t.pathname=e)}return t}function He(e,t,n,r={}){let{window:a=document.defaultView,v5Compat:o=!1}=r,l=a.history,s="POP",u=null,c=d();c==null&&(c=0,l.replaceState({...l.state,idx:c},""));function d(){return(l.state||{idx:null}).idx}function f(){s="POP";let p=d(),h=p==null?null:p-c;c=p,u&&u({action:s,location:y.location,delta:h})}function m(p,h){s="PUSH";let R=de(p)?p:Z(y.location,p,h);c=d()+1;let w=he(R,c),C=y.createHref(R.unstable_mask||R);try{l.pushState(w,"",C)}catch(x){if(x instanceof DOMException&&x.name==="DataCloneError")throw x;a.location.assign(C)}o&&u&&u({action:s,location:y.location,delta:1})}function g(p,h){s="REPLACE";let R=de(p)?p:Z(y.location,p,h);c=d();let w=he(R,c),C=y.createHref(R.unstable_mask||R);l.replaceState(w,"",C),o&&u&&u({action:s,location:y.location,delta:0})}function v(p){return ze(p)}let y={get action(){return s},get location(){return e(a,l)},listen(p){if(u)throw new Error("A history only accepts one active listener");return a.addEventListener(fe,f),u=p,()=>{a.removeEventListener(fe,f),u=null}},createHref(p){return t(a,p)},createURL:v,encodeLocation(p){let h=v(p);return{pathname:h.pathname,search:h.search,hash:h.hash}},push:m,replace:g,go(p){return l.go(p)}};return y}function ze(e,t=!1){let n="http://localhost";typeof window<"u"&&(n=window.location.origin!=="null"?window.location.origin:window.location.href),E(n,"No window.location.(origin|href) available to create URL");let r=typeof e=="string"?e:O(e);return r=r.replace(/ $/,"%20"),!t&&r.startsWith("//")&&(r=n+r),new URL(r,n)}function ve(e,t,n="/"){return je(e,t,n,!1)}function je(e,t,n,r){let a=typeof t=="string"?N(t):t,o=$(a.pathname||"/",n);if(o==null)return null;let l=Re(e);Ve(l);let s=null;for(let u=0;s==null&&u<l.length;++u){let c=rt(o);s=et(l[u],c,r)}return s}function Re(e,t=[],n=[],r="",a=!1){let o=(l,s,u=a,c)=>{let d={relativePath:c===void 0?l.path||"":c,caseSensitive:l.caseSensitive===!0,childrenIndex:s,route:l};if(d.relativePath.startsWith("/")){if(!d.relativePath.startsWith(r)&&u)return;E(d.relativePath.startsWith(r),`Absolute route path "${d.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),d.relativePath=d.relativePath.slice(r.length)}let f=S([r,d.relativePath]),m=n.concat(d);l.children&&l.children.length>0&&(E(l.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${f}".`),Re(l.children,t,m,f,u)),!(l.path==null&&!l.index)&&t.push({path:f,score:Qe(f,l.index),routesMeta:m})};return e.forEach((l,s)=>{var u;if(l.path===""||!((u=l.path)!=null&&u.includes("?")))o(l,s);else for(let c of we(l.path))o(l,s,!0,c)}),t}function we(e){let t=e.split("/");if(t.length===0)return[];let[n,...r]=t,a=n.endsWith("?"),o=n.replace(/\?$/,"");if(r.length===0)return a?[o,""]:[o];let l=we(r.join("/")),s=[];return s.push(...l.map(u=>u===""?o:[o,u].join("/"))),a&&s.push(...l),s.map(u=>e.startsWith("/")&&u===""?"/":u)}function Ve(e){e.sort((t,n)=>t.score!==n.score?n.score-t.score:Ze(t.routesMeta.map(r=>r.childrenIndex),n.routesMeta.map(r=>r.childrenIndex)))}var Je=/^:[\w-]+$/,Ke=3,qe=2,Ye=1,Ge=10,Xe=-2,me=e=>e==="*";function Qe(e,t){let n=e.split("/"),r=n.length;return n.some(me)&&(r+=Xe),t&&(r+=qe),n.filter(a=>!me(a)).reduce((a,o)=>a+(Je.test(o)?Ke:o===""?Ye:Ge),r)}function Ze(e,t){return e.length===t.length&&e.slice(0,-1).every((r,a)=>r===t[a])?e[e.length-1]-t[t.length-1]:0}function et(e,t,n=!1){let{routesMeta:r}=e,a={},o="/",l=[];for(let s=0;s<r.length;++s){let u=r[s],c=s===r.length-1,d=o==="/"?t:t.slice(o.length)||"/",f=V({path:u.relativePath,caseSensitive:u.caseSensitive,end:c},d),m=u.route;if(!f&&c&&n&&!r[r.length-1].route.index&&(f=V({path:u.relativePath,caseSensitive:u.caseSensitive,end:!1},d)),!f)return null;Object.assign(a,f.params),l.push({params:a,pathname:S([o,f.pathname]),pathnameBase:lt(S([o,f.pathnameBase])),route:m}),f.pathnameBase!=="/"&&(o=S([o,f.pathnameBase]))}return l}function V(e,t){typeof e=="string"&&(e={path:e,caseSensitive:!1,end:!0});let[n,r]=tt(e.path,e.caseSensitive,e.end),a=t.match(n);if(!a)return null;let o=a[0],l=o.replace(/(.)\/+$/,"$1"),s=a.slice(1);return{params:r.reduce((c,{paramName:d,isOptional:f},m)=>{if(d==="*"){let v=s[m]||"";l=o.slice(0,o.length-v.length).replace(/(.)\/+$/,"$1")}const g=s[m];return f&&!g?c[d]=void 0:c[d]=(g||"").replace(/%2F/g,"/"),c},{}),pathname:o,pathnameBase:l,pattern:e}}function tt(e,t=!1,n=!0){L(e==="*"||!e.endsWith("*")||e.endsWith("/*"),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,"/*")}".`);let r=[],a="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(l,s,u,c,d)=>{if(r.push({paramName:s,isOptional:u!=null}),u){let f=d.charAt(c+l.length);return f&&f!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return e.endsWith("*")?(r.push({paramName:"*"}),a+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?a+="\\/*$":e!==""&&e!=="/"&&(a+="(?:(?=\\/|$))"),[new RegExp(a,t?void 0:"i"),r]}function rt(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return L(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function $(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&r!=="/"?null:e.slice(n)||"/"}var nt=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function at(e,t="/"){let{pathname:n,search:r="",hash:a=""}=typeof e=="string"?N(e):e,o;return n?(n=xe(n),n.startsWith("/")?o=pe(n.substring(1),"/"):o=pe(n,t)):o=t,{pathname:o,search:it(r),hash:st(a)}}function pe(e,t){let n=J(t).split("/");return e.split("/").forEach(a=>{a===".."?n.length>1&&n.pop():a!=="."&&n.push(a)}),n.length>1?n.join("/"):"/"}function G(e,t,n,r){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${n}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function ot(e){return e.filter((t,n)=>n===0||t.route.path&&t.route.path.length>0)}function Ee(e){let t=ot(e);return t.map((n,r)=>r===t.length-1?n.pathname:n.pathnameBase)}function te(e,t,n,r=!1){let a;typeof e=="string"?a=N(e):(a={...e},E(!a.pathname||!a.pathname.includes("?"),G("?","pathname","search",a)),E(!a.pathname||!a.pathname.includes("#"),G("#","pathname","hash",a)),E(!a.search||!a.search.includes("#"),G("#","search","hash",a)));let o=e===""||a.pathname==="",l=o?"/":a.pathname,s;if(l==null)s=n;else{let f=t.length-1;if(!r&&l.startsWith("..")){let m=l.split("/");for(;m[0]==="..";)m.shift(),f-=1;a.pathname=m.join("/")}s=f>=0?t[f]:"/"}let u=at(a,s),c=l&&l!=="/"&&l.endsWith("/"),d=(o||l===".")&&n.endsWith("/");return!u.pathname.endsWith("/")&&(c||d)&&(u.pathname+="/"),u}var xe=e=>e.replace(/\/\/+/g,"/"),S=e=>xe(e.join("/")),J=e=>e.replace(/\/+$/,""),lt=e=>J(e).replace(/^\/*/,"/"),it=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,st=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e,ut=class{constructor(e,t,n,r=!1){this.status=e,this.statusText=t||"",this.internal=r,n instanceof Error?(this.data=n.toString(),this.error=n):this.data=n}};function ct(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}function ft(e){let t=e.map(n=>n.route.path).filter(Boolean);return S(t)||"/"}var Ce=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function be(e,t){let n=e;if(typeof n!="string"||!nt.test(n))return{absoluteURL:void 0,isExternal:!1,to:n};let r=n,a=!1;if(Ce)try{let o=new URL(window.location.href),l=n.startsWith("//")?new URL(o.protocol+n):new URL(n),s=$(l.pathname,t);l.origin===o.origin&&s!=null?n=s+l.search+l.hash:a=!0}catch{L(!1,`<Link to="${n}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:a,to:n}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var Se=["POST","PUT","PATCH","DELETE"];new Set(Se);var dt=["GET",...Se];new Set(dt);var _=i.createContext(null);_.displayName="DataRouter";var K=i.createContext(null);K.displayName="DataRouterState";var Pe=i.createContext(!1);function ht(){return i.useContext(Pe)}var Le=i.createContext({isTransitioning:!1});Le.displayName="ViewTransition";var mt=i.createContext(new Map);mt.displayName="Fetchers";var pt=i.createContext(null);pt.displayName="Await";var b=i.createContext(null);b.displayName="Navigation";var A=i.createContext(null);A.displayName="Location";var k=i.createContext({outlet:null,matches:[],isDataRoute:!1});k.displayName="Route";var re=i.createContext(null);re.displayName="RouteError";var ke="REACT_ROUTER_ERROR",yt="REDIRECT",gt="ROUTE_ERROR_RESPONSE";function vt(e){if(e.startsWith(`${ke}:${yt}:{`))try{let t=JSON.parse(e.slice(28));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.location=="string"&&typeof t.reloadDocument=="boolean"&&typeof t.replace=="boolean")return t}catch{}}function Rt(e){if(e.startsWith(`${ke}:${gt}:{`))try{let t=JSON.parse(e.slice(40));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string")return new ut(t.status,t.statusText,t.data)}catch{}}function wt(e,{relative:t}={}){E(U(),"useHref() may be used only in the context of a <Router> component.");let{basename:n,navigator:r}=i.useContext(b),{hash:a,pathname:o,search:l}=W(e,{relative:t}),s=o;return n!=="/"&&(s=o==="/"?n:S([n,o])),r.createHref({pathname:s,search:l,hash:a})}function U(){return i.useContext(A)!=null}function T(){return E(U(),"useLocation() may be used only in the context of a <Router> component."),i.useContext(A).location}var $e="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Te(e){i.useContext(b).static||i.useLayoutEffect(e)}function Et(){let{isDataRoute:e}=i.useContext(k);return e?Nt():xt()}function xt(){E(U(),"useNavigate() may be used only in the context of a <Router> component.");let e=i.useContext(_),{basename:t,navigator:n}=i.useContext(b),{matches:r}=i.useContext(k),{pathname:a}=T(),o=JSON.stringify(Ee(r)),l=i.useRef(!1);return Te(()=>{l.current=!0}),i.useCallback((u,c={})=>{if(L(l.current,$e),!l.current)return;if(typeof u=="number"){n.go(u);return}let d=te(u,JSON.parse(o),a,c.relative==="path");e==null&&t!=="/"&&(d.pathname=d.pathname==="/"?t:S([t,d.pathname])),(c.replace?n.replace:n.push)(d,c.state,c)},[t,n,o,a,e])}i.createContext(null);function gr(){let{matches:e}=i.useContext(k),t=e[e.length-1];return(t==null?void 0:t.params)??{}}function W(e,{relative:t}={}){let{matches:n}=i.useContext(k),{pathname:r}=T(),a=JSON.stringify(Ee(n));return i.useMemo(()=>te(e,JSON.parse(a),r,t==="path"),[e,a,r,t])}function Ct(e,t){return De(e,t)}function De(e,t,n){var p;E(U(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:r}=i.useContext(b),{matches:a}=i.useContext(k),o=a[a.length-1],l=o?o.params:{},s=o?o.pathname:"/",u=o?o.pathnameBase:"/",c=o&&o.route;{let h=c&&c.path||"";Ie(s,!c||h.endsWith("*")||h.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${s}" (under <Route path="${h}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
11
11
 
12
- Please change the parent <Route path="${h}"> to <Route path="${h==="/"?"*":`${h}/*`}">.`)}let d=T(),f;if(t){let h=typeof t=="string"?N(t):t;E(u==="/"||((p=h.pathname)==null?void 0:p.startsWith(u)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${u}" but pathname "${h.pathname}" was given in the \`location\` prop.`),f=h}else f=d;let m=f.pathname||"/",g=m;if(u!=="/"){let h=u.replace(/^\//,"").split("/");g="/"+m.replace(/^\//,"").split("/").slice(h.length).join("/")}let v=ve(e,{pathname:g});L(c||v!=null,`No routes matched location "${f.pathname}${f.search}${f.hash}" `),L(v==null||v[v.length-1].route.element!==void 0||v[v.length-1].route.Component!==void 0||v[v.length-1].route.lazy!==void 0,`Matched leaf route at location "${f.pathname}${f.search}${f.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let y=kt(v&&v.map(h=>Object.assign({},h,{params:Object.assign({},l,h.params),pathname:S([u,r.encodeLocation?r.encodeLocation(h.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:h.pathname]),pathnameBase:h.pathnameBase==="/"?u:S([u,r.encodeLocation?r.encodeLocation(h.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:h.pathnameBase])})),a,n);return t&&y?i.createElement(A.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...f},navigationType:"POP"}},y):y}function bt(){let e=It(),t=ct(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r="rgba(200,200,200, 0.5)",a={padding:"0.5rem",backgroundColor:r},o={padding:"2px 4px",backgroundColor:r},l=null;return console.error("Error handled by React Router default ErrorBoundary:",e),l=i.createElement(i.Fragment,null,i.createElement("p",null,"💿 Hey developer 👋"),i.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",i.createElement("code",{style:o},"ErrorBoundary")," or"," ",i.createElement("code",{style:o},"errorElement")," prop on your route.")),i.createElement(i.Fragment,null,i.createElement("h2",null,"Unexpected Application Error!"),i.createElement("h3",{style:{fontStyle:"italic"}},t),n?i.createElement("pre",{style:a},n):null,l)}var St=i.createElement(bt,null),Fe=class extends i.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error("React Router caught the following error during render",e)}render(){let e=this.state.error;if(this.context&&typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){const n=Rt(e.digest);n&&(e=n)}let t=e!==void 0?i.createElement(k.Provider,{value:this.props.routeContext},i.createElement(re.Provider,{value:e,children:this.props.component})):this.props.children;return this.context?i.createElement(Pt,{error:e},t):t}};Fe.contextType=Pe;var X=new WeakMap;function Pt({children:e,error:t}){let{basename:n}=i.useContext(b);if(typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){let r=vt(t.digest);if(r){let a=X.get(t);if(a)throw a;let o=be(r.location,n);if(Ce&&!X.get(t))if(o.isExternal||r.reloadDocument)window.location.href=o.absoluteURL||o.to;else{const l=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(o.to,{replace:r.replace}));throw X.set(t,l),l}return i.createElement("meta",{httpEquiv:"refresh",content:`0;url=${o.absoluteURL||o.to}`})}}return e}function Lt({routeContext:e,match:t,children:n}){let r=i.useContext(_);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),i.createElement(k.Provider,{value:e},n)}function kt(e,t=[],n){let r=n==null?void 0:n.state;if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let a=e,o=r==null?void 0:r.errors;if(o!=null){let d=a.findIndex(f=>f.route.id&&(o==null?void 0:o[f.route.id])!==void 0);E(d>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),a=a.slice(0,Math.min(a.length,d+1))}let l=!1,s=-1;if(n&&r){l=r.renderFallback;for(let d=0;d<a.length;d++){let f=a[d];if((f.route.HydrateFallback||f.route.hydrateFallbackElement)&&(s=d),f.route.id){let{loaderData:m,errors:g}=r,v=f.route.loader&&!m.hasOwnProperty(f.route.id)&&(!g||g[f.route.id]===void 0);if(f.route.lazy||v){n.isStatic&&(l=!0),s>=0?a=a.slice(0,s+1):a=[a[0]];break}}}}let u=n==null?void 0:n.onError,c=r&&u?(d,f)=>{var m,g;u(d,{location:r.location,params:((g=(m=r.matches)==null?void 0:m[0])==null?void 0:g.params)??{},unstable_pattern:ft(r.matches),errorInfo:f})}:void 0;return a.reduceRight((d,f,m)=>{let g,v=!1,y=null,p=null;r&&(g=o&&f.route.id?o[f.route.id]:void 0,y=f.route.errorElement||St,l&&(s<0&&m===0?(Ie("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),v=!0,p=null):s===m&&(v=!0,p=f.route.hydrateFallbackElement||null)));let h=t.concat(a.slice(0,m+1)),R=()=>{let w;return g?w=y:v?w=p:f.route.Component?w=i.createElement(f.route.Component,null):f.route.element?w=f.route.element:w=d,i.createElement(Lt,{match:f,routeContext:{outlet:d,matches:h,isDataRoute:r!=null},children:w})};return r&&(f.route.ErrorBoundary||f.route.errorElement||m===0)?i.createElement(Fe,{location:r.location,revalidation:r.revalidation,component:y,error:g,children:R(),routeContext:{outlet:null,matches:h,isDataRoute:!0},onError:c}):R()},null)}function ne(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function $t(e){let t=i.useContext(_);return E(t,ne(e)),t}function Tt(e){let t=i.useContext(K);return E(t,ne(e)),t}function Dt(e){let t=i.useContext(k);return E(t,ne(e)),t}function ae(e){let t=Dt(e),n=t.matches[t.matches.length-1];return E(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Ft(){return ae("useRouteId")}function It(){var r;let e=i.useContext(re),t=Tt("useRouteError"),n=ae("useRouteError");return e!==void 0?e:(r=t.errors)==null?void 0:r[n]}function Nt(){let{router:e}=$t("useNavigate"),t=ae("useNavigate"),n=i.useRef(!1);return Te(()=>{n.current=!0}),i.useCallback(async(a,o={})=>{L(n.current,$e),n.current&&(typeof a=="number"?await e.navigate(a):await e.navigate(a,{fromRouteId:t,...o}))},[e,t])}var ye={};function Ie(e,t,n){!t&&!ye[e]&&(ye[e]=!0,L(!1,n))}i.memo(_t);function _t({routes:e,future:t,state:n,isStatic:r,onError:a}){return De(e,void 0,{state:n,isStatic:r,onError:a})}function Bt(e){E(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function Mt({basename:e="/",children:t=null,location:n,navigationType:r="POP",navigator:a,static:o=!1,unstable_useTransitions:l}){E(!U(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let s=e.replace(/^\/*/,"/"),u=i.useMemo(()=>({basename:s,navigator:a,static:o,unstable_useTransitions:l,future:{}}),[s,a,o,l]);typeof n=="string"&&(n=N(n));let{pathname:c="/",search:d="",hash:f="",state:m=null,key:g="default",unstable_mask:v}=n,y=i.useMemo(()=>{let p=$(c,s);return p==null?null:{location:{pathname:p,search:d,hash:f,state:m,key:g,unstable_mask:v},navigationType:r}},[s,c,d,f,m,g,r,v]);return L(y!=null,`<Router basename="${s}"> is not able to match the URL "${c}${d}${f}" because it does not start with the basename, so the <Router> won't render anything.`),y==null?null:i.createElement(b.Provider,{value:u},i.createElement(A.Provider,{children:t,value:y}))}function vr({children:e,location:t}){return Ct(ee(e),t)}function ee(e,t=[]){let n=[];return i.Children.forEach(e,(r,a)=>{if(!i.isValidElement(r))return;let o=[...t,a];if(r.type===i.Fragment){n.push.apply(n,ee(r.props.children,o));return}E(r.type===Bt,`[${typeof r.type=="string"?r.type:r.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),E(!r.props.index||!r.props.children,"An index route cannot have child routes.");let l={id:r.props.id||o.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(l.children=ee(r.props.children,o)),n.push(l)}),n}var z="get",j="application/x-www-form-urlencoded";function q(e){return typeof HTMLElement<"u"&&e instanceof HTMLElement}function Ot(e){return q(e)&&e.tagName.toLowerCase()==="button"}function At(e){return q(e)&&e.tagName.toLowerCase()==="form"}function Ut(e){return q(e)&&e.tagName.toLowerCase()==="input"}function Wt(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Ht(e,t){return e.button===0&&(!t||t==="_self")&&!Wt(e)}var H=null;function zt(){if(H===null)try{new FormData(document.createElement("form"),0),H=!1}catch{H=!0}return H}var jt=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Q(e){return e!=null&&!jt.has(e)?(L(!1,`"${e}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${j}"`),null):e}function Vt(e,t){let n,r,a,o,l;if(At(e)){let s=e.getAttribute("action");r=s?$(s,t):null,n=e.getAttribute("method")||z,a=Q(e.getAttribute("enctype"))||j,o=new FormData(e)}else if(Ot(e)||Ut(e)&&(e.type==="submit"||e.type==="image")){let s=e.form;if(s==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let u=e.getAttribute("formaction")||s.getAttribute("action");if(r=u?$(u,t):null,n=e.getAttribute("formmethod")||s.getAttribute("method")||z,a=Q(e.getAttribute("formenctype"))||Q(s.getAttribute("enctype"))||j,o=new FormData(s,e),!zt()){let{name:c,type:d,value:f}=e;if(d==="image"){let m=c?`${c}.`:"";o.append(`${m}x`,"0"),o.append(`${m}y`,"0")}else c&&o.append(c,f)}}else{if(q(e))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');n=z,r=null,a=j,l=e}return o&&a==="text/plain"&&(l=o,o=void 0),{action:r,method:n.toLowerCase(),encType:a,formData:o,body:l}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function oe(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function Ne(e,t,n,r){let a=typeof e=="string"?new URL(e,typeof window>"u"?"server://singlefetch/":window.location.origin):e;return n?a.pathname.endsWith("/")?a.pathname=`${a.pathname}_.${r}`:a.pathname=`${a.pathname}.${r}`:a.pathname==="/"?a.pathname=`_root.${r}`:t&&$(a.pathname,t)==="/"?a.pathname=`${J(t)}/_root.${r}`:a.pathname=`${J(a.pathname)}.${r}`,a}async function Jt(e,t){if(e.id in t)return t[e.id];try{let n=await import(e.module);return t[e.id]=n,n}catch(n){return console.error(`Error loading route module \`${e.module}\`, reloading page...`),console.error(n),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function Kt(e){return e==null?!1:e.href==null?e.rel==="preload"&&typeof e.imageSrcSet=="string"&&typeof e.imageSizes=="string":typeof e.rel=="string"&&typeof e.href=="string"}async function qt(e,t,n){let r=await Promise.all(e.map(async a=>{let o=t.routes[a.route.id];if(o){let l=await Jt(o,n);return l.links?l.links():[]}return[]}));return Qt(r.flat(1).filter(Kt).filter(a=>a.rel==="stylesheet"||a.rel==="preload").map(a=>a.rel==="stylesheet"?{...a,rel:"prefetch",as:"style"}:{...a,rel:"prefetch"}))}function ge(e,t,n,r,a,o){let l=(u,c)=>n[c]?u.route.id!==n[c].route.id:!0,s=(u,c)=>{var d;return n[c].pathname!==u.pathname||((d=n[c].route.path)==null?void 0:d.endsWith("*"))&&n[c].params["*"]!==u.params["*"]};return o==="assets"?t.filter((u,c)=>l(u,c)||s(u,c)):o==="data"?t.filter((u,c)=>{var f;let d=r.routes[u.route.id];if(!d||!d.hasLoader)return!1;if(l(u,c)||s(u,c))return!0;if(u.route.shouldRevalidate){let m=u.route.shouldRevalidate({currentUrl:new URL(a.pathname+a.search+a.hash,window.origin),currentParams:((f=n[0])==null?void 0:f.params)||{},nextUrl:new URL(e,window.origin),nextParams:u.params,defaultShouldRevalidate:!0});if(typeof m=="boolean")return m}return!0}):[]}function Yt(e,t,{includeHydrateFallback:n}={}){return Gt(e.map(r=>{let a=t.routes[r.route.id];if(!a)return[];let o=[a.module];return a.clientActionModule&&(o=o.concat(a.clientActionModule)),a.clientLoaderModule&&(o=o.concat(a.clientLoaderModule)),n&&a.hydrateFallbackModule&&(o=o.concat(a.hydrateFallbackModule)),a.imports&&(o=o.concat(a.imports)),o}).flat(1))}function Gt(e){return[...new Set(e)]}function Xt(e){let t={},n=Object.keys(e).sort();for(let r of n)t[r]=e[r];return t}function Qt(e,t){let n=new Set;return new Set(t),e.reduce((r,a)=>{let o=JSON.stringify(Xt(a));return n.has(o)||(n.add(o),r.push({key:o,link:a})),r},[])}function le(){let e=i.useContext(_);return oe(e,"You must render this element inside a <DataRouterContext.Provider> element"),e}function Zt(){let e=i.useContext(K);return oe(e,"You must render this element inside a <DataRouterStateContext.Provider> element"),e}var ie=i.createContext(void 0);ie.displayName="FrameworkContext";function se(){let e=i.useContext(ie);return oe(e,"You must render this element inside a <HydratedRouter> element"),e}function er(e,t){let n=i.useContext(ie),[r,a]=i.useState(!1),[o,l]=i.useState(!1),{onFocus:s,onBlur:u,onMouseEnter:c,onMouseLeave:d,onTouchStart:f}=t,m=i.useRef(null);i.useEffect(()=>{if(e==="render"&&l(!0),e==="viewport"){let y=h=>{h.forEach(R=>{l(R.isIntersecting)})},p=new IntersectionObserver(y,{threshold:.5});return m.current&&p.observe(m.current),()=>{p.disconnect()}}},[e]),i.useEffect(()=>{if(r){let y=setTimeout(()=>{l(!0)},100);return()=>{clearTimeout(y)}}},[r]);let g=()=>{a(!0)},v=()=>{a(!1),l(!1)};return n?e!=="intent"?[o,m,{}]:[o,m,{onFocus:M(s,g),onBlur:M(u,v),onMouseEnter:M(c,g),onMouseLeave:M(d,v),onTouchStart:M(f,g)}]:[!1,m,{}]}function M(e,t){return n=>{e&&e(n),n.defaultPrevented||t(n)}}function tr({page:e,...t}){let n=ht(),{router:r}=le(),a=i.useMemo(()=>ve(r.routes,e,r.basename),[r.routes,e,r.basename]);return a?n?i.createElement(nr,{page:e,matches:a,...t}):i.createElement(ar,{page:e,matches:a,...t}):null}function rr(e){let{manifest:t,routeModules:n}=se(),[r,a]=i.useState([]);return i.useEffect(()=>{let o=!1;return qt(e,t,n).then(l=>{o||a(l)}),()=>{o=!0}},[e,t,n]),r}function nr({page:e,matches:t,...n}){let r=T(),{future:a}=se(),{basename:o}=le(),l=i.useMemo(()=>{if(e===r.pathname+r.search+r.hash)return[];let s=Ne(e,o,a.unstable_trailingSlashAwareDataRequests,"rsc"),u=!1,c=[];for(let d of t)typeof d.route.shouldRevalidate=="function"?u=!0:c.push(d.route.id);return u&&c.length>0&&s.searchParams.set("_routes",c.join(",")),[s.pathname+s.search]},[o,a.unstable_trailingSlashAwareDataRequests,e,r,t]);return i.createElement(i.Fragment,null,l.map(s=>i.createElement("link",{key:s,rel:"prefetch",as:"fetch",href:s,...n})))}function ar({page:e,matches:t,...n}){let r=T(),{future:a,manifest:o,routeModules:l}=se(),{basename:s}=le(),{loaderData:u,matches:c}=Zt(),d=i.useMemo(()=>ge(e,t,c,o,r,"data"),[e,t,c,o,r]),f=i.useMemo(()=>ge(e,t,c,o,r,"assets"),[e,t,c,o,r]),m=i.useMemo(()=>{if(e===r.pathname+r.search+r.hash)return[];let y=new Set,p=!1;if(t.forEach(R=>{var C;let w=o.routes[R.route.id];!w||!w.hasLoader||(!d.some(x=>x.route.id===R.route.id)&&R.route.id in u&&((C=l[R.route.id])!=null&&C.shouldRevalidate)||w.hasClientLoader?p=!0:y.add(R.route.id))}),y.size===0)return[];let h=Ne(e,s,a.unstable_trailingSlashAwareDataRequests,"data");return p&&y.size>0&&h.searchParams.set("_routes",t.filter(R=>y.has(R.route.id)).map(R=>R.route.id).join(",")),[h.pathname+h.search]},[s,a.unstable_trailingSlashAwareDataRequests,u,r,o,d,t,e,l]),g=i.useMemo(()=>Yt(f,o),[f,o]),v=rr(f);return i.createElement(i.Fragment,null,m.map(y=>i.createElement("link",{key:y,rel:"prefetch",as:"fetch",href:y,...n})),g.map(y=>i.createElement("link",{key:y,rel:"modulepreload",href:y,...n})),v.map(({key:y,link:p})=>i.createElement("link",{key:y,nonce:n.nonce,...p,crossOrigin:p.crossOrigin??n.crossOrigin})))}function or(...e){return t=>{e.forEach(n=>{typeof n=="function"?n(t):n!=null&&(n.current=t)})}}var lr=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{lr&&(window.__reactRouterVersion="7.14.2")}catch{}function Rr({basename:e,children:t,unstable_useTransitions:n,window:r}){let a=i.useRef();a.current==null&&(a.current=Ue({window:r,v5Compat:!0}));let o=a.current,[l,s]=i.useState({action:o.action,location:o.location}),u=i.useCallback(c=>{n===!1?s(c):i.startTransition(()=>s(c))},[n]);return i.useLayoutEffect(()=>o.listen(u),[o,u]),i.createElement(Mt,{basename:e,children:t,location:l.location,navigationType:l.action,navigator:o,unstable_useTransitions:n})}var _e=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Be=i.forwardRef(function({onClick:t,discover:n="render",prefetch:r="none",relative:a,reloadDocument:o,replace:l,unstable_mask:s,state:u,target:c,to:d,preventScrollReset:f,viewTransition:m,unstable_defaultShouldRevalidate:g,...v},y){let{basename:p,navigator:h,unstable_useTransitions:R}=i.useContext(b),w=typeof d=="string"&&_e.test(d),C=be(d,p);d=C.to;let x=wt(d,{relative:a}),P=T(),D=null;if(s){let F=te(s,[],P.unstable_mask?P.unstable_mask.pathname:"/",!0);p!=="/"&&(F.pathname=F.pathname==="/"?p:S([p,F.pathname])),D=h.createHref(F)}let[I,B,Y]=er(r,v),Oe=cr(d,{replace:l,unstable_mask:s,state:u,target:c,preventScrollReset:f,relative:a,viewTransition:m,unstable_defaultShouldRevalidate:g,unstable_useTransitions:R});function Ae(F){t&&t(F),F.defaultPrevented||Oe(F)}let ue=!(C.isExternal||o),ce=i.createElement("a",{...v,...Y,href:(ue?D:void 0)||C.absoluteURL||x,onClick:ue?Ae:t,ref:or(y,B),target:c,"data-discover":!w&&n==="render"?"true":void 0});return I&&!w?i.createElement(i.Fragment,null,ce,i.createElement(tr,{page:x})):ce});Be.displayName="Link";var ir=i.forwardRef(function({"aria-current":t="page",caseSensitive:n=!1,className:r="",end:a=!1,style:o,to:l,viewTransition:s,children:u,...c},d){let f=W(l,{relative:c.relative}),m=T(),g=i.useContext(K),{navigator:v,basename:y}=i.useContext(b),p=g!=null&&pr(f)&&s===!0,h=v.encodeLocation?v.encodeLocation(f).pathname:f.pathname,R=m.pathname,w=g&&g.navigation&&g.navigation.location?g.navigation.location.pathname:null;n||(R=R.toLowerCase(),w=w?w.toLowerCase():null,h=h.toLowerCase()),w&&y&&(w=$(w,y)||w);const C=h!=="/"&&h.endsWith("/")?h.length-1:h.length;let x=R===h||!a&&R.startsWith(h)&&R.charAt(C)==="/",P=w!=null&&(w===h||!a&&w.startsWith(h)&&w.charAt(h.length)==="/"),D={isActive:x,isPending:P,isTransitioning:p},I=x?t:void 0,B;typeof r=="function"?B=r(D):B=[r,x?"active":null,P?"pending":null,p?"transitioning":null].filter(Boolean).join(" ");let Y=typeof o=="function"?o(D):o;return i.createElement(Be,{...c,"aria-current":I,className:B,ref:d,style:Y,to:l,viewTransition:s},typeof u=="function"?u(D):u)});ir.displayName="NavLink";var sr=i.forwardRef(({discover:e="render",fetcherKey:t,navigate:n,reloadDocument:r,replace:a,state:o,method:l=z,action:s,onSubmit:u,relative:c,preventScrollReset:d,viewTransition:f,unstable_defaultShouldRevalidate:m,...g},v)=>{let{unstable_useTransitions:y}=i.useContext(b),p=hr(),h=mr(s,{relative:c}),R=l.toLowerCase()==="get"?"get":"post",w=typeof s=="string"&&_e.test(s),C=x=>{if(u&&u(x),x.defaultPrevented)return;x.preventDefault();let P=x.nativeEvent.submitter,D=(P==null?void 0:P.getAttribute("formmethod"))||l,I=()=>p(P||x.currentTarget,{fetcherKey:t,method:D,navigate:n,replace:a,state:o,relative:c,preventScrollReset:d,viewTransition:f,unstable_defaultShouldRevalidate:m});y&&n!==!1?i.startTransition(()=>I()):I()};return i.createElement("form",{ref:v,method:R,action:h,onSubmit:r?u:C,...g,"data-discover":!w&&e==="render"?"true":void 0})});sr.displayName="Form";function ur(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Me(e){let t=i.useContext(_);return E(t,ur(e)),t}function cr(e,{target:t,replace:n,unstable_mask:r,state:a,preventScrollReset:o,relative:l,viewTransition:s,unstable_defaultShouldRevalidate:u,unstable_useTransitions:c}={}){let d=Et(),f=T(),m=W(e,{relative:l});return i.useCallback(g=>{if(Ht(g,t)){g.preventDefault();let v=n!==void 0?n:O(f)===O(m),y=()=>d(e,{replace:v,unstable_mask:r,state:a,preventScrollReset:o,relative:l,viewTransition:s,unstable_defaultShouldRevalidate:u});c?i.startTransition(()=>y()):y()}},[f,d,m,n,r,a,t,e,o,l,s,u,c])}var fr=0,dr=()=>`__${String(++fr)}__`;function hr(){let{router:e}=Me("useSubmit"),{basename:t}=i.useContext(b),n=Ft(),r=e.fetch,a=e.navigate;return i.useCallback(async(o,l={})=>{let{action:s,method:u,encType:c,formData:d,body:f}=Vt(o,t);if(l.navigate===!1){let m=l.fetcherKey||dr();await r(m,n,l.action||s,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:d,body:f,formMethod:l.method||u,formEncType:l.encType||c,flushSync:l.flushSync})}else await a(l.action||s,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:d,body:f,formMethod:l.method||u,formEncType:l.encType||c,replace:l.replace,state:l.state,fromRouteId:n,flushSync:l.flushSync,viewTransition:l.viewTransition})},[r,a,t,n])}function mr(e,{relative:t}={}){let{basename:n}=i.useContext(b),r=i.useContext(k);E(r,"useFormAction must be used inside a RouteContext");let[a]=r.matches.slice(-1),o={...W(e||".",{relative:t})},l=T();if(e==null){o.search=l.search;let s=new URLSearchParams(o.search),u=s.getAll("index");if(u.some(d=>d==="")){s.delete("index"),u.filter(f=>f).forEach(f=>s.append("index",f));let d=s.toString();o.search=d?`?${d}`:""}}return(!e||e===".")&&a.route.index&&(o.search=o.search?o.search.replace(/^\?/,"?index&"):"?index"),n!=="/"&&(o.pathname=o.pathname==="/"?n:S([n,o.pathname])),O(o)}function pr(e,{relative:t}={}){let n=i.useContext(Le);E(n!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=Me("useViewTransitionState"),a=W(e,{relative:t});if(!n.isTransitioning)return!1;let o=$(n.currentLocation.pathname,r)||n.currentLocation.pathname,l=$(n.nextLocation.pathname,r)||n.nextLocation.pathname;return V(a.pathname,l)!=null||V(a.pathname,o)!=null}export{Rr as B,Be as L,vr as R,gr as a,Bt as b,Et as u};
12
+ Please change the parent <Route path="${h}"> to <Route path="${h==="/"?"*":`${h}/*`}">.`)}let d=T(),f;if(t){let h=typeof t=="string"?N(t):t;E(u==="/"||((p=h.pathname)==null?void 0:p.startsWith(u)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${u}" but pathname "${h.pathname}" was given in the \`location\` prop.`),f=h}else f=d;let m=f.pathname||"/",g=m;if(u!=="/"){let h=u.replace(/^\//,"").split("/");g="/"+m.replace(/^\//,"").split("/").slice(h.length).join("/")}let v=ve(e,{pathname:g});L(c||v!=null,`No routes matched location "${f.pathname}${f.search}${f.hash}" `),L(v==null||v[v.length-1].route.element!==void 0||v[v.length-1].route.Component!==void 0||v[v.length-1].route.lazy!==void 0,`Matched leaf route at location "${f.pathname}${f.search}${f.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let y=kt(v&&v.map(h=>Object.assign({},h,{params:Object.assign({},l,h.params),pathname:S([u,r.encodeLocation?r.encodeLocation(h.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:h.pathname]),pathnameBase:h.pathnameBase==="/"?u:S([u,r.encodeLocation?r.encodeLocation(h.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:h.pathnameBase])})),a,n);return t&&y?i.createElement(A.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...f},navigationType:"POP"}},y):y}function bt(){let e=It(),t=ct(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r="rgba(200,200,200, 0.5)",a={padding:"0.5rem",backgroundColor:r},o={padding:"2px 4px",backgroundColor:r},l=null;return console.error("Error handled by React Router default ErrorBoundary:",e),l=i.createElement(i.Fragment,null,i.createElement("p",null,"💿 Hey developer 👋"),i.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",i.createElement("code",{style:o},"ErrorBoundary")," or"," ",i.createElement("code",{style:o},"errorElement")," prop on your route.")),i.createElement(i.Fragment,null,i.createElement("h2",null,"Unexpected Application Error!"),i.createElement("h3",{style:{fontStyle:"italic"}},t),n?i.createElement("pre",{style:a},n):null,l)}var St=i.createElement(bt,null),Fe=class extends i.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error("React Router caught the following error during render",e)}render(){let e=this.state.error;if(this.context&&typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){const n=Rt(e.digest);n&&(e=n)}let t=e!==void 0?i.createElement(k.Provider,{value:this.props.routeContext},i.createElement(re.Provider,{value:e,children:this.props.component})):this.props.children;return this.context?i.createElement(Pt,{error:e},t):t}};Fe.contextType=Pe;var X=new WeakMap;function Pt({children:e,error:t}){let{basename:n}=i.useContext(b);if(typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){let r=vt(t.digest);if(r){let a=X.get(t);if(a)throw a;let o=be(r.location,n);if(Ce&&!X.get(t))if(o.isExternal||r.reloadDocument)window.location.href=o.absoluteURL||o.to;else{const l=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(o.to,{replace:r.replace}));throw X.set(t,l),l}return i.createElement("meta",{httpEquiv:"refresh",content:`0;url=${o.absoluteURL||o.to}`})}}return e}function Lt({routeContext:e,match:t,children:n}){let r=i.useContext(_);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),i.createElement(k.Provider,{value:e},n)}function kt(e,t=[],n){let r=n==null?void 0:n.state;if(e==null){if(!r)return null;if(r.errors)e=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)e=r.matches;else return null}let a=e,o=r==null?void 0:r.errors;if(o!=null){let d=a.findIndex(f=>f.route.id&&(o==null?void 0:o[f.route.id])!==void 0);E(d>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),a=a.slice(0,Math.min(a.length,d+1))}let l=!1,s=-1;if(n&&r){l=r.renderFallback;for(let d=0;d<a.length;d++){let f=a[d];if((f.route.HydrateFallback||f.route.hydrateFallbackElement)&&(s=d),f.route.id){let{loaderData:m,errors:g}=r,v=f.route.loader&&!m.hasOwnProperty(f.route.id)&&(!g||g[f.route.id]===void 0);if(f.route.lazy||v){n.isStatic&&(l=!0),s>=0?a=a.slice(0,s+1):a=[a[0]];break}}}}let u=n==null?void 0:n.onError,c=r&&u?(d,f)=>{var m,g;u(d,{location:r.location,params:((g=(m=r.matches)==null?void 0:m[0])==null?void 0:g.params)??{},unstable_pattern:ft(r.matches),errorInfo:f})}:void 0;return a.reduceRight((d,f,m)=>{let g,v=!1,y=null,p=null;r&&(g=o&&f.route.id?o[f.route.id]:void 0,y=f.route.errorElement||St,l&&(s<0&&m===0?(Ie("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),v=!0,p=null):s===m&&(v=!0,p=f.route.hydrateFallbackElement||null)));let h=t.concat(a.slice(0,m+1)),R=()=>{let w;return g?w=y:v?w=p:f.route.Component?w=i.createElement(f.route.Component,null):f.route.element?w=f.route.element:w=d,i.createElement(Lt,{match:f,routeContext:{outlet:d,matches:h,isDataRoute:r!=null},children:w})};return r&&(f.route.ErrorBoundary||f.route.errorElement||m===0)?i.createElement(Fe,{location:r.location,revalidation:r.revalidation,component:y,error:g,children:R(),routeContext:{outlet:null,matches:h,isDataRoute:!0},onError:c}):R()},null)}function ne(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function $t(e){let t=i.useContext(_);return E(t,ne(e)),t}function Tt(e){let t=i.useContext(K);return E(t,ne(e)),t}function Dt(e){let t=i.useContext(k);return E(t,ne(e)),t}function ae(e){let t=Dt(e),n=t.matches[t.matches.length-1];return E(n.route.id,`${e} can only be used on routes that contain a unique "id"`),n.route.id}function Ft(){return ae("useRouteId")}function It(){var r;let e=i.useContext(re),t=Tt("useRouteError"),n=ae("useRouteError");return e!==void 0?e:(r=t.errors)==null?void 0:r[n]}function Nt(){let{router:e}=$t("useNavigate"),t=ae("useNavigate"),n=i.useRef(!1);return Te(()=>{n.current=!0}),i.useCallback(async(a,o={})=>{L(n.current,$e),n.current&&(typeof a=="number"?await e.navigate(a):await e.navigate(a,{fromRouteId:t,...o}))},[e,t])}var ye={};function Ie(e,t,n){!t&&!ye[e]&&(ye[e]=!0,L(!1,n))}i.memo(_t);function _t({routes:e,future:t,state:n,isStatic:r,onError:a}){return De(e,void 0,{state:n,isStatic:r,onError:a})}function Bt(e){E(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function Mt({basename:e="/",children:t=null,location:n,navigationType:r="POP",navigator:a,static:o=!1,unstable_useTransitions:l}){E(!U(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let s=e.replace(/^\/*/,"/"),u=i.useMemo(()=>({basename:s,navigator:a,static:o,unstable_useTransitions:l,future:{}}),[s,a,o,l]);typeof n=="string"&&(n=N(n));let{pathname:c="/",search:d="",hash:f="",state:m=null,key:g="default",unstable_mask:v}=n,y=i.useMemo(()=>{let p=$(c,s);return p==null?null:{location:{pathname:p,search:d,hash:f,state:m,key:g,unstable_mask:v},navigationType:r}},[s,c,d,f,m,g,r,v]);return L(y!=null,`<Router basename="${s}"> is not able to match the URL "${c}${d}${f}" because it does not start with the basename, so the <Router> won't render anything.`),y==null?null:i.createElement(b.Provider,{value:u},i.createElement(A.Provider,{children:t,value:y}))}function vr({children:e,location:t}){return Ct(ee(e),t)}function ee(e,t=[]){let n=[];return i.Children.forEach(e,(r,a)=>{if(!i.isValidElement(r))return;let o=[...t,a];if(r.type===i.Fragment){n.push.apply(n,ee(r.props.children,o));return}E(r.type===Bt,`[${typeof r.type=="string"?r.type:r.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),E(!r.props.index||!r.props.children,"An index route cannot have child routes.");let l={id:r.props.id||o.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(l.children=ee(r.props.children,o)),n.push(l)}),n}var z="get",j="application/x-www-form-urlencoded";function q(e){return typeof HTMLElement<"u"&&e instanceof HTMLElement}function Ot(e){return q(e)&&e.tagName.toLowerCase()==="button"}function At(e){return q(e)&&e.tagName.toLowerCase()==="form"}function Ut(e){return q(e)&&e.tagName.toLowerCase()==="input"}function Wt(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Ht(e,t){return e.button===0&&(!t||t==="_self")&&!Wt(e)}var H=null;function zt(){if(H===null)try{new FormData(document.createElement("form"),0),H=!1}catch{H=!0}return H}var jt=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Q(e){return e!=null&&!jt.has(e)?(L(!1,`"${e}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${j}"`),null):e}function Vt(e,t){let n,r,a,o,l;if(At(e)){let s=e.getAttribute("action");r=s?$(s,t):null,n=e.getAttribute("method")||z,a=Q(e.getAttribute("enctype"))||j,o=new FormData(e)}else if(Ot(e)||Ut(e)&&(e.type==="submit"||e.type==="image")){let s=e.form;if(s==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let u=e.getAttribute("formaction")||s.getAttribute("action");if(r=u?$(u,t):null,n=e.getAttribute("formmethod")||s.getAttribute("method")||z,a=Q(e.getAttribute("formenctype"))||Q(s.getAttribute("enctype"))||j,o=new FormData(s,e),!zt()){let{name:c,type:d,value:f}=e;if(d==="image"){let m=c?`${c}.`:"";o.append(`${m}x`,"0"),o.append(`${m}y`,"0")}else c&&o.append(c,f)}}else{if(q(e))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');n=z,r=null,a=j,l=e}return o&&a==="text/plain"&&(l=o,o=void 0),{action:r,method:n.toLowerCase(),encType:a,formData:o,body:l}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function oe(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function Ne(e,t,n,r){let a=typeof e=="string"?new URL(e,typeof window>"u"?"server://singlefetch/":window.location.origin):e;return n?a.pathname.endsWith("/")?a.pathname=`${a.pathname}_.${r}`:a.pathname=`${a.pathname}.${r}`:a.pathname==="/"?a.pathname=`_root.${r}`:t&&$(a.pathname,t)==="/"?a.pathname=`${J(t)}/_root.${r}`:a.pathname=`${J(a.pathname)}.${r}`,a}async function Jt(e,t){if(e.id in t)return t[e.id];try{let n=await import(e.module);return t[e.id]=n,n}catch(n){return console.error(`Error loading route module \`${e.module}\`, reloading page...`),console.error(n),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function Kt(e){return e==null?!1:e.href==null?e.rel==="preload"&&typeof e.imageSrcSet=="string"&&typeof e.imageSizes=="string":typeof e.rel=="string"&&typeof e.href=="string"}async function qt(e,t,n){let r=await Promise.all(e.map(async a=>{let o=t.routes[a.route.id];if(o){let l=await Jt(o,n);return l.links?l.links():[]}return[]}));return Qt(r.flat(1).filter(Kt).filter(a=>a.rel==="stylesheet"||a.rel==="preload").map(a=>a.rel==="stylesheet"?{...a,rel:"prefetch",as:"style"}:{...a,rel:"prefetch"}))}function ge(e,t,n,r,a,o){let l=(u,c)=>n[c]?u.route.id!==n[c].route.id:!0,s=(u,c)=>{var d;return n[c].pathname!==u.pathname||((d=n[c].route.path)==null?void 0:d.endsWith("*"))&&n[c].params["*"]!==u.params["*"]};return o==="assets"?t.filter((u,c)=>l(u,c)||s(u,c)):o==="data"?t.filter((u,c)=>{var f;let d=r.routes[u.route.id];if(!d||!d.hasLoader)return!1;if(l(u,c)||s(u,c))return!0;if(u.route.shouldRevalidate){let m=u.route.shouldRevalidate({currentUrl:new URL(a.pathname+a.search+a.hash,window.origin),currentParams:((f=n[0])==null?void 0:f.params)||{},nextUrl:new URL(e,window.origin),nextParams:u.params,defaultShouldRevalidate:!0});if(typeof m=="boolean")return m}return!0}):[]}function Yt(e,t,{includeHydrateFallback:n}={}){return Gt(e.map(r=>{let a=t.routes[r.route.id];if(!a)return[];let o=[a.module];return a.clientActionModule&&(o=o.concat(a.clientActionModule)),a.clientLoaderModule&&(o=o.concat(a.clientLoaderModule)),n&&a.hydrateFallbackModule&&(o=o.concat(a.hydrateFallbackModule)),a.imports&&(o=o.concat(a.imports)),o}).flat(1))}function Gt(e){return[...new Set(e)]}function Xt(e){let t={},n=Object.keys(e).sort();for(let r of n)t[r]=e[r];return t}function Qt(e,t){let n=new Set;return new Set(t),e.reduce((r,a)=>{let o=JSON.stringify(Xt(a));return n.has(o)||(n.add(o),r.push({key:o,link:a})),r},[])}function le(){let e=i.useContext(_);return oe(e,"You must render this element inside a <DataRouterContext.Provider> element"),e}function Zt(){let e=i.useContext(K);return oe(e,"You must render this element inside a <DataRouterStateContext.Provider> element"),e}var ie=i.createContext(void 0);ie.displayName="FrameworkContext";function se(){let e=i.useContext(ie);return oe(e,"You must render this element inside a <HydratedRouter> element"),e}function er(e,t){let n=i.useContext(ie),[r,a]=i.useState(!1),[o,l]=i.useState(!1),{onFocus:s,onBlur:u,onMouseEnter:c,onMouseLeave:d,onTouchStart:f}=t,m=i.useRef(null);i.useEffect(()=>{if(e==="render"&&l(!0),e==="viewport"){let y=h=>{h.forEach(R=>{l(R.isIntersecting)})},p=new IntersectionObserver(y,{threshold:.5});return m.current&&p.observe(m.current),()=>{p.disconnect()}}},[e]),i.useEffect(()=>{if(r){let y=setTimeout(()=>{l(!0)},100);return()=>{clearTimeout(y)}}},[r]);let g=()=>{a(!0)},v=()=>{a(!1),l(!1)};return n?e!=="intent"?[o,m,{}]:[o,m,{onFocus:M(s,g),onBlur:M(u,v),onMouseEnter:M(c,g),onMouseLeave:M(d,v),onTouchStart:M(f,g)}]:[!1,m,{}]}function M(e,t){return n=>{e&&e(n),n.defaultPrevented||t(n)}}function tr({page:e,...t}){let n=ht(),{router:r}=le(),a=i.useMemo(()=>ve(r.routes,e,r.basename),[r.routes,e,r.basename]);return a?n?i.createElement(nr,{page:e,matches:a,...t}):i.createElement(ar,{page:e,matches:a,...t}):null}function rr(e){let{manifest:t,routeModules:n}=se(),[r,a]=i.useState([]);return i.useEffect(()=>{let o=!1;return qt(e,t,n).then(l=>{o||a(l)}),()=>{o=!0}},[e,t,n]),r}function nr({page:e,matches:t,...n}){let r=T(),{future:a}=se(),{basename:o}=le(),l=i.useMemo(()=>{if(e===r.pathname+r.search+r.hash)return[];let s=Ne(e,o,a.unstable_trailingSlashAwareDataRequests,"rsc"),u=!1,c=[];for(let d of t)typeof d.route.shouldRevalidate=="function"?u=!0:c.push(d.route.id);return u&&c.length>0&&s.searchParams.set("_routes",c.join(",")),[s.pathname+s.search]},[o,a.unstable_trailingSlashAwareDataRequests,e,r,t]);return i.createElement(i.Fragment,null,l.map(s=>i.createElement("link",{key:s,rel:"prefetch",as:"fetch",href:s,...n})))}function ar({page:e,matches:t,...n}){let r=T(),{future:a,manifest:o,routeModules:l}=se(),{basename:s}=le(),{loaderData:u,matches:c}=Zt(),d=i.useMemo(()=>ge(e,t,c,o,r,"data"),[e,t,c,o,r]),f=i.useMemo(()=>ge(e,t,c,o,r,"assets"),[e,t,c,o,r]),m=i.useMemo(()=>{if(e===r.pathname+r.search+r.hash)return[];let y=new Set,p=!1;if(t.forEach(R=>{var C;let w=o.routes[R.route.id];!w||!w.hasLoader||(!d.some(x=>x.route.id===R.route.id)&&R.route.id in u&&((C=l[R.route.id])!=null&&C.shouldRevalidate)||w.hasClientLoader?p=!0:y.add(R.route.id))}),y.size===0)return[];let h=Ne(e,s,a.unstable_trailingSlashAwareDataRequests,"data");return p&&y.size>0&&h.searchParams.set("_routes",t.filter(R=>y.has(R.route.id)).map(R=>R.route.id).join(",")),[h.pathname+h.search]},[s,a.unstable_trailingSlashAwareDataRequests,u,r,o,d,t,e,l]),g=i.useMemo(()=>Yt(f,o),[f,o]),v=rr(f);return i.createElement(i.Fragment,null,m.map(y=>i.createElement("link",{key:y,rel:"prefetch",as:"fetch",href:y,...n})),g.map(y=>i.createElement("link",{key:y,rel:"modulepreload",href:y,...n})),v.map(({key:y,link:p})=>i.createElement("link",{key:y,nonce:n.nonce,...p,crossOrigin:p.crossOrigin??n.crossOrigin})))}function or(...e){return t=>{e.forEach(n=>{typeof n=="function"?n(t):n!=null&&(n.current=t)})}}var lr=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{lr&&(window.__reactRouterVersion="7.14.2")}catch{}function Rr({basename:e,children:t,unstable_useTransitions:n,window:r}){let a=i.useRef();a.current==null&&(a.current=Ue({window:r,v5Compat:!0}));let o=a.current,[l,s]=i.useState({action:o.action,location:o.location}),u=i.useCallback(c=>{n===!1?s(c):i.startTransition(()=>s(c))},[n]);return i.useLayoutEffect(()=>o.listen(u),[o,u]),i.createElement(Mt,{basename:e,children:t,location:l.location,navigationType:l.action,navigator:o,unstable_useTransitions:n})}var _e=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Be=i.forwardRef(function({onClick:t,discover:n="render",prefetch:r="none",relative:a,reloadDocument:o,replace:l,unstable_mask:s,state:u,target:c,to:d,preventScrollReset:f,viewTransition:m,unstable_defaultShouldRevalidate:g,...v},y){let{basename:p,navigator:h,unstable_useTransitions:R}=i.useContext(b),w=typeof d=="string"&&_e.test(d),C=be(d,p);d=C.to;let x=wt(d,{relative:a}),P=T(),D=null;if(s){let F=te(s,[],P.unstable_mask?P.unstable_mask.pathname:"/",!0);p!=="/"&&(F.pathname=F.pathname==="/"?p:S([p,F.pathname])),D=h.createHref(F)}let[I,B,Y]=er(r,v),Oe=cr(d,{replace:l,unstable_mask:s,state:u,target:c,preventScrollReset:f,relative:a,viewTransition:m,unstable_defaultShouldRevalidate:g,unstable_useTransitions:R});function Ae(F){t&&t(F),F.defaultPrevented||Oe(F)}let ue=!(C.isExternal||o),ce=i.createElement("a",{...v,...Y,href:(ue?D:void 0)||C.absoluteURL||x,onClick:ue?Ae:t,ref:or(y,B),target:c,"data-discover":!w&&n==="render"?"true":void 0});return I&&!w?i.createElement(i.Fragment,null,ce,i.createElement(tr,{page:x})):ce});Be.displayName="Link";var ir=i.forwardRef(function({"aria-current":t="page",caseSensitive:n=!1,className:r="",end:a=!1,style:o,to:l,viewTransition:s,children:u,...c},d){let f=W(l,{relative:c.relative}),m=T(),g=i.useContext(K),{navigator:v,basename:y}=i.useContext(b),p=g!=null&&pr(f)&&s===!0,h=v.encodeLocation?v.encodeLocation(f).pathname:f.pathname,R=m.pathname,w=g&&g.navigation&&g.navigation.location?g.navigation.location.pathname:null;n||(R=R.toLowerCase(),w=w?w.toLowerCase():null,h=h.toLowerCase()),w&&y&&(w=$(w,y)||w);const C=h!=="/"&&h.endsWith("/")?h.length-1:h.length;let x=R===h||!a&&R.startsWith(h)&&R.charAt(C)==="/",P=w!=null&&(w===h||!a&&w.startsWith(h)&&w.charAt(h.length)==="/"),D={isActive:x,isPending:P,isTransitioning:p},I=x?t:void 0,B;typeof r=="function"?B=r(D):B=[r,x?"active":null,P?"pending":null,p?"transitioning":null].filter(Boolean).join(" ");let Y=typeof o=="function"?o(D):o;return i.createElement(Be,{...c,"aria-current":I,className:B,ref:d,style:Y,to:l,viewTransition:s},typeof u=="function"?u(D):u)});ir.displayName="NavLink";var sr=i.forwardRef(({discover:e="render",fetcherKey:t,navigate:n,reloadDocument:r,replace:a,state:o,method:l=z,action:s,onSubmit:u,relative:c,preventScrollReset:d,viewTransition:f,unstable_defaultShouldRevalidate:m,...g},v)=>{let{unstable_useTransitions:y}=i.useContext(b),p=hr(),h=mr(s,{relative:c}),R=l.toLowerCase()==="get"?"get":"post",w=typeof s=="string"&&_e.test(s),C=x=>{if(u&&u(x),x.defaultPrevented)return;x.preventDefault();let P=x.nativeEvent.submitter,D=(P==null?void 0:P.getAttribute("formmethod"))||l,I=()=>p(P||x.currentTarget,{fetcherKey:t,method:D,navigate:n,replace:a,state:o,relative:c,preventScrollReset:d,viewTransition:f,unstable_defaultShouldRevalidate:m});y&&n!==!1?i.startTransition(()=>I()):I()};return i.createElement("form",{ref:v,method:R,action:h,onSubmit:r?u:C,...g,"data-discover":!w&&e==="render"?"true":void 0})});sr.displayName="Form";function ur(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Me(e){let t=i.useContext(_);return E(t,ur(e)),t}function cr(e,{target:t,replace:n,unstable_mask:r,state:a,preventScrollReset:o,relative:l,viewTransition:s,unstable_defaultShouldRevalidate:u,unstable_useTransitions:c}={}){let d=Et(),f=T(),m=W(e,{relative:l});return i.useCallback(g=>{if(Ht(g,t)){g.preventDefault();let v=n!==void 0?n:O(f)===O(m),y=()=>d(e,{replace:v,unstable_mask:r,state:a,preventScrollReset:o,relative:l,viewTransition:s,unstable_defaultShouldRevalidate:u});c?i.startTransition(()=>y()):y()}},[f,d,m,n,r,a,t,e,o,l,s,u,c])}var fr=0,dr=()=>`__${String(++fr)}__`;function hr(){let{router:e}=Me("useSubmit"),{basename:t}=i.useContext(b),n=Ft(),r=e.fetch,a=e.navigate;return i.useCallback(async(o,l={})=>{let{action:s,method:u,encType:c,formData:d,body:f}=Vt(o,t);if(l.navigate===!1){let m=l.fetcherKey||dr();await r(m,n,l.action||s,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:d,body:f,formMethod:l.method||u,formEncType:l.encType||c,flushSync:l.flushSync})}else await a(l.action||s,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:d,body:f,formMethod:l.method||u,formEncType:l.encType||c,replace:l.replace,state:l.state,fromRouteId:n,flushSync:l.flushSync,viewTransition:l.viewTransition})},[r,a,t,n])}function mr(e,{relative:t}={}){let{basename:n}=i.useContext(b),r=i.useContext(k);E(r,"useFormAction must be used inside a RouteContext");let[a]=r.matches.slice(-1),o={...W(e||".",{relative:t})},l=T();if(e==null){o.search=l.search;let s=new URLSearchParams(o.search),u=s.getAll("index");if(u.some(d=>d==="")){s.delete("index"),u.filter(f=>f).forEach(f=>s.append("index",f));let d=s.toString();o.search=d?`?${d}`:""}}return(!e||e===".")&&a.route.index&&(o.search=o.search?o.search.replace(/^\?/,"?index&"):"?index"),n!=="/"&&(o.pathname=o.pathname==="/"?n:S([n,o.pathname])),O(o)}function pr(e,{relative:t}={}){let n=i.useContext(Le);E(n!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:r}=Me("useViewTransitionState"),a=W(e,{relative:t});if(!n.isTransitioning)return!1;let o=$(n.currentLocation.pathname,r)||n.currentLocation.pathname,l=$(n.nextLocation.pathname,r)||n.nextLocation.pathname;return V(a.pathname,l)!=null||V(a.pathname,o)!=null}export{Rr as B,Be as L,ir as N,vr as R,gr as a,Bt as b,Et as u};
@@ -0,0 +1,100 @@
1
+ # iA Writer Typeface
2
+
3
+ Copyright © 2018 Information Architects Inc. with Reserved Font Name "iA Writer"
4
+
5
+ # Based on IBM Plex Typeface
6
+
7
+ Copyright © 2017 IBM Corp. with Reserved Font Name "Plex"
8
+
9
+ # License
10
+
11
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
12
+ This license is copied below, and is also available with a FAQ at:
13
+ http://scripts.sil.org/OFL
14
+
15
+ -----------------------------------------------------------
16
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
17
+ -----------------------------------------------------------
18
+
19
+ PREAMBLE
20
+ The goals of the Open Font License (OFL) are to stimulate worldwide
21
+ development of collaborative font projects, to support the font creation
22
+ efforts of academic and linguistic communities, and to provide a free and
23
+ open framework in which fonts may be shared and improved in partnership
24
+ with others.
25
+
26
+ The OFL allows the licensed fonts to be used, studied, modified and
27
+ redistributed freely as long as they are not sold by themselves. The
28
+ fonts, including any derivative works, can be bundled, embedded,
29
+ redistributed and/or sold with any software provided that any reserved
30
+ names are not used by derivative works. The fonts and derivatives,
31
+ however, cannot be released under any other type of license. The
32
+ requirement for fonts to remain under this license does not apply
33
+ to any document created using the fonts or their derivatives.
34
+
35
+ DEFINITIONS
36
+ "Font Software" refers to the set of files released by the Copyright
37
+ Holder(s) under this license and clearly marked as such. This may
38
+ include source files, build scripts and documentation.
39
+
40
+ "Reserved Font Name" refers to any names specified as such after the
41
+ copyright statement(s).
42
+
43
+ "Original Version" refers to the collection of Font Software components as
44
+ distributed by the Copyright Holder(s).
45
+
46
+ "Modified Version" refers to any derivative made by adding to, deleting,
47
+ or substituting -- in part or in whole -- any of the components of the
48
+ Original Version, by changing formats or by porting the Font Software to a
49
+ new environment.
50
+
51
+ "Author" refers to any designer, engineer, programmer, technical
52
+ writer or other person who contributed to the Font Software.
53
+
54
+ PERMISSION & CONDITIONS
55
+ Permission is hereby granted, free of charge, to any person obtaining
56
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
57
+ redistribute, and sell modified and unmodified copies of the Font
58
+ Software, subject to the following conditions:
59
+
60
+ 1) Neither the Font Software nor any of its individual components,
61
+ in Original or Modified Versions, may be sold by itself.
62
+
63
+ 2) Original or Modified Versions of the Font Software may be bundled,
64
+ redistributed and/or sold with any software, provided that each copy
65
+ contains the above copyright notice and this license. These can be
66
+ included either as stand-alone text files, human-readable headers or
67
+ in the appropriate machine-readable metadata fields within text or
68
+ binary files as long as those fields can be easily viewed by the user.
69
+
70
+ 3) No Modified Version of the Font Software may use the Reserved Font
71
+ Name(s) unless explicit written permission is granted by the corresponding
72
+ Copyright Holder. This restriction only applies to the primary font name as
73
+ presented to the users.
74
+
75
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
76
+ Software shall not be used to promote, endorse or advertise any
77
+ Modified Version, except to acknowledge the contribution(s) of the
78
+ Copyright Holder(s) and the Author(s) or with their explicit written
79
+ permission.
80
+
81
+ 5) The Font Software, modified or unmodified, in part or in whole,
82
+ must be distributed entirely under this license, and must not be
83
+ distributed under any other license. The requirement for fonts to
84
+ remain under this license does not apply to any document created
85
+ using the Font Software.
86
+
87
+ TERMINATION
88
+ This license becomes null and void if any of the above conditions are
89
+ not met.
90
+
91
+ DISCLAIMER
92
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
93
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
94
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
95
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
96
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
97
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
98
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
99
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
100
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,93 @@
1
+ Copyright 2019 The Lilex Project Authors (https://github.com/mishamyrt/Lilex)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ https://openfontlicense.org
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -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-53CBbz4w.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-U9e8DquG.js"></script>
8
8
  <link rel="modulepreload" crossorigin href="/assets/react-BG4Iuztk.js">
9
9
  <link rel="modulepreload" crossorigin href="/assets/xterm-D5X2JljJ.js">
10
- <link rel="modulepreload" crossorigin href="/assets/router-B_Nv0oRz.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/router-BVggVFlO.js">
11
11
  <link rel="stylesheet" crossorigin href="/assets/xterm-CFbL2ovg.css">
12
- <link rel="stylesheet" crossorigin href="/assets/index-B9D6BV08.css">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-BRLVtzDj.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.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "AI agent orchestration",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -1,4 +0,0 @@
1
- var Je=Object.defineProperty;var Ve=(s,t,n)=>t in s?Je(s,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):s[t]=n;var L=(s,t,n)=>Ve(s,typeof t!="symbol"?t+"":t,n);import{r as a,j as e,c as Ke}from"./react-BG4Iuztk.js";import{x as Ye,a as Ze}from"./xterm-D5X2JljJ.js";import{L as ee,u as ve,a as Se,B as Xe,R as et,b as ae}from"./router-B_Nv0oRz.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const i of r)if(i.type==="childList")for(const c of i.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&o(c)}).observe(document,{childList:!0,subtree:!0});function n(r){const i={};return r.integrity&&(i.integrity=r.integrity),r.referrerPolicy&&(i.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?i.credentials="include":r.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(r){if(r.ep)return;r.ep=!0;const i=n(r);fetch(r.href,i)}})();const me="/api",ke="baxian.token",ye="baxian:unauthorized";function Ne(){try{return typeof localStorage<"u"?localStorage.getItem(ke):null}catch{return null}}function tt(s){try{localStorage.setItem(ke,s)}catch(t){console.error("Failed to save auth token to localStorage",t)}}function st(){try{localStorage.removeItem(ke)}catch(s){console.error("Failed to clear auth token from localStorage",s)}}function ie(s){const t=Ne();return{...s??{},...t?{Authorization:`Bearer ${t}`}:{}}}class de extends Error{constructor(t,n,o){super(n),this.status=t,this.details=o,this.name="ApiError"}}async function oe(s){const t=await s.text();let n=t||`HTTP ${s.status}`,o;try{const r=JSON.parse(t);typeof r.error=="string"&&(n=r.error),Array.isArray(r.details)&&(o=r.details)}catch{}throw s.status===401&&typeof window<"u"&&window.dispatchEvent(new CustomEvent(ye)),new de(s.status,n,o)}async function se(s){const t=await fetch(`${me}${s}`,{headers:ie()});return t.ok||await oe(t),t.json()}async function rt(){const s=await fetch("/health");return s.ok||await oe(s),s.json()}async function Z(s,t,n){const o=t!==void 0,r=await fetch(`${me}${s}`,{method:"POST",headers:o?ie({"Content-Type":"application/json"}):ie(),body:o?JSON.stringify(t):void 0,signal:n==null?void 0:n.signal});return r.ok||await oe(r),r.json()}async function nt(s,t,n){const o=await fetch(`${me}${s}`,{method:"PATCH",headers:ie({"Content-Type":"application/json"}),body:t?JSON.stringify(t):void 0,signal:n==null?void 0:n.signal});if(o.ok||await oe(o),o.status===204)return;const r=await o.text();if(r)return JSON.parse(r)}async function Te(s){const t=await fetch(`${me}${s}`,{method:"DELETE",headers:ie()});if(t.ok||await oe(t),t.status===204)return;const n=await t.text();if(n)return JSON.parse(n)}const W=encodeURIComponent,O={agents:{list:()=>se("/agents"),get:s=>se(`/agents/${W(s)}`),stop:s=>Te(`/agents/${W(s)}/session`),probe:(s,t,n)=>Z("/agents/probe",{mode:s,host:t},n)},tasks:{list:s=>se(`/tasks${s?`?projectId=${W(s)}`:""}`),get:s=>se(`/tasks/${W(s)}`),create:s=>Z("/tasks",s),update:(s,t)=>nt(`/tasks/${W(s)}`,t),retry:s=>Z(`/tasks/${W(s)}/retry`),review:s=>Z(`/tasks/${W(s)}/review`)},projects:{list:()=>se("/projects"),get:s=>se(`/projects/${W(s)}`),create:s=>Z("/projects",s),addAgent:(s,t)=>Z(`/projects/${W(s)}/agents`,t),deleteAgent:(s,t)=>Te(`/projects/${W(s)}/agents/${W(t)}`),resumeAgent:(s,t)=>Z(`/projects/${W(s)}/agents/${W(t)}/resume`),bootstrap:s=>Z(`/projects/${W(s)}/bootstrap`)},config:{get:()=>se("/config")},health:{get:rt},server:{restart:()=>Z("/restart")}},Fe=a.createContext(null),at={success:"bg-green-50 border-green-200 text-green-900",warn:"bg-amber-50 border-amber-200 text-amber-900",error:"bg-red-50 border-red-200 text-red-900"},it={success:"✅",warn:"⚠️",error:"❌"};let ot=1;function lt({children:s}){const[t,n]=a.useState([]),o=a.useCallback(i=>{n(c=>c.filter(m=>m.id!==i))},[]),r=a.useCallback(i=>{const c=ot++,m=i.durationMs??3e3;n(p=>[...p,{...i,id:c}]),setTimeout(()=>o(c),m)},[o]);return e.jsxs(Fe.Provider,{value:{show:r},children:[s,e.jsx("div",{className:"fixed top-4 right-4 z-[60] flex flex-col gap-2 pointer-events-none",children:t.map(i=>e.jsx("div",{className:`pointer-events-auto px-4 py-3 rounded shadow-lg border w-80 ${at[i.kind]}`,role:"status",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{"aria-hidden":!0,children:it[i.kind]}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-semibold",children:i.title}),i.body&&e.jsx("div",{className:"text-sm mt-1 whitespace-pre-line",children:i.body})]}),e.jsx("button",{type:"button",onClick:()=>o(i.id),className:"text-current opacity-50 hover:opacity-100","aria-label":"Dismiss",children:"✕"})]})},i.id))})]})}function le(){const s=a.useContext(Fe);if(!s)throw new Error("useToast must be inside <ToastProvider>");return s}const ue="baxian.pendingRestart",ct=500,dt=3e4,ze=a.createContext(null);function ut(){try{const s=localStorage.getItem(ue);if(!s)return{count:0,baselineStartedAt:null};const t=JSON.parse(s);return{count:typeof t.count=="number"?t.count:0,baselineStartedAt:typeof t.baselineStartedAt=="string"?t.baselineStartedAt:null}}catch{return{count:0,baselineStartedAt:null}}}function ht(s){try{s.count<=0?localStorage.removeItem(ue):localStorage.setItem(ue,JSON.stringify(s))}catch{}}function mt({children:s}){const t=ut(),[n,o]=a.useState(t.count),[r,i]=a.useState(t.baselineStartedAt),[c,m]=a.useState(t.count>0?"pending":"idle"),[p,b]=a.useState(),u=a.useRef(t.count),h=a.useRef(t.count>0?"pending":"idle"),f=a.useRef(0),x=a.useCallback(S=>{u.current=S,o(S)},[]),d=a.useCallback(S=>{o(A=>{const g=S(A);return u.current=g,g})},[]),j=a.useCallback(S=>{h.current=S,m(S)},[]);a.useEffect(()=>{ht({count:n,baselineStartedAt:r})},[n,r]),a.useEffect(()=>{let S=!1;(async()=>{try{const g=await O.health.get();if(S)return;i(R=>R!==null&&g.startedAt!==R?(x(0),j("idle"),null):R)}catch{}})();const A=g=>{if(g.key===ue){if(g.newValue===null){if(h.current==="restarting"&&f.current>0){x(f.current),i(null);return}x(0),i(null),h.current!=="restarting"&&j("idle");return}try{const R=JSON.parse(g.newValue);typeof R.count=="number"&&(h.current==="restarting"&&R.count>u.current&&(f.current+=R.count-u.current),x(R.count),h.current!=="restarting"&&j(R.count>0?"pending":"idle")),typeof R.baselineStartedAt=="string"?i(R.baselineStartedAt):R.baselineStartedAt===null&&i(null)}catch{}}};return window.addEventListener("storage",A),()=>{S=!0,window.removeEventListener("storage",A)}},[x,j]);const l=a.useRef(!1),T=a.useCallback(()=>{d(S=>S+1),h.current==="restarting"?f.current+=1:j("pending"),i(S=>(S!==null||l.current||(l.current=!0,(async()=>{try{const A=await O.health.get();i(g=>g??A.startedAt)}catch{}finally{l.current=!1}})()),S))},[j,d]),$=a.useCallback(async()=>{f.current=0,b(void 0),j("restarting");let S;try{S=(await O.health.get()).startedAt}catch(g){j("failed"),b(`获取重启前 startedAt 失败: ${g instanceof Error?g.message:String(g)}`);return}try{await O.server.restart()}catch(g){if(!(g instanceof de&&g.status===409)){j("failed"),b(`触发重启失败: ${g instanceof Error?g.message:String(g)}`);return}}const A=Date.now();for(;Date.now()-A<dt;){await new Promise(g=>setTimeout(g,ct));try{const g=await O.health.get();if(g.startedAt!==S){const R=f.current;f.current=0,i(R>0?g.startedAt:null),x(R),j(R>0?"pending":"idle");return}}catch{}}j("failed"),b("重启超时(30s 未恢复)。请检查日志或手动 baxian start -c <path>")},[x,j]);return e.jsx(ze.Provider,{value:{phase:c,count:n,error:p,flagDirty:T,triggerRestart:$},children:s})}function xe(){const s=a.useContext(ze);if(!s)throw new Error("usePendingRestart must be used inside PendingRestartProvider");return s}const xt=[500,1e3,2e3,4e3,8e3,15e3,3e4];class Me{constructor(t){L(this,"attempts",0);L(this,"timer",null);L(this,"delaysMs");this.opts=t,this.delaysMs=t.delaysMs??xt}schedule(){if(this.timer||!this.shouldReconnect())return;const t=this.delaysMs[Math.min(this.attempts,this.delaysMs.length-1)];this.attempts+=1,this.timer=setTimeout(()=>{this.timer=null,this.shouldReconnect()&&this.opts.reconnect()},t)}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null)}reset(){this.attempts=0}shouldReconnect(){return this.opts.shouldReconnect?this.opts.shouldReconnect():!0}}let Ie=0;function ft(){Ie++;const s=Math.random().toString(36).slice(2,8);return`sub-${Date.now().toString(36)}-${Ie}-${s}`}function bt(s){return Array.from(new TextEncoder().encode(s)).map(t=>t.toString(16).padStart(2,"0")).join("")}function pt(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/stream`}const gt=(s,t)=>t&&t.length>0?new WebSocket(s,t):new WebSocket(s);class yt{constructor(t={}){L(this,"wsUrl");L(this,"wsFactory");L(this,"tokenProvider");L(this,"ws",null);L(this,"subs",new Map);L(this,"snapshotPending",new Set);L(this,"preSubscribeQueue",new Map);L(this,"outbox",[]);L(this,"reconnectScheduler");L(this,"explicitlyClosed",!1);this.wsUrl=t.wsUrl??pt(),this.wsFactory=t.wsFactory??gt,this.tokenProvider=t.tokenProvider??Ne,this.reconnectScheduler=new Me({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.subs.size>0})}subscribe(t){const n=ft(),o={subscriberId:n,agentId:t.agentId,mode:t.mode,onSnapshot:t.onSnapshot,onData:t.onData,onError:t.onError,onSessionGone:t.onSessionGone};return this.subs.set(n,o),this.snapshotPending.add(n),this.preSubscribeQueue.set(n,[]),this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",subscriberId:n,agentId:t.agentId,mode:t.mode}),{subscriberId:n,unsubscribe:()=>this.unsubscribe(n)}}send(t,n){if(this.subs.has(t)){if(this.snapshotPending.has(t)){this.outbox.push({op:"input",subscriberId:t,data:n});return}this.wsSendOrQueue({op:"input",subscriberId:t,data:n})}}resize(t,n,o){const r=this.subs.get(t);r&&(r.lastSize={cols:n,rows:o},!this.snapshotPending.has(t)&&this.wsSendOrQueue({op:"resize",subscriberId:t,cols:n,rows:o}))}ping(){this.wsSendOrQueue({op:"ping"})}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.subs.clear(),this.snapshotPending.clear(),this.preSubscribeQueue.clear(),this.outbox=[]}unsubscribe(t){this.subs.has(t)&&(this.subs.delete(t),this.snapshotPending.delete(t),this.preSubscribeQueue.delete(t),this.wsSendOrQueue({op:"unsubscribe",subscriberId:t}),this.subs.size===0&&this.teardownSocket())}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const t=this.tokenProvider(),n=t?[`baxian.token.${bt(t)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,n)}catch(r){console.warn("[pane-stream] WebSocket constructor threw:",r),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(c){console.warn("[pane-stream] resubscribe send failed:",c)}}const r=this.outbox;this.outbox=[];for(const i of r)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(c){console.warn("[pane-stream] outbox flush failed:",c)}}},o.onmessage=r=>{if(o!==this.ws)return;let i;try{const c=typeof r.data=="string"?r.data:String(r.data);i=JSON.parse(c)}catch{return}this.handleMessage(i)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&this.subs.size!==0&&this.scheduleReconnect())},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}wsSendOrQueue(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(t));return}catch(n){console.warn("[pane-stream] send failed, will queue:",n)}this.outbox.push(t)}handleMessage(t){var n,o;switch(t.type){case"snapshot":this.handleSnapshot(t);break;case"subscribed":this.handleSubscribed(t);break;case"data":this.dispatch(t);break;case"session_gone":for(const r of[...this.subs.values()])r.agentId===t.agentId&&((n=r.onSessionGone)==null||n.call(r));break;case"error":{if(t.subscriberId){const r=this.subs.get(t.subscriberId);(o=r==null?void 0:r.onError)==null||o.call(r,{code:t.code,message:t.message})}else console.warn("[pane-stream] connection-level error:",t.code,t.message);break}}}handleSnapshot(t){const n=this.subs.get(t.subscriberId);n&&n.onSnapshot({cols:t.cols,rows:t.rows,data:t.data})}handleSubscribed(t){const n=this.subs.get(t.subscriberId);if(!n)return;n.snapshotSeq=t.snapshotSeq,n.lastSize||(n.lastSize={cols:t.cols,rows:t.rows}),this.snapshotPending.delete(t.subscriberId);const o=this.preSubscribeQueue.get(t.subscriberId);if(this.preSubscribeQueue.delete(t.subscriberId),o)for(const r of o)r.seq>t.snapshotSeq&&n.onData(r.data);n.mode==="full"&&n.lastSize&&this.wsSendOrQueue({op:"resize",subscriberId:n.subscriberId,cols:n.lastSize.cols,rows:n.lastSize.rows}),this.flushOutboxForSub(t.subscriberId)}flushOutboxForSub(t){if(this.outbox.length===0||!this.ws||this.ws.readyState!==WebSocket.OPEN)return;const n=[];for(const o of this.outbox)if("subscriberId"in o&&o.subscriberId===t&&o.op!=="subscribe")try{this.ws.send(JSON.stringify(o))}catch(r){console.warn("[pane-stream] flushOutboxForSub send failed:",r)}else n.push(o);this.outbox=n}dispatch(t){for(const n of this.subs.values())if(n.agentId===t.agentId)if(this.snapshotPending.has(n.subscriberId)){const o=this.preSubscribeQueue.get(n.subscriberId);o&&o.push({seq:t.seq,data:t.data})}else n.onData(t.data)}}let be=null;function pe(){return be||(be=new yt),be}function jt(s){const{agentId:t,mode:n}=s,o=a.useRef(null),r=a.useRef({onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone});r.current={onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone},a.useEffect(()=>{const p=pe().subscribe({agentId:t,mode:n,onSnapshot:b=>r.current.onSnapshot(b),onData:b=>r.current.onData(b),onError:b=>{var u,h;return(h=(u=r.current).onError)==null?void 0:h.call(u,b)},onSessionGone:()=>{var b,u;return(u=(b=r.current).onSessionGone)==null?void 0:u.call(b)}});return o.current=p.subscriberId,()=>{o.current=null,p.unsubscribe()}},[t,n]);const i=a.useCallback(m=>{const p=o.current;p&&pe().send(p,m)},[]),c=a.useCallback((m,p)=>{const b=o.current;b&&pe().resize(b,m,p)},[]);return{send:i,resize:c}}const wt=18,vt=250,St=256*1024,he="#e1e2e7",kt={background:he,foreground:"#3760bf",cursor:"#3760bf",cursorAccent:he,selectionBackground:"#b7c1e3",selectionForeground:"#3760bf",black:"#b4b5b9",red:"#f52a65",green:"#587539",yellow:"#8c6c3e",blue:"#2e7de9",magenta:"#9854f1",cyan:"#007197",white:"#6172b0",brightBlack:"#a1a6c5",brightRed:"#ff4774",brightGreen:"#5c8524",brightYellow:"#a27629",brightBlue:"#358aff",brightMagenta:"#a463ff",brightCyan:"#007ea8",brightWhite:"#3760bf"},Nt=/\x1b\[(?:\?[\d;]*c|>[\d;]*c|\??\d+;\d+R|\d+n)/g;function Et(s){return s.replace(Nt,"")}function je({agentId:s,mode:t,interactive:n=!1,maxLines:o,className:r,autoFocus:i=!0,deferFullUntilFocus:c=!1}){const m=a.useRef(null),p=a.useRef(null),b=a.useRef(null),u=a.useRef(!1),h=a.useRef(""),f=a.useRef([]),x=a.useRef(0),d=a.useRef(null),j=a.useRef(null),l=a.useRef(Promise.resolve()),T=a.useRef(0),[$,S]=a.useState(null),[A,g]=a.useState(!1),R=`${s}\0${t}\0${c?"1":"0"}`,[k,P]=a.useState({key:R,active:!1}),N=k.key===R&&k.active,D=t==="full"&&c,F=D&&!N?"preview":t,I=n&&F==="full",M=(y,_)=>_.length===0?Promise.resolve():new Promise(C=>{try{y.write(_,()=>C())}catch(w){console.warn("[pane-terminal] write failed:",w),C()}}),Q=(y,_)=>{l.current=l.current.then(async()=>{const C=p.current;if(!(!C||_!==T.current))try{await y(C)}catch(w){console.warn("[pane-terminal] terminal task failed:",w)}}).catch(C=>{console.warn("[pane-terminal] write chain failed:",C)})},U=(y,_)=>{Q(C=>M(C,y),_)},J=()=>{d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),j.current!==null&&(clearTimeout(j.current),j.current=null)},Y=()=>{J(),f.current=[],x.current=0},H=()=>{J();const y=f.current;y.length!==0&&(f.current=[],x.current=0,U(y.join(""),T.current))},V=y=>{if(y.length!==0){if(f.current.push(y),x.current+=y.length,x.current>=St){H();return}d.current===null&&(d.current=requestAnimationFrame(H)),j.current===null&&(j.current=setTimeout(H,vt))}},{send:K,resize:te}=jt({agentId:s,mode:F,onSnapshot:({cols:y,rows:_,data:C})=>{if(p.current)try{const v=T.current+1;T.current=v,Y(),Q(async q=>{q.reset(),y>0&&_>0&&q.resize(y,_),await M(q,C)},v)}catch(v){console.warn("[pane-terminal] snapshot write failed:",v)}},onData:y=>{V(y)},onError:y=>S(`${y.code}: ${y.message}`),onSessionGone:()=>g(!0)});a.useEffect(()=>{S(null),g(!1)},[s,F]),a.useEffect(()=>{h.current=""},[R]),a.useEffect(()=>{if(F!=="full")return;const y=h.current;y.length!==0&&(h.current="",K(y))},[K,F]);const G=a.useCallback(()=>{!n||!D||N||(u.current=!0,P({key:R,active:!0}))},[R,N,n,D]);a.useEffect(()=>{const y=m.current;if(!y)return;let _=!1;const C=new Ye.Terminal({cursorBlink:n,disableStdin:!n,theme:kt,scrollback:F==="full"?5e3:1e3}),w=new Ze.FitAddon;if(C.loadAddon(w),C.open(y),p.current=C,b.current=w,n&&(i||u.current)){u.current=!1;try{C.focus()}catch{}}n&&C.onData(re=>{const ne=Et(re);if(ne.length!==0){if(D&&!N){h.current+=ne,G();return}K(ne)}});const v=()=>y.clientWidth>0&&y.clientHeight>0,q=(re=!1)=>{if(!v())return!1;const ne=C.cols,He=C.rows;try{w.fit()}catch{return!1}return C.cols>0&&C.rows>0&&(re||C.cols!==ne||C.rows!==He)&&te(C.cols,C.rows),!0};let B=null,X=null,ce=null,Ge=0;const Ae=()=>{B||(B=new ResizeObserver(()=>{X&&clearTimeout(X),X=setTimeout(()=>{X=null,q()},100)}),B.observe(y))},Ce=()=>{ce=requestAnimationFrame(()=>{if(ce=null,!(_||!I)){if(q(!0)){Ae();return}if(Ge++<5){Ce();return}Ae()}})};return Ce(),()=>{_=!0,ce!==null&&cancelAnimationFrame(ce),d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),j.current!==null&&(clearTimeout(j.current),j.current=null),T.current++,f.current=[],x.current=0,l.current=Promise.resolve(),X&&clearTimeout(X),B==null||B.disconnect(),p.current=null,b.current=null;try{C.dispose()}catch(re){console.warn("[pane-terminal] dispose failed:",re)}}},[G,s,i,I,N,n,K,D,F,te]);const E=()=>{var y;if(n){G();try{(y=p.current)==null||y.focus()}catch{}}},z=o&&o>0?{maxHeight:`${o*wt}px`}:void 0;return e.jsxs("div",{className:r??"flex flex-col h-full w-full min-h-0 bg-[#e1e2e7]",children:[($||A)&&e.jsx("div",{className:"px-3 py-1 text-[11px] font-mono text-red-300 bg-red-950/40 border-b border-red-900/60",children:A?"session ended":$}),e.jsx("div",{ref:m,className:"flex-1 min-h-0 overflow-hidden px-2 py-1.5",style:z,onMouseDown:E})]})}const Rt={unknown:{label:"Unknown",cls:"bg-slate-100 text-slate-700"},idle:{label:"Idle",cls:"bg-gray-100 text-gray-700"},pending:{label:"Pending user",cls:"bg-amber-200 text-amber-900"},working:{label:"Working",cls:"bg-green-100 text-green-800"},waiting:{label:"Waiting",cls:"bg-blue-100 text-blue-800"},error:{label:"Error",cls:"bg-red-100 text-red-800"}},At={present:{label:"Session present",cls:"bg-emerald-100 text-emerald-800"},absent:{label:"No session",cls:"bg-gray-100 text-gray-700"},unreachable:{label:"Host unreachable",cls:"bg-amber-100 text-amber-800"},unknown:{label:"Session unknown",cls:"bg-slate-100 text-slate-600"}};function Ct({agent:s,projectId:t,role:n,onDeleted:o,pendingRestart:r=!1,terminalLoading:i=!1,showTaskBinding:c=!0,terminalMode:m="activity-preview"}){var G,E,z,y,_,C,w;const[p,b]=a.useState(!1),[u,h]=a.useState(null),{show:f}=le(),{flagDirty:x}=xe(),[d,j]=a.useState(!1),[l,T]=a.useState(null),[$,S]=a.useState(!1),[A,g]=a.useState(!1),[R,k]=a.useState(!1),P=(G=s.binding)==null?void 0:G.taskId,N=((E=s.binding)==null?void 0:E.status)==="awaiting_human",D=!!((z=s.binding)!=null&&z.creationToken)&&!((y=s.binding)!=null&&y.paneId)&&!N&&s.reason!=="PENDING_HUMAN",F=D?{label:"Starting",cls:"bg-sky-100 text-sky-800"}:Rt[s.runtimeStatus],I=D?{label:"Starting session",cls:"bg-sky-100 text-sky-800"}:At[s.tmuxSessionStatus],M=m==="activity-preview"&&!D&&(s.runtimeStatus==="working"||s.runtimeStatus==="pending"),Q=m==="embedded-full",U=i||r||D,J=i?"Agent 状态加载中":r?"重启 baxian server 后可用":"Agent 正在启动",Y=async()=>{b(!0),h(null);try{await O.agents.stop(s.id)}catch(v){h(v instanceof Error?v.message:String(v))}finally{b(!1)}},H=async()=>{if(P&&window.confirm(`请 QA 对 task ${P} 重审?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`)){S(!0);try{const v=await O.tasks.review(P);f({kind:"success",title:`已派 QA 重审 (round ${v.reviewRound})`})}catch(v){f({kind:"error",title:"Review 派发失败",body:v instanceof Error?v.message:String(v)})}finally{S(!1)}}},V=async()=>{k(!0);try{(await O.projects.bootstrap(t)).ok?f({kind:"success",title:"Bootstrap retry 完成",body:"agent 状态将在下一次刷新生效。"}):f({kind:"warn",title:"Bootstrap retry 仍失败",body:"看一下红色错误卡的最新原因,按提示修复后再试。"})}catch(v){f({kind:"error",title:"Bootstrap retry 失败",body:v instanceof Error?v.message:String(v)})}finally{k(!1)}},K=async()=>{if(window.confirm(`确认 Resume Agent ${s.id}?baxian 会清除 awaiting_human 状态,agent 重新可派遣。`)){g(!0);try{const v=await O.projects.resumeAgent(t,s.id);f({kind:"success",title:`Agent ${s.id} 已 Resume`,body:v.releasedBinding?"原任务已释放,agent 可接新任务。":"保留绑定(原任务仍 active)。"})}catch(v){f({kind:"error",title:"Resume 失败",body:v instanceof Error?v.message:String(v)})}finally{g(!1)}}},te=async()=>{if(window.confirm(`确认删除 Agent ${s.id}?此操作不可撤销`)){j(!0),T(null);try{const v=await O.projects.deleteAgent(t,s.id);v!=null&&v.restartRequired&&x();const q=(v==null?void 0:v.removed)??[s.id];if(q.length>1){const B=q.filter(X=>X!==s.id).join(", ");f({kind:"warn",title:`已删除 Agent ${s.id}`,body:`配对的 QA Agent ${B} 也被一并移除。`})}else f({kind:"success",title:`Agent ${s.id} 已删除`});o==null||o()}catch(v){T(v instanceof Error?v.message:String(v))}finally{j(!1)}}};return e.jsxs("div",{className:"bg-white rounded-lg border p-4 min-w-0 h-full flex flex-col",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2 mb-2",children:[e.jsx("span",{className:"font-mono font-bold",children:s.id}),e.jsxs("div",{className:"flex flex-wrap justify-end gap-1",children:[N&&e.jsx("span",{className:"px-2 py-0.5 rounded text-xs font-medium bg-amber-200 text-amber-900",title:((_=s.binding)==null?void 0:_.awaitingReason)??"需人工处理",children:"Held"}),e.jsx("span",{className:`px-2 py-0.5 rounded text-xs font-medium ${F.cls}`,children:F.label}),e.jsx("span",{className:`px-2 py-0.5 rounded text-xs font-medium ${I.cls}`,children:I.label}),s.stale&&e.jsx("span",{className:"px-2 py-0.5 rounded text-xs font-medium bg-orange-100 text-orange-800",title:s.observedAt?`Last observed at ${s.observedAt}`:void 0,children:"Stale"})]})]}),D&&e.jsx("div",{className:"text-xs text-sky-900 mb-2 bg-sky-50 border border-sky-200 px-2 py-2 rounded",children:"Agent 正在启动,终端可用后会自动刷新。"}),N&&e.jsxs("div",{className:"text-xs text-amber-900 mb-2 bg-amber-50 border border-amber-200 px-2 py-2 rounded",children:[e.jsx("span",{className:"font-mono",children:(C=s.binding)==null?void 0:C.awaitingPhase}),((w=s.binding)==null?void 0:w.awaitingReason)&&e.jsxs("span",{children:[" · ",s.binding.awaitingReason]})]}),!D&&s.runtimeStatus==="pending"&&e.jsxs("div",{className:"text-xs text-amber-900 mb-2 bg-amber-50 border border-amber-200 px-2 py-2 rounded space-y-1",children:[e.jsx("div",{className:"font-medium",children:"等待人工介入"}),e.jsxs("div",{children:["Agent 正在等待人工输入。请打开 ",e.jsx(ee,{to:`/terminal/${s.id}`,className:"text-blue-700 underline",children:"Terminal"})," 处理; 处理完后状态会随下一次观测刷新。"]})]}),s.latestError&&e.jsxs("div",{className:"text-xs text-red-700 mb-2 bg-red-50 border border-red-200 px-2 py-2 rounded space-y-1",children:[e.jsx("div",{className:"font-medium break-words",children:s.latestError.message}),e.jsxs("div",{className:"text-[11px] text-red-600",children:[s.latestError.reason," · ",s.latestError.occurredAt]})]}),s.latestBootstrapError&&e.jsxs("div",{className:"text-xs text-red-700 mb-2 bg-red-50 border border-red-200 px-2 py-2 rounded space-y-1",children:[e.jsx("div",{className:"font-medium break-words",children:s.latestBootstrapError.message}),s.latestBootstrapError.recommendation&&e.jsx("div",{className:"break-words",children:s.latestBootstrapError.recommendation}),e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsxs("div",{className:"text-[11px] text-red-600 truncate",children:[s.latestBootstrapError.reason," · ",s.latestBootstrapError.occurredAt]}),e.jsx("button",{type:"button",onClick:V,disabled:R,className:"text-[11px] px-2 py-1 rounded border border-red-300 bg-white text-red-700 hover:bg-red-100 disabled:opacity-50 disabled:cursor-not-allowed shrink-0",children:R?"Retrying…":"Retry bootstrap"})]})]}),c&&P&&e.jsxs("div",{className:"text-sm text-gray-500 mb-2",children:["Task: ",P]}),M&&e.jsx("div",{className:"mb-2 border border-zinc-800",style:{backgroundColor:he},children:e.jsx(je,{agentId:s.id,mode:"preview",maxLines:6,interactive:!1})}),Q&&e.jsx("div",{className:"mt-3 mb-2 h-80 min-h-0 overflow-hidden border border-zinc-800",style:{backgroundColor:he},children:U?e.jsx("div",{className:"flex h-full items-center justify-center px-3 text-sm text-gray-600",children:J}):e.jsx(je,{agentId:s.id,mode:"full",interactive:!0,autoFocus:!1,deferFullUntilFocus:!0})}),r&&e.jsx("div",{className:"text-xs text-amber-700 mb-2 bg-amber-50 px-2 py-1 rounded",children:"⚠️ 重启 baxian server 后生效"}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-x-3 gap-y-2 items-center",children:[U?e.jsx("span",{className:"text-sm text-gray-400 cursor-not-allowed",title:J,children:"Terminal"}):e.jsx(ee,{to:`/terminal/${s.id}`,className:"text-sm text-blue-600 hover:underline",children:"Terminal"}),!r&&s.runtimeStatus==="working"&&e.jsx("button",{onClick:Y,disabled:p,className:"text-sm text-red-600 hover:underline disabled:opacity-50",children:p?"Stopping…":"Stop"}),u&&e.jsx("span",{className:"text-xs text-red-500",children:u}),N&&e.jsx("button",{type:"button",onClick:K,disabled:A,title:"清除 awaiting_human 状态,让 agent 重新可派遣",className:"text-sm text-amber-700 hover:underline disabled:opacity-50",children:A?"Resuming…":"Resume"}),!r&&P&&n==="dev"&&e.jsx("button",{type:"button",onClick:H,disabled:$,title:`让 QA 立即对 task ${P} 跑一轮 review(需要该 task 已有 PR)`,className:"text-sm text-purple-700 hover:underline disabled:opacity-50",children:$?"Dispatching…":"Request QA review"}),e.jsx("button",{type:"button",onClick:te,disabled:d,className:"text-sm text-red-600 hover:underline disabled:opacity-50 ml-auto","aria-label":`Delete agent ${s.id}`,children:d?"删除中…":"🗑"}),l&&e.jsx("span",{className:"text-xs text-red-500",children:l})]})]})}const Tt=new Set(["in_progress","review","fixing","approved"]);function Be({group:s,projectId:t,agentsById:n,agentsLoaded:o,agentsError:r=!1,tasks:i,onDeleted:c,terminalMode:m="activity-preview"}){const p=s.find(x=>x.role==="dev")??s[0],b=s.find(x=>x.role==="qa"),u=i.filter(x=>It(x,p==null?void 0:p.id,b==null?void 0:b.id)),h=`Agent group ${s.map(x=>x.id).join(" / ")}`,f=m==="embedded-full"?s.length<=1?"lg:grid-cols-1":s.length===2?"lg:grid-cols-2":s.length===3?"lg:grid-cols-3":"lg:grid-cols-4":"sm:grid-cols-2";return e.jsxs("div",{role:"group","aria-label":h,className:"min-w-0",children:[u.length>0?e.jsx("div",{className:"mb-2 max-h-28 overflow-y-auto rounded border bg-white divide-y",children:u.map(x=>{const d=x.phase==="spec"?x.specReviewRound??0:x.reviewRound;return e.jsxs(ee,{to:`/task/${x.id}`,className:"flex items-center gap-3 px-3 py-2 text-sm hover:bg-gray-50",children:[e.jsxs("div",{className:"min-w-0 flex-1 flex items-center gap-2",children:[e.jsx("span",{className:"font-mono text-xs text-blue-700 shrink-0",children:x.id}),e.jsx("span",{className:"truncate font-medium text-gray-900",children:x.title})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("span",{className:"text-xs px-2 py-0.5 rounded bg-gray-100 text-gray-700",children:x.status}),e.jsxs("span",{"aria-label":`Round ${d}`,className:"text-xs font-semibold px-2 py-0.5 rounded bg-blue-100 text-blue-700",children:["Round ",d]})]})]},x.id)})}):e.jsx("div",{className:"mb-2 rounded border border-dashed bg-white px-3 py-2 text-sm text-gray-400","aria-label":`${h} no active task`,children:"暂无任务"}),e.jsx("div",{className:`grid grid-cols-1 ${f} gap-4`,children:s.map(x=>{const d=n.get(x.id),j=d??{id:x.id,projectId:t,runtimeStatus:"unknown",tmuxSessionStatus:"unknown",stale:!0};return e.jsx(Ct,{agent:j,projectId:t,role:x.role,pendingRestart:o&&!d,terminalLoading:!o&&!d&&!r,onDeleted:c,showTaskBinding:!1,terminalMode:m},x.id)})})]})}function It(s,t,n){return!(!t||!Tt.has(s.status)||!(s.agentId===t||s.preferredAgentId===t)||n&&s.qaAgentId&&s.qaAgentId!==n)}const Pt={sm:"max-w-md",md:"max-w-lg",lg:"max-w-2xl"},Pe='input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])';function fe({open:s,onClose:t,title:n,children:o,size:r="md"}){const i=a.useRef(null),c=a.useRef(null),m=a.useRef(t);return a.useEffect(()=>{m.current=t},[t]),a.useEffect(()=>{if(!s)return;c.current=document.activeElement;const p=h=>{if(h.key==="Escape"){m.current();return}if(h.key!=="Tab")return;const f=i.current;if(!f)return;const x=Array.from(f.querySelectorAll(Pe)).filter(T=>T.offsetParent!==null||T===document.activeElement);if(x.length===0){h.preventDefault();return}const d=x[0],j=x[x.length-1],l=document.activeElement;h.shiftKey&&(l===d||!f.contains(l))?(h.preventDefault(),j.focus()):!h.shiftKey&&(l===j||!f.contains(l))&&(h.preventDefault(),d.focus())};document.addEventListener("keydown",p);const b=document.body.style.overflow;document.body.style.overflow="hidden";const u=i.current;if(u){const h=u.querySelector(Pe);h==null||h.focus()}return()=>{var h,f;document.removeEventListener("keydown",p),document.body.style.overflow=b,(f=(h=c.current)==null?void 0:h.focus)==null||f.call(h)}},[s]),s?e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-3 sm:px-4",onClick:()=>m.current(),role:"presentation",children:e.jsxs("div",{ref:i,className:`bg-white rounded-lg shadow-xl w-full ${Pt[r]} max-h-[90vh] overflow-auto`,onClick:p=>p.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":n,children:[e.jsxs("div",{className:"flex items-center justify-between px-6 py-4 border-b",children:[e.jsx("h2",{className:"text-lg font-semibold",children:n}),e.jsx("button",{type:"button",onClick:()=>m.current(),className:"text-gray-400 hover:text-gray-600","aria-label":"Close",children:"✕"})]}),e.jsx("div",{className:"px-6 py-4",children:o})]})}):null}const $t=/^[a-z][a-z0-9-]{1,31}$/,Dt=/^[A-Za-z0-9_-][A-Za-z0-9._-]*\/[A-Za-z0-9_-][A-Za-z0-9._-]*$/;function Ot({open:s,onClose:t,onCreated:n}){const[o,r]=a.useState(""),[i,c]=a.useState(""),[m,p]=a.useState(null),[b,u]=a.useState(!1),[h,f]=a.useState(null),[x,d]=a.useState({}),[j,l]=a.useState(new Set),T=a.useRef(0),{show:$}=le(),{flagDirty:S}=xe();a.useEffect(()=>{if(!s)return;T.current+=1;const k=T.current;r(""),c(""),p(null),f(null),d({}),l(new Set),O.config.get().then(P=>{k===T.current&&l(new Set(P.project.map(N=>N.id)))}).catch(()=>{})},[s]);const A=()=>{b||t()},g=()=>{const k={};return o?$t.test(o)?j.has(o)&&(k.id="该 id 已被占用"):k.id="小写字母开头,只含 a-z 0-9 -,长度 2-32":k.id="必填",i?Dt.test(i)||(k.repo="需为 owner/repo 形式"):k.repo="必填",d(k),Object.keys(k).length===0},R=async k=>{if(k.preventDefault(),!!g()){u(!0),f(null);try{const P=await O.projects.create({id:o,repo:i,merge:m});P.restartRequired&&S(),$({kind:"success",title:`项目 ${P.project.id} 已创建`}),n(P.project.id)}catch(P){f(P instanceof Error?P.message:String(P))}finally{u(!1)}}};return e.jsx(fe,{open:s,onClose:A,title:"新建项目",size:"md",children:e.jsxs("form",{onSubmit:R,className:"space-y-4",children:[h&&e.jsx("div",{className:"bg-red-50 border border-red-200 text-red-800 px-3 py-2 rounded text-sm",children:h}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"proj-id",children:"项目 ID"}),e.jsx("input",{id:"proj-id",type:"text",value:o,onChange:k=>r(k.target.value),className:"w-full border rounded px-3 py-2",placeholder:"kongkong",disabled:b}),x.id&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:x.id})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"proj-repo",children:"GitHub 仓库"}),e.jsx("input",{id:"proj-repo",type:"text",value:i,onChange:k=>c(k.target.value),className:"w-full border rounded px-3 py-2",placeholder:"rockdai/baxian",disabled:b}),x.repo&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:x.repo})]}),e.jsxs("div",{children:[e.jsx("span",{className:"block text-sm font-medium mb-1",children:"合并策略"}),e.jsxs("label",{className:"flex items-center gap-2 mb-1",children:[e.jsx("input",{type:"radio",name:"merge",checked:m===null,onChange:()=>p(null),disabled:b}),e.jsx("span",{className:"text-sm",children:"人类合并(默认)"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"merge",checked:m==="auto",onChange:()=>p("auto"),disabled:b}),e.jsx("span",{className:"text-sm",children:"QA Approve 后自动合并"})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4 border-t",children:[e.jsx("button",{type:"button",onClick:A,disabled:b,className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50",children:"取消"}),e.jsx("button",{type:"submit",disabled:b,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50",children:b?"创建中…":"创建"})]})]})})}const $e=/^[a-z][a-z0-9-]{1,31}$/,_t=500,De={id:"",role:"dev",pairWith:"",mode:"local",hostname:"",user:"",runtime:"",workdir:"",yolo:!0,model:"",addDirs:""};function Qe({open:s,onClose:t,projectId:n,onCreated:o}){var G;const[r,i]=a.useState(De),[c,m]=a.useState(null),[p,b]=a.useState(new Set),[u,h]=a.useState(null),[f,x]=a.useState(!1),[d,j]=a.useState(!1),[l,T]=a.useState(null),$=a.useRef(null),S=a.useRef(null),A=a.useRef(0),{show:g}=le(),{flagDirty:R}=xe();a.useEffect(()=>{if(!s)return;A.current+=1;const E=A.current;i(De),m(null),b(new Set),h(null),x(!1),T(null),O.config.get().then(z=>{if(E!==A.current)return;const y=z.project.find(C=>C.id===n)??null;m(y);const _=new Set;z.project.forEach(C=>C.agent.forEach(w=>w.forEach(v=>_.add(v.id)))),b(_)}).catch(()=>{})},[s,n]);const k=()=>{d||t()},P=a.useCallback(()=>{$.current&&$.current.abort();const E=new AbortController;$.current=E,x(!0),T(null);const z=r.mode==="remote"?{hostname:r.hostname,user:r.user||void 0}:void 0;O.agents.probe(r.mode,z,{signal:E.signal}).then(y=>{E.signal.aborted||(h(y),T(null))}).catch(y=>{E.signal.aborted||(h(null),T(y instanceof Error?y.message:String(y)))}).finally(()=>{$.current===E&&x(!1)})},[r.mode,r.hostname,r.user]);a.useEffect(()=>{if(s&&(h(null),$.current&&$.current.abort(),!(r.mode==="remote"&&!r.hostname)))return S.current&&clearTimeout(S.current),S.current=setTimeout(P,_t),()=>{S.current&&clearTimeout(S.current)}},[s,r.mode,r.hostname,r.user,P]),a.useEffect(()=>{s||$.current&&$.current.abort()},[s]),a.useEffect(()=>()=>{$.current&&$.current.abort(),S.current&&clearTimeout(S.current)},[]);const N=(c==null?void 0:c.agent.filter(E=>E.length===1&&E[0].role==="dev").map(E=>E[0]))??[],D=N.length>0,F=$e.test(r.id)&&!p.has(r.id),I=r.mode==="local"||r.mode==="remote"&&r.hostname.length>0,M=r.runtime!==""&&(r.runtime==="claude-code"?!!(u!=null&&u.runtimes["claude-code"].ok):!!(u!=null&&u.runtimes.codex.ok)),Q=!!(u!=null&&u.tmux.ok),U=r.mode==="local"||!!((G=u==null?void 0:u.ssh)!=null&&G.ok),J=r.role==="dev"||r.role==="qa"&&r.pairWith!=="",Y=!d&&F&&I&&J&&M&&Q&&U,H=async E=>{if(E.preventDefault(),!!Y){j(!0),T(null);try{const z=r.addDirs.split(`
2
- `).map(C=>C.trim()).filter(C=>C.length>0),y={id:r.id,role:r.role,runtime:r.runtime,mode:r.mode,...r.mode==="remote"?{host:{hostname:r.hostname,...r.user?{user:r.user}:{}}}:{},...r.workdir?{workdir:r.workdir}:{},yolo:r.yolo,...r.model.trim()?{model:r.model.trim()}:{},...z.length>0?{addDirs:z}:{},...r.role==="qa"?{pairWith:r.pairWith}:{}},_=await O.projects.addAgent(n,y);_.restartRequired&&R(),g({kind:"success",title:`Agent ${_.agent.id} 已添加到 ${n}`}),o(),t()}catch(z){T(z instanceof Error?z.message:String(z))}finally{j(!1)}}},V=({rt:E})=>{if(r.mode==="remote"&&!r.hostname)return e.jsx("span",{className:"text-xs text-gray-400 ml-2",children:"(请先填写 hostname)"});if(f)return e.jsx("span",{className:"text-xs text-gray-400 ml-2",children:"…探测中"});if(!u)return e.jsx("span",{className:"text-xs text-gray-400 ml-2",children:"?"});const y=u.runtimes[E];return y.ok?e.jsxs("span",{className:"text-xs text-green-600 ml-2",children:["✓ ",y.path??""]}):e.jsxs("span",{className:"text-xs text-red-500 ml-2",title:y.message,children:["⨯ ",y.message]})},K=()=>r.mode==="remote"&&!r.hostname?null:f?e.jsx("div",{className:"text-xs text-gray-400",children:"tmux: …探测中"}):u?u.tmux.ok?e.jsxs("div",{className:"text-xs text-green-600",children:["tmux: ✓ ",u.tmux.path??""]}):e.jsxs("div",{className:"text-xs text-red-500",children:["tmux: ⨯ ",u.tmux.message]}):null,te=()=>r.mode!=="remote"||!r.hostname||!(u!=null&&u.ssh)?null:u.ssh.ok?e.jsxs("div",{className:"text-xs text-green-600",children:["SSH: ✓ ",u.ssh.message]}):e.jsxs("div",{className:"text-xs text-red-500",children:["SSH: ⨯ ",u.ssh.message]});return e.jsx(fe,{open:s,onClose:k,title:`添加 Agent 到 ${n}`,size:"lg",children:e.jsxs("form",{onSubmit:H,className:"space-y-4",children:[l&&e.jsx("div",{className:"bg-red-50 border border-red-200 text-red-800 px-3 py-2 rounded text-sm",children:l}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"agent-id",children:"Agent ID"}),e.jsx("input",{id:"agent-id",type:"text",value:r.id,onChange:E=>i({...r,id:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"kk-cc",disabled:d}),r.id&&!$e.test(r.id)&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:"小写字母开头,只含 a-z 0-9 -,长度 2-32"}),r.id&&p.has(r.id)&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:"该 id 已被占用(全局唯一)"})]}),e.jsxs("div",{children:[e.jsx("span",{className:"block text-sm font-medium mb-1",children:"角色"}),e.jsxs("label",{className:"inline-flex items-center gap-2 mr-4",children:[e.jsx("input",{type:"radio",name:"role",checked:r.role==="dev",onChange:()=>i({...r,role:"dev",pairWith:""}),disabled:d}),e.jsx("span",{className:"text-sm",children:"Dev"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",title:D?"":"请先创建一个 Dev Agent",children:[e.jsx("input",{type:"radio",name:"role",checked:r.role==="qa",onChange:()=>i({...r,role:"qa"}),disabled:d||!D}),e.jsx("span",{className:`text-sm ${D?"":"text-gray-400"}`,children:"QA"})]})]}),r.role==="qa"&&e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"pair-with",children:"配对 Dev Agent"}),e.jsxs("select",{id:"pair-with",value:r.pairWith,onChange:E=>i({...r,pairWith:E.target.value}),className:"w-full border rounded px-3 py-2",disabled:d,children:[e.jsx("option",{value:"",children:"请选择"}),N.map(E=>e.jsxs("option",{value:E.id,children:[E.id," (dev, ",E.mode,")"]},E.id))]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"block text-sm font-medium mb-1",children:"运行模式"}),e.jsxs("label",{className:"inline-flex items-center gap-2 mr-4",children:[e.jsx("input",{type:"radio",name:"mode",checked:r.mode==="local",onChange:()=>i({...r,mode:"local",hostname:"",user:""}),disabled:d}),e.jsx("span",{className:"text-sm",children:"本机"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"mode",checked:r.mode==="remote",onChange:()=>i({...r,mode:"remote"}),disabled:d}),e.jsx("span",{className:"text-sm",children:"远程 (SSH)"})]})]}),r.mode==="remote"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"hostname",children:"Hostname"}),e.jsx("input",{id:"hostname",type:"text",value:r.hostname,onChange:E=>i({...r,hostname:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"macmini-2026",disabled:d}),e.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"端口/私钥/跳板机请配 ~/.ssh/config"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"user",children:"User(可选)"}),e.jsx("input",{id:"user",type:"text",value:r.user,onChange:E=>i({...r,user:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"留空则读 ~/.ssh/config 的 User",disabled:d})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("span",{className:"block text-sm font-medium",children:"运行时"}),e.jsx("button",{type:"button",onClick:P,className:"text-xs text-blue-600 hover:underline disabled:opacity-50 disabled:no-underline disabled:cursor-not-allowed",disabled:d||f||r.mode==="remote"&&!r.hostname,children:"↻ 重新探测"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"runtime",checked:r.runtime==="claude-code",onChange:()=>i({...r,runtime:"claude-code"}),disabled:d||(u?!u.runtimes["claude-code"].ok:!1)}),e.jsx("span",{className:"text-sm",children:"Claude Code"}),e.jsx(V,{rt:"claude-code"})]}),e.jsxs("label",{className:"flex items-center gap-2 mt-1",children:[e.jsx("input",{type:"radio",name:"runtime",checked:r.runtime==="codex",onChange:()=>i({...r,runtime:"codex"}),disabled:d||(u?!u.runtimes.codex.ok:!1)}),e.jsx("span",{className:"text-sm",children:"Codex"}),e.jsx(V,{rt:"codex"})]}),e.jsx("div",{className:"mt-2",children:e.jsx(K,{})}),e.jsx("div",{children:e.jsx(te,{})})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"workdir",children:"Workdir(可选)"}),e.jsx("input",{id:"workdir",type:"text",value:r.workdir,onChange:E=>i({...r,workdir:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"留空时自动 clone 到 ~/.baxian/repos/<owner>/<repo>",disabled:d})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"model",children:"Model(可选)"}),e.jsx("input",{id:"model",type:"text",value:r.model,onChange:E=>i({...r,model:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:r.runtime==="codex"?"例: o3 / gpt-4o(留空走 default)":"例: sonnet / opus / claude-sonnet-4-6(留空走 default)",disabled:d}),e.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"透传到 launch 命令的 --model 参数;留空跟随 CLI 默认。"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"addDirs",children:"Additional Dirs(可选)"}),e.jsx("textarea",{id:"addDirs",value:r.addDirs,onChange:E=>i({...r,addDirs:E.target.value}),className:"w-full border rounded px-3 py-2 font-mono text-xs",rows:3,placeholder:`每行一个绝对路径,例:
3
- /Users/me/shared-libs
4
- /Users/me/extra-repo`,disabled:d}),e.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"透传到 --add-dir。当前 YOLO 模式下不影响权限拦截,主要用于让 CLI 把额外目录纳入工作根。"})]}),e.jsx("div",{className:"bg-amber-50 border border-amber-200 px-3 py-2 rounded",children:e.jsxs("label",{className:"flex items-start gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",className:"mt-1",checked:r.yolo,onChange:E=>i({...r,yolo:E.target.checked}),disabled:d}),e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"font-medium",children:"YOLO 模式(推荐开启)"}),e.jsxs("div",{className:"text-xs text-amber-900 mt-1",children:["Agent 自主执行所有命令、文件改动,无需逐条确认。开启后体验更顺滑, 但",e.jsx("strong",{children:"请确认在受控环境(容器、隔离 worktree)中运行"}),"。"]})]})]})}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4 border-t",children:[e.jsx("button",{type:"button",onClick:k,disabled:d,className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50",children:"取消"}),e.jsx("button",{type:"submit",disabled:!Y,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50",children:d?"添加中…":"添加 Agent"})]})]})})}const Oe=200,_e=16e3;function Ee(s){const t=s.mode==="edit",n=ve(),{show:o}=le(),r=t?s.task.projectId:s.projectId,i=t?s.task.title:"",c=t?s.task.description:"",m=t?s.task.preferredAgentId:"",[p,b]=a.useState([]),[u,h]=a.useState([]),[f,x]=a.useState(r??""),[d,j]=a.useState(m),[l,T]=a.useState(i),[$,S]=a.useState(c),[A,g]=a.useState(!1),[R,k]=a.useState(null),P=a.useRef(0);a.useEffect(()=>{if(!s.open)return;P.current+=1;const w=P.current;b([]),h([]),x(r??""),j(m),T(i),S(c),k(null),g(!1),Promise.all([O.projects.list(),O.agents.list()]).then(([v,q])=>{w===P.current&&(b(v),h(q))}).catch(v=>{w===P.current&&k(v instanceof Error?v.message:String(v))})},[s.open,r,i,c,m]);const N=a.useMemo(()=>p.find(w=>w.id===f)??null,[p,f]),D=a.useMemo(()=>N?N.agent.flat().filter(w=>w.role==="dev"):[],[N]),F=a.useMemo(()=>new Set(u.map(w=>w.id)),[u]),I=a.useMemo(()=>D.filter(w=>F.has(w.id)),[D,F]),M=a.useMemo(()=>D.filter(w=>!F.has(w.id)),[D,F]);a.useEffect(()=>{if(!t){if(I.length===0){d!==""&&j("");return}I.find(w=>w.id===d)||j(I[0].id)}},[I,d,t]);const Q=!t||I.find(w=>w.id===d),U=t&&!Q&&!!d,J=U&&M.some(w=>w.id===d),Y=J?`当前 dev "${d}" 在 baxian.json 中存在但 runtime 未加载,可能是手动编辑过配置文件;重启 server 可拉起`:U?`当前 dev "${d}" 不在 runtime(可能已从 project 配置移除);保存可能失败,请确认或选择新 dev`:!f||I.length>0?null:M.length>0?"baxian.json 里有 dev agent 但 runtime 未加载(可能是手动编辑过配置);重启 server 后生效":"请先为项目添加 dev agent",H=l.trim(),V=$.trim(),K=I.length>0||U,G=!!f&&K&&!!d&&H.length>0&&V.length>0&&!A,E=()=>{A||s.onClose()},z=async w=>{var v,q;if(w.preventDefault(),!!G){g(!0),k(null);try{if(s.mode==="edit"){const B=await O.tasks.update(s.task.id,{title:H,description:V,preferredAgentId:d});o({kind:"success",title:"任务已更新"}),(v=s.onUpdated)==null||v.call(s,B),s.onClose()}else{const B=await O.tasks.create({projectId:f,title:H,description:V,preferredAgentId:d});o({kind:"success",title:"任务已创建"}),(q=s.onCreated)==null||q.call(s,B),s.onClose(),n(`/task/${B.id}`)}}catch(B){k(B instanceof Error?B.message:String(B))}finally{g(!1)}}},y=t?"编辑 Task":"新建 Task",_=t?A?"保存中…":"保存":A?"创建中…":"创建",C=!t&&!r;return e.jsx(fe,{open:s.open,onClose:E,title:y,size:"md",children:e.jsxs("form",{onSubmit:z,className:"space-y-4",children:[R&&e.jsx("div",{className:"bg-red-50 border border-red-200 text-red-800 px-3 py-2 rounded text-sm",children:R}),C&&e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-project",children:"Project"}),e.jsxs("select",{id:"task-project",value:f,onChange:w=>x(w.target.value),className:"w-full border rounded px-3 py-2 disabled:bg-gray-50",disabled:A,required:!0,children:[e.jsx("option",{value:"",disabled:!0,children:"选择项目"}),p.map(w=>e.jsx("option",{value:w.id,children:w.id},w.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-dev",children:"Dev Agent"}),e.jsxs("select",{id:"task-dev",value:d,onChange:w=>j(w.target.value),className:"w-full border rounded px-3 py-2 disabled:bg-gray-50",disabled:A||I.length===0&&!U||I.length===1&&I[0].id===d&&!U,required:!0,children:[I.length===0&&!U&&e.jsx("option",{value:"",disabled:!0,children:"无可用 dev"}),U&&e.jsxs("option",{value:d,children:[d," ",J?"(待重启)":"(不在 runtime)"]}),I.map(w=>e.jsx("option",{value:w.id,children:w.id},w.id))]}),Y&&e.jsx("div",{className:"text-xs text-amber-700 mt-1",children:Y})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-title",children:"Title"}),e.jsx("input",{id:"task-title",type:"text",value:l,onChange:w=>T(w.target.value),maxLength:Oe,className:"w-full border rounded px-3 py-2",placeholder:"一句话描述要做什么",disabled:A,required:!0}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1 text-right",children:[l.length," / ",Oe]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-description",children:"Description"}),e.jsx("textarea",{id:"task-description",value:$,onChange:w=>S(w.target.value),maxLength:_e,rows:8,className:"w-full border rounded px-3 py-2 font-mono text-sm",placeholder:"详细描述任务,支持 markdown",disabled:A,required:!0}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1 text-right",children:[$.length," / ",_e]})]}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4 border-t",children:[e.jsx("button",{type:"button",onClick:E,disabled:A,className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50",children:"取消"}),e.jsx("button",{type:"submit",disabled:!G,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50",children:_})]})]})})}function Lt(s){return Array.from(new TextEncoder().encode(s)).map(t=>t.toString(16).padStart(2,"0")).join("")}function Ft(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/realtime`}const zt=(s,t)=>t&&t.length>0?new WebSocket(s,t):new WebSocket(s);class Mt{constructor(t={}){L(this,"wsUrl");L(this,"wsFactory");L(this,"tokenProvider");L(this,"ws",null);L(this,"topics",new Map);L(this,"cache",new Map);L(this,"outbox",[]);L(this,"reconnectScheduler");L(this,"explicitlyClosed",!1);this.wsUrl=t.wsUrl??Ft(),this.wsFactory=t.wsFactory??zt,this.tokenProvider=t.tokenProvider??Ne,this.reconnectScheduler=new Me({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.topics.size>0})}subscribe(t,n,o){let r=this.topics.get(t);const i=!r;return r||(r={data:new Set,error:new Set},this.topics.set(t,r)),r.data.add(n),o&&r.error.add(o),i?(this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",topic:t})):this.cache.has(t)&&queueMicrotask(()=>{var c;(c=this.topics.get(t))!=null&&c.data.has(n)&&this.cache.has(t)&&n(this.cache.get(t))}),()=>this.unsubscribe(t,n,o)}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.topics.clear(),this.cache.clear(),this.outbox=[]}unsubscribe(t,n,o){const r=this.topics.get(t);r&&(r.data.delete(n),o&&r.error.delete(o),r.data.size===0&&r.error.size===0&&(this.topics.delete(t),this.cache.delete(t),this.wsSendOrQueue({op:"unsubscribe",topic:t}),this.topics.size===0&&this.teardownSocket()))}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const t=this.tokenProvider(),n=t?[`baxian.token.${Lt(t)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,n)}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 r=!1;o.onopen=()=>{if(o!==this.ws)return;r=!0,this.reconnectScheduler.reset();for(const c of this.topics.keys())try{o.send(JSON.stringify({op:"subscribe",topic:c}))}catch(m){console.warn("[events-client] resubscribe send failed:",m)}const i=this.outbox;this.outbox=[];for(const c of i)if(!(c.op==="subscribe"||c.op==="unsubscribe"))try{o.send(JSON.stringify(c))}catch(m){console.warn("[events-client] outbox flush failed:",m)}},o.onmessage=i=>{if(o!==this.ws)return;let c;try{const m=typeof i.data=="string"?i.data:String(i.data);c=JSON.parse(m)}catch{return}this.handleMessage(c)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&(r||this.broadcastConnectionError({code:"connection_failed",message:"WebSocket failed to connect (auth, network, or proxy issue)"}),this.topics.size!==0&&this.scheduleReconnect()))},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}broadcastConnectionError(t){for(const n of this.topics.values())for(const o of[...n.error])try{o(t)}catch(r){console.error("[events-client] error handler threw on connection error:",r)}}wsSendOrQueue(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(t));return}catch(n){console.warn("[events-client] send failed, will queue:",n)}this.outbox.push(t)}handleMessage(t){switch(t.type){case"data":{const n=this.topics.get(t.topic);if(this.cache.set(t.topic,t.data),!n)return;for(const o of[...n.data])try{o(t.data)}catch(r){console.error(`[events-client] handler threw on ${t.topic}:`,r)}break}case"error":{const n={code:t.code,message:t.message};if(t.topic){const o=this.topics.get(t.topic);if(o)for(const r of[...o.error])try{r(n)}catch(i){console.error(`[events-client] error handler threw on ${t.topic}:`,i)}}else console.warn("[events-client] connection-level error:",t.code,t.message);break}}}}let ge=null;function Re(){return ge||(ge=new Mt),ge}function Ue(){const[s,t]=a.useState(null),[n,o]=a.useState(!1),[r,i]=a.useState(null);return a.useEffect(()=>Re().subscribe("agents",m=>{i(null),t(m),o(!0)},m=>i(m)),[]),{data:s,loaded:n,error:r}}function Bt(s){const[t,n]=a.useState(null),[o,r]=a.useState(!1),[i,c]=a.useState(null);return a.useEffect(()=>(n(null),r(!1),c(null),Re().subscribe(`task:${s}`,p=>{c(null),n(p),r(!0)},p=>c(p))),[s]),{data:t,loaded:o,error:i}}function Qt(s){const[t,n]=a.useState(null),[o,r]=a.useState(!1),[i,c]=a.useState(null);return a.useEffect(()=>{if(!s){n(null),r(!1),c(null);return}n(null),r(!1),c(null);let m=!1,p=!1,b=!1;const u=Re().subscribe(`project-tasks:${s}`,h=>{m||(p=!0,c(null),n(h),r(!0))},h=>{m||(c(h),!(p||b)&&(b=!0,O.tasks.list(s).then(f=>{m||p||(n(f),r(!0))},f=>{console.warn(`[useProjectTasks] REST fallback failed for ${s}:`,f)})))});return()=>{m=!0,u()}},[s]),{data:t,loaded:o,error:i}}function Ut(){const[s,t]=a.useState([]),[n,o]=a.useState([]),[r,i]=a.useState(!1),[c,m]=a.useState(null),[p,b]=a.useState(null),[u,h]=a.useState(!1),[f,x]=a.useState(!1),[d,j]=a.useState({kind:"closed"}),l=a.useRef(0),{data:T,loaded:$,error:S}=Ue(),A=(S==null?void 0:S.message)??null,g=new Map((T??[]).map(N=>[N.id,N])),R=c??A??p,k=async()=>{const N=++l.current;try{const D=await O.projects.list();if(N!==l.current)return;t(D),m(null)}catch(D){if(N!==l.current)return;m(D instanceof Error?D.message:String(D))}finally{N===l.current&&i(!0)}},P=async()=>{try{const N=await O.tasks.list();o(N),b(null)}catch(N){b(N instanceof Error?N.message:String(N))}};return a.useEffect(()=>{k(),P()},[]),e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 mb-6",children:[e.jsx("h1",{className:"text-xl sm:text-2xl font-bold",children:"Dashboard"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{onClick:()=>h(!0),className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"+ 新建项目"}),e.jsx("button",{onClick:()=>x(!0),disabled:s.length===0,"aria-describedby":s.length===0?"create-task-hint":void 0,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:bg-gray-300 disabled:cursor-not-allowed",children:"+ 新建 Task"}),s.length===0&&e.jsx("span",{id:"create-task-hint",className:"text-xs text-gray-500 self-center",children:"请先创建项目"})]})]}),R&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",R]}),r&&s.length===0&&!c&&e.jsx("div",{className:"text-gray-500 text-sm py-12 text-center border-2 border-dashed rounded",children:'还没有项目。点击右上角"+ 新建项目"开始。'}),s.map(N=>e.jsxs("div",{className:"mb-8",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 mb-4",children:[e.jsx("h2",{className:"text-lg font-semibold",children:N.id}),e.jsx("span",{className:"text-sm text-gray-500 break-words min-w-0",children:N.repo}),e.jsx(ee,{to:`/project/${N.id}`,className:"text-sm text-blue-600 hover:underline ml-auto",children:"Details"})]}),N.agent.flat().length===0?e.jsx("div",{className:"text-gray-400 text-sm py-6 text-center border border-dashed rounded",children:"还没有 Agent。进入 Details 添加。"}):e.jsx("div",{className:"grid grid-cols-1 xl:grid-cols-2 gap-4",children:N.agent.map((D,F)=>e.jsx(Be,{group:D,projectId:N.id,agentsById:g,agentsLoaded:$,agentsError:!!S,tasks:n.filter(I=>I.projectId===N.id),onDeleted:()=>{k(),P()}},D.map(I=>I.id).join(":")||F))})]},N.id)),e.jsx(Ot,{open:u,onClose:()=>h(!1),onCreated:N=>{h(!1),k(),j({kind:"asking",projectId:N})}}),e.jsx(fe,{open:d.kind==="asking",onClose:()=>j({kind:"closed"}),title:"项目已创建",size:"sm",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-sm",children:"现在添加第一个 Agent,还是稍后再加?"}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:()=>j({kind:"closed"}),className:"px-4 py-2 border rounded text-sm hover:bg-gray-50",children:"稍后再加"}),e.jsx("button",{type:"button",onClick:()=>{d.kind==="asking"&&j({kind:"addingAgent",projectId:d.projectId})},className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"继续添加 Agent"})]})]})}),d.kind==="addingAgent"&&e.jsx(Qe,{open:!0,projectId:d.projectId,onClose:()=>j({kind:"closed"}),onCreated:()=>{k()}}),e.jsx(Ee,{open:f,onClose:()=>x(!1),onCreated:()=>{P()}})]})}function qe({tasks:s}){const t=ve();return s.length===0?e.jsx("div",{className:"text-gray-400 text-sm",children:"No tasks"}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left border-b text-xs text-gray-500",children:[e.jsx("th",{className:"py-2 pr-4 font-medium",children:"ID"}),e.jsx("th",{className:"py-2 pr-4 font-medium",children:"Title"}),e.jsx("th",{className:"py-2 pr-4 font-medium hidden sm:table-cell",children:"Agent"}),e.jsx("th",{className:"py-2 pr-4 font-medium",children:"Status"}),e.jsx("th",{className:"py-2 font-medium hidden sm:table-cell",children:"Round"})]})}),e.jsx("tbody",{children:s.map(n=>e.jsxs("tr",{className:"border-b hover:bg-gray-50 cursor-pointer",onClick:()=>t(`/task/${n.id}`),children:[e.jsx("td",{className:"py-2 pr-4 font-mono whitespace-nowrap",children:e.jsx(ee,{to:`/task/${n.id}`,className:"text-blue-600 hover:underline",onClick:o=>o.stopPropagation(),children:n.id})}),e.jsx("td",{className:"py-2 pr-4 break-words",children:n.title}),e.jsx("td",{className:"py-2 pr-4 font-mono text-xs hidden sm:table-cell",children:n.agentId?n.agentId:n.preferredAgentId?e.jsx("span",{className:"italic text-gray-500",children:n.preferredAgentId}):"-"}),e.jsxs("td",{className:"py-2 pr-4 whitespace-nowrap",children:[e.jsx("span",{className:"text-xs px-2 py-0.5 rounded bg-gray-100",children:n.status}),n.phase==="spec"&&e.jsx("span",{className:"ml-1 text-xs px-2 py-0.5 rounded bg-indigo-100 text-indigo-800",children:"spec"})]}),e.jsx("td",{className:"py-2 text-xs text-gray-500 hidden sm:table-cell",children:n.phase==="spec"?n.specReviewRound??0:n.reviewRound})]},n.id))})]})})}function qt(){const{id:s}=Se(),[t,n]=a.useState(null),[o,r]=a.useState(null),[i,c]=a.useState(!1),[m,p]=a.useState(!1),b=a.useRef(0),{data:u,loaded:h,error:f}=Ue(),{data:x,error:d}=Qt(s),j=(f==null?void 0:f.message)??null,l=(d==null?void 0:d.message)??null,T=x??[],$=new Map((u??[]).map(g=>[g.id,g])),S=o??j??l,A=a.useCallback(async g=>{const R=++b.current;try{const k=await O.projects.get(g);if(R!==b.current)return;n(k),r(null)}catch(k){if(R!==b.current)return;r(k instanceof Error?k.message:String(k))}},[]);return a.useEffect(()=>{s&&(n(null),r(null),A(s))},[s,A]),t?e.jsxs("div",{children:[S&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",S]}),e.jsx("h1",{className:"text-xl sm:text-2xl font-bold mb-2 break-words",children:t.id}),e.jsx("p",{className:"text-gray-500 mb-6 break-words",children:t.repo}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Agents"}),e.jsx("button",{onClick:()=>c(!0),className:"px-3 py-1.5 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"+ 添加 Agent"})]}),t.agent.flat().length===0?e.jsx("div",{className:"text-gray-400 text-sm py-6 text-center border border-dashed rounded mb-8",children:"还没有 Agent,点击右上角添加。"}):e.jsx("div",{className:"space-y-5 mb-8",children:t.agent.map((g,R)=>e.jsx(Be,{group:g,projectId:t.id,agentsById:$,agentsLoaded:h,agentsError:!!f,tasks:T,onDeleted:()=>{A(t.id)},terminalMode:"embedded-full"},g.map(k=>k.id).join(":")||R))}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Tasks"}),e.jsx("button",{onClick:()=>p(!0),className:"px-3 py-1.5 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"+ 新建 Task"})]}),e.jsx(qe,{tasks:T}),e.jsx(Qe,{open:i,projectId:t.id,onClose:()=>c(!1),onCreated:()=>{A(t.id)}}),e.jsx(Ee,{open:m,projectId:t.id,onClose:()=>p(!1)})]}):o?e.jsxs("div",{className:"text-red-600",children:["Error: ",o]}):e.jsx("div",{children:"Loading..."})}function Wt(){const{agentId:s}=Se();return s?e.jsxs("div",{className:"flex-1 min-h-0 flex flex-col border border-zinc-800 bg-[#e1e2e7] shadow-sm",children:[e.jsx("div",{className:"flex items-center gap-3 h-8 px-3 bg-zinc-900 border-b border-zinc-800 text-[11px] font-mono select-none",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"h-2 w-2 rounded-full bg-emerald-500","aria-hidden":!0}),e.jsx("span",{className:"text-zinc-200",children:s})]})}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(je,{agentId:s,mode:"full",interactive:!0})})]}):e.jsx("div",{children:"No agent specified"})}function Gt(){const[s,t]=a.useState([]),[n,o]=a.useState(null);return a.useEffect(()=>{let r=!1;return(async()=>{try{const i=await O.tasks.list();r||t(i)}catch(i){r||o(i instanceof Error?i.message:String(i))}})(),()=>{r=!0}},[]),e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl sm:text-2xl font-bold mb-6",children:"Tasks"}),n&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",n]}),e.jsx(qe,{tasks:s})]})}const We=new Set(["merged","failed","max_rounds","cancelled"]),Le=We,Ht={pending:"bg-gray-200 text-gray-800",in_progress:"bg-blue-200 text-blue-800",review:"bg-purple-200 text-purple-800",fixing:"bg-orange-200 text-orange-800",approved:"bg-green-100 text-green-800",merged:"bg-green-300 text-green-900",failed:"bg-red-200 text-red-800",max_rounds:"bg-red-200 text-red-800",cancelled:"bg-gray-400 text-gray-100"};function Jt(){const{id:s}=Se(),t=ve(),{show:n}=le(),[o,r]=a.useState(!1),[i,c]=a.useState(!1),[m,p]=a.useState(!1),[b,u]=a.useState(!1),[h,f]=a.useState(null),{data:x,loaded:d,error:j}=Bt(s??""),l=h??x,T=(j==null?void 0:j.message)??null;a.useEffect(()=>{f(null)},[s]),a.useEffect(()=>{h&&x&&x.updatedAt>=h.updatedAt&&f(null)},[h,x]);const $=I=>{f(I)};if(!s)return e.jsx("div",{className:"text-red-600",children:"Task ID required"});if(T&&!l)return e.jsxs("div",{className:"text-red-600",children:["Error: ",T]});if(d&&!l)return e.jsxs("div",{className:"text-red-600",children:["Task not found: ",s]});if(!l)return e.jsx("div",{children:"Loading..."});const S=l.status==="pending",A=l.status==="pending"||l.status==="in_progress",g=Le.has(l.status)&&!!l.preferredAgentId,R=!!l.prNumber,k=l.preferredAgentId==="",P=l.status==="approved"&&l.prNumber!==void 0,N=async()=>{if(confirm(`确定取消 task ${l.id}?`)){c(!0);try{const I=await O.tasks.update(l.id,{status:"cancelled"});$(I),n({kind:"success",title:"任务已取消"})}catch(I){n({kind:"error",title:"取消失败",body:I instanceof Error?I.message:String(I)})}finally{c(!1)}}},D=async()=>{const M=We.has(l.status)?`task ${l.id} 已是 ${l.status} 状态。手动请 QA 重审会再跑一轮 review,但状态机不会把 QA 结果带回主流程。继续?`:`请 QA 重审 task ${l.id}?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`;if(confirm(M)){u(!0);try{const Q=await O.tasks.review(l.id);$(Q),n({kind:"success",title:`已派 QA 重审 (round ${Q.reviewRound})`})}catch(Q){n({kind:"error",title:"Review 派发失败",body:Q instanceof Error?Q.message:String(Q)})}finally{u(!1)}}},F=async()=>{const I=l.status==="merged"?`task ${l.id} 已 merged。Retry 会用同样的标题/描述新建一个 task 从头跑,确定继续?`:`Retry task ${l.id}?这会新建一个 task 从头开始,旧 task 保留为历史。`;if(confirm(I)){p(!0);try{const M=await O.tasks.retry(l.id);n({kind:"success",title:`已新建 task ${M.id}`}),t(`/task/${M.id}`)}catch(M){n({kind:"error",title:"Retry 失败",body:M instanceof Error?M.message:String(M)})}finally{p(!1)}}};return e.jsxs("div",{className:"max-w-4xl mx-auto",children:[T&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",T]}),k&&e.jsx("div",{className:"mb-4 p-3 bg-amber-100 border-l-4 border-amber-500 text-amber-800 text-sm",children:l.status==="pending"?e.jsxs(e.Fragment,{children:["This task has no preferred dev (legacy). Click ",e.jsx("b",{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",{children:l.status}),")."]})}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 mb-2",children:[e.jsx("span",{className:"font-mono text-sm font-bold",children:l.id}),e.jsx("span",{className:`px-2 py-1 rounded text-xs font-medium ${Ht[l.status]}`,children:l.status}),l.phase==="spec"&&e.jsx("span",{className:"px-2 py-1 rounded text-xs font-medium bg-indigo-100 text-indigo-800",children:"spec phase"}),e.jsxs("span",{className:"text-xs text-gray-500",children:["created ",l.createdAt]}),e.jsxs("span",{className:"text-xs text-gray-500",children:["updated ",l.updatedAt]})]}),e.jsx("h1",{className:"text-xl sm:text-2xl font-bold mb-4 break-words",children:l.title}),P&&e.jsxs("div",{className:"mb-4 rounded border border-green-200 bg-green-50 p-4 text-sm text-green-900",children:[e.jsx("div",{className:"font-semibold",children:"QA approved · awaiting PR merge"}),e.jsx("div",{className:"mt-1",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:"mt-3 inline-flex rounded border border-green-300 bg-white px-3 py-1.5 text-sm font-medium text-green-800 hover:bg-green-100",children:["Open PR #",l.prNumber]})]}),e.jsx("pre",{className:"whitespace-pre-wrap font-sans bg-gray-50 border rounded p-4 mb-6 text-sm",children:l.description}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-2 text-sm mb-6",children:[e.jsxs("div",{children:["Project: ",e.jsx("span",{className:"font-mono",children:l.projectId})]}),e.jsxs("div",{children:["Dev: ",e.jsx("span",{className:"font-mono",children:l.agentId||"-"})]}),e.jsxs("div",{children:["Preferred: ",e.jsx("span",{className:"font-mono",children:l.preferredAgentId||"-"})]}),e.jsxs("div",{children:["QA: ",e.jsx("span",{className:"font-mono",children:l.qaAgentId||"-"})]}),e.jsxs("div",{children:["PR:"," ",l.prNumber?l.prUrl?e.jsxs("a",{href:l.prUrl,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:underline",children:["#",l.prNumber]}):e.jsxs("span",{children:["#",l.prNumber]}):e.jsx("span",{children:"-"})]}),e.jsxs("div",{children:["Branch: ",e.jsx("span",{className:"font-mono",children:l.branch||"-"})]}),e.jsxs("div",{children:["Round: ",l.reviewRound,l.specReviewRound!==void 0&&l.specReviewRound>0&&e.jsxs("span",{className:"ml-2 text-xs text-indigo-700",children:["spec: ",l.specReviewRound]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",disabled:!S,onClick:()=>r(!0),className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",children:"Edit"}),e.jsx("button",{type:"button",disabled:!A||i,onClick:N,className:"px-4 py-2 border border-red-300 text-red-700 rounded text-sm hover:bg-red-50 disabled:opacity-50 disabled:cursor-not-allowed",children:i?"Cancelling...":"Cancel"}),e.jsx("button",{type:"button",disabled:!g||m,onClick:F,title:Le.has(l.status)?k?"Legacy task has no preferred dev to retry against":"新建一个 task 从头跑,丢弃当前 worktree/branch":`Cannot retry in status ${l.status}`,className:"px-4 py-2 border border-blue-300 text-blue-700 rounded text-sm hover:bg-blue-50 disabled:opacity-50 disabled:cursor-not-allowed",children:m?"Retrying...":"Retry"}),e.jsx("button",{type:"button",disabled:!R||b,onClick:D,title:l.prNumber?"让 QA agent 立即开始新一轮 review(reviewRound +1)":"该 task 还没有 PR,无法派 review",className:"px-4 py-2 border border-purple-300 text-purple-700 rounded text-sm hover:bg-purple-50 disabled:opacity-50 disabled:cursor-not-allowed",children:b?"Dispatching...":"Request QA review"})]}),e.jsx(Ee,{mode:"edit",open:o,onClose:()=>r(!1),task:l,onUpdated:$})]})}function Vt(){const{phase:s,count:t,error:n,triggerRestart:o}=xe();return s==="idle"?null:s==="failed"?e.jsxs("div",{className:"bg-red-50 border-b border-red-200 px-4 py-2 flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm text-red-800",children:["❌ 重启失败:",n]}),e.jsx("button",{onClick:()=>{o()},className:"text-sm text-red-700 hover:underline font-medium",children:"重试"})]}):s==="restarting"?e.jsx("div",{className:"bg-blue-50 border-b border-blue-200 px-4 py-2 text-sm text-blue-800",children:"🔄 重启中…"}):e.jsxs("div",{className:"bg-amber-50 border-b border-amber-200 px-4 py-2 flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm text-amber-900",children:["⚠️ 有 ",t," 项配置变更待重启 baxian server 才生效"]}),e.jsx("button",{onClick:()=>{o()},className:"px-3 py-1 bg-amber-600 text-white text-sm rounded hover:bg-amber-700",children:"现在重启"})]})}function Kt(){return e.jsx(Xe,{children:e.jsxs("div",{className:"h-screen flex flex-col bg-gray-50",children:[e.jsxs("nav",{className:"bg-white border-b px-4 py-3 sm:px-6 flex flex-wrap items-center gap-x-4 gap-y-2 sm:gap-x-6 flex-none",children:[e.jsx(ee,{to:"/",className:"font-bold text-lg",children:"baxian"}),e.jsx(ee,{to:"/",className:"text-gray-600 hover:text-black",children:"Dashboard"}),e.jsx(ee,{to:"/tasks",className:"text-gray-600 hover:text-black",children:"Tasks"})]}),e.jsx(Vt,{}),e.jsx("main",{className:"flex-1 min-h-0 overflow-y-auto flex flex-col p-3 sm:p-6",children:e.jsxs(et,{children:[e.jsx(ae,{path:"/",element:e.jsx(Ut,{})}),e.jsx(ae,{path:"/project/:id",element:e.jsx(qt,{})}),e.jsx(ae,{path:"/terminal/:agentId",element:e.jsx(Wt,{})}),e.jsx(ae,{path:"/tasks",element:e.jsx(Gt,{})}),e.jsx(ae,{path:"/task/:id",element:e.jsx(Jt,{})})]})})]})})}function Yt({children:s}){const[t,n]=a.useState({kind:"probing"}),o=a.useRef(t);a.useEffect(()=>{o.current=t},[t]);const r=a.useCallback(async()=>{n({kind:"probing"});try{await O.config.get(),n({kind:"authorized"})}catch(i){if(i instanceof de&&i.status===401){n({kind:"unauthorized"});return}const c=i instanceof Error?i.message:"无法连接服务器";n({kind:"error",message:c})}},[]);return a.useEffect(()=>{r()},[r]),a.useEffect(()=>{const i=()=>{o.current.kind!=="probing"&&n({kind:"unauthorized",message:"登录已失效,请重新输入令牌"})};return window.addEventListener(ye,i),()=>window.removeEventListener(ye,i)},[]),t.kind==="authorized"?e.jsx(e.Fragment,{children:s}):t.kind==="error"?e.jsxs(we,{title:"无法连接服务器",children:[e.jsx("p",{className:"text-sm text-gray-600",children:t.message}),e.jsx("button",{type:"button",onClick:()=>{r()},className:"mt-4 w-full px-3 py-2 bg-blue-600 text-white text-sm font-medium rounded hover:bg-blue-700",children:"重试"})]}):t.kind==="probing"?e.jsx(we,{title:"加载中",children:e.jsx("p",{className:"text-sm text-gray-500",children:"正在检查登录状态…"})}):e.jsx(Zt,{message:t.message,onSubmit:async i=>{tt(i);try{await O.config.get(),n({kind:"authorized"})}catch(c){if(st(),c instanceof de&&c.status===401){n({kind:"unauthorized",message:"令牌无效,请重试"});return}const m=c instanceof Error?c.message:"登录失败";n({kind:"error",message:m})}}})}function we({title:s,children:t}){return e.jsx("div",{className:"min-h-screen flex items-center justify-center bg-gray-50 px-4",children:e.jsxs("div",{className:"w-full max-w-sm bg-white border rounded-lg shadow-sm px-6 py-6",children:[e.jsx("h1",{className:"text-lg font-semibold mb-3",children:s}),t]})})}function Zt({message:s,onSubmit:t}){const[n,o]=a.useState(""),[r,i]=a.useState(!1),[c,m]=a.useState(void 0),p=async u=>{u.preventDefault();const h=n.trim();if(!h){m("请输入访问令牌");return}m(void 0),i(!0);try{await t(h)}finally{i(!1)}},b=c??s;return e.jsxs(we,{title:"登录 baxian",children:[e.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"服务器开启了访问鉴权,请输入访问令牌继续。"}),e.jsxs("form",{onSubmit:u=>{p(u)},children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-1",htmlFor:"baxian-token",children:"访问令牌"}),e.jsx("input",{id:"baxian-token",type:"password",autoComplete:"current-password",autoFocus:!0,value:n,onChange:u=>o(u.target.value),className:"w-full px-3 py-2 border rounded text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"请输入服务器配置的 token",disabled:r}),b&&e.jsx("p",{role:"alert",className:"mt-2 text-sm text-red-600",children:b}),e.jsx("button",{type:"submit",disabled:r,className:"mt-4 w-full px-3 py-2 bg-blue-600 text-white text-sm font-medium rounded hover:bg-blue-700 disabled:opacity-60 disabled:cursor-not-allowed",children:r?"登录中…":"登录"})]})]})}Ke.createRoot(document.getElementById("root")).render(e.jsx(a.StrictMode,{children:e.jsx(mt,{children:e.jsx(lt,{children:e.jsx(Yt,{children:e.jsx(Kt,{})})})})}));
@@ -1 +0,0 @@
1
- *,: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:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";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}.\!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}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.fixed{position:fixed}.inset-0{top:0;right:0;bottom:0;left:0}.right-4{right:1rem}.top-4{top:1rem}.z-50{z-index:50}.z-\[60\]{z-index:60}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.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-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-2{height:.5rem}.h-8{height:2rem}.h-80{height:20rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-28{max-height:7rem}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0px}.min-h-screen{min-height:100vh}.w-2{width:.5rem}.w-80{width:20rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-none{flex:none}.shrink-0{flex-shrink:0}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.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))}.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{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-500{--tw-border-opacity: 1;border-color:rgb(245 158 11 / var(--tw-border-opacity, 1))}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-blue-300{--tw-border-opacity: 1;border-color:rgb(147 197 253 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-green-300{--tw-border-opacity: 1;border-color:rgb(134 239 172 / var(--tw-border-opacity, 1))}.border-purple-300{--tw-border-opacity: 1;border-color:rgb(216 180 254 / var(--tw-border-opacity, 1))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-red-300{--tw-border-opacity: 1;border-color:rgb(252 165 165 / var(--tw-border-opacity, 1))}.border-red-900\/60{border-color:#7f1d1d99}.border-sky-200{--tw-border-opacity: 1;border-color:rgb(186 230 253 / var(--tw-border-opacity, 1))}.border-zinc-800{--tw-border-opacity: 1;border-color:rgb(39 39 42 / var(--tw-border-opacity, 1))}.bg-\[\#e1e2e7\]{--tw-bg-opacity: 1;background-color:rgb(225 226 231 / var(--tw-bg-opacity, 1))}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-200{--tw-bg-opacity: 1;background-color:rgb(253 230 138 / var(--tw-bg-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.bg-black\/40{background-color:#0006}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-200{--tw-bg-opacity: 1;background-color:rgb(191 219 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-emerald-100{--tw-bg-opacity: 1;background-color:rgb(209 250 229 / var(--tw-bg-opacity, 1))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-400{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-300{--tw-bg-opacity: 1;background-color:rgb(134 239 172 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-indigo-100{--tw-bg-opacity: 1;background-color:rgb(224 231 255 / var(--tw-bg-opacity, 1))}.bg-orange-100{--tw-bg-opacity: 1;background-color:rgb(255 237 213 / var(--tw-bg-opacity, 1))}.bg-orange-200{--tw-bg-opacity: 1;background-color:rgb(254 215 170 / var(--tw-bg-opacity, 1))}.bg-purple-200{--tw-bg-opacity: 1;background-color:rgb(233 213 255 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-200{--tw-bg-opacity: 1;background-color:rgb(254 202 202 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-950\/40{background-color:#450a0a66}.bg-sky-100{--tw-bg-opacity: 1;background-color:rgb(224 242 254 / var(--tw-bg-opacity, 1))}.bg-sky-50{--tw-bg-opacity: 1;background-color:rgb(240 249 255 / var(--tw-bg-opacity, 1))}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-zinc-900{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.p-3{padding:.75rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.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-0\.5{padding-top:.125rem;padding-bottom:.125rem}.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-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pr-4{padding-right:1rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.text-\[11px\]{font-size:11px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.italic{font-style:italic}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-current{color:currentColor}.text-emerald-800{--tw-text-opacity: 1;color:rgb(6 95 70 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-green-900{--tw-text-opacity: 1;color:rgb(20 83 45 / var(--tw-text-opacity, 1))}.text-indigo-700{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.text-indigo-800{--tw-text-opacity: 1;color:rgb(55 48 163 / var(--tw-text-opacity, 1))}.text-orange-800{--tw-text-opacity: 1;color:rgb(154 52 18 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-purple-800{--tw-text-opacity: 1;color:rgb(107 33 168 / var(--tw-text-opacity, 1))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-red-800{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.text-red-900{--tw-text-opacity: 1;color:rgb(127 29 29 / var(--tw-text-opacity, 1))}.text-sky-800{--tw-text-opacity: 1;color:rgb(7 89 133 / var(--tw-text-opacity, 1))}.text-sky-900{--tw-text-opacity: 1;color:rgb(12 74 110 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-zinc-200{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.opacity-50{opacity:.5}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px 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-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 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-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px 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)}.hover\:bg-amber-700:hover{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-50:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-green-100:hover{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.hover\:bg-purple-50:hover{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.hover\:bg-red-100:hover{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:text-black:hover{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2: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(2px + 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-blue-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-300:disabled{--tw-bg-opacity: 1;background-color:rgb(209 213 219 / var(--tw-bg-opacity, 1))}.disabled\:bg-gray-50:disabled{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.disabled\:no-underline:disabled{text-decoration-line:none}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media(min-width:640px){.sm\:table-cell{display:table-cell}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.sm\:p-6{padding:1.5rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-2xl{font-size:1.5rem;line-height:2rem}}@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))}}