baxian 1.2.43 → 1.2.44

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;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%}.\!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:4px;--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1));padding:.375rem .75rem;font-size:14px;line-height:1.55;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:4px;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:14px;line-height:1.55;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:4px;background-color:transparent;padding:.375rem .75rem;font-size:14px;line-height:1.55;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:12px;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(22 101 52 / var(--tw-text-opacity, 1))}.pill-live:before{--tw-bg-opacity: 1;background-color:rgb(22 101 52 / 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-danger{--tw-bg-opacity: 1;background-color:rgb(253 236 234 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.pill-danger:before{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / 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))}.pill-idle{--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(109 116 132 / var(--tw-text-opacity, 1))}.pill-idle:before{--tw-bg-opacity: 1;background-color:rgb(192 195 202 / var(--tw-bg-opacity, 1))}.card{border-radius:6px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(232 233 236 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.card:hover{--tw-border-opacity: 1;border-color:rgb(206 209 214 / var(--tw-border-opacity, 1))}.status-dot{display:inline-block;height:.725rem;width:.725rem;flex-shrink:0;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1))}.status-dot--warn{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1));animation:breathe 1.8s ease-in-out 2}.status-dot--danger{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1));animation:breathe 1.8s ease-in-out 2}.status-dot--info{--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1));animation:breathe 1.8s ease-in-out 2}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.inset-x-4{left:1rem;right:1rem}.-top-4{top:-1rem}.bottom-full{bottom:100%}.right-0{right:0}.right-7{right:1.75rem}.top-4{top:1rem}.top-full{top:100%}.z-10{z-index:10}.z-50{z-index:50}.z-\[60\]{z-index:60}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.-mr-1{margin-right:-.25rem}.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-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-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-auto{margin-top:auto}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-12{height:3rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3\.5{height:.875rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-80{height:20rem}.h-dvh{height:100dvh}.h-full{height:100%}.max-h-28{max-height:7rem}.max-h-\[90dvh\]{max-height:90dvh}.min-h-0{min-height:0px}.min-h-dvh{min-height:100dvh}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-3\.5{width:.875rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-auto{width:auto}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[1\.75rem\]{min-width:1.75rem}.min-w-\[140px\]{min-width:140px}.min-w-\[180px\]{min-width:180px}.min-w-\[60px\]{min-width:60px}.max-w-2xl{max-width:42rem}.max-w-5xl{max-width:64rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xs{max-width:20rem}.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))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[1fr_auto_1fr\]{grid-template-columns:1fr auto 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-6{gap:1.5rem}.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}.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-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * 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))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * 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))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.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{white-space:pre}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:4px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:6px}.rounded-md{border-radius:4px}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-accent{--tw-border-opacity: 1;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1))}.border-accent-soft{--tw-border-opacity: 1;border-color:rgb(234 240 255 / var(--tw-border-opacity, 1))}.border-accent\/25{border-color:#1348dc40}.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-accent{--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1))}.bg-accent-soft{--tw-bg-opacity: 1;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1))}.bg-accent-soft\/30{background-color:#eaf0ff4d}.bg-accent-soft\/40{background-color:#eaf0ff66}.bg-accent-soft\/60{background-color:#eaf0ff99}.bg-danger{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.bg-diff-add{--tw-bg-opacity: 1;background-color:rgb(230 244 236 / var(--tw-bg-opacity, 1))}.bg-diff-del{--tw-bg-opacity: 1;background-color:rgb(253 236 234 / var(--tw-bg-opacity, 1))}.bg-og-1000{--tw-bg-opacity: 1;background-color:rgb(13 13 15 / var(--tw-bg-opacity, 1))}.bg-og-1000\/45{background-color:#0d0d0f73}.bg-og-25{--tw-bg-opacity: 1;background-color:rgb(241 242 244 / var(--tw-bg-opacity, 1))}.bg-og-300{--tw-bg-opacity: 1;background-color:rgb(171 175 184 / var(--tw-bg-opacity, 1))}.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(22 101 52 / var(--tw-bg-opacity, 1))}.bg-surface{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-term{--tw-bg-opacity: 1;background-color:rgb(253 253 253 / var(--tw-bg-opacity, 1))}.bg-warn{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.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-5{padding-left:1.25rem;padding-right:1.25rem}.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-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pr-28{padding-right:7rem}.pt-1{padding-top:.25rem}.pt-24{padding-top:6rem}.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-sm{font-size:14px;line-height:1.55}.text-xs{font-size:12px;line-height:1.4}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.normal-case{text-transform:none}.leading-\[1\.5\]{line-height:1.5}.leading-none{line-height:1}.tracking-\[0\.05em\]{letter-spacing:.05em}.tracking-\[0\.06em\]{letter-spacing:.06em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-accent{--tw-text-opacity: 1;color:rgb(19 72 220 / var(--tw-text-opacity, 1))}.text-current{color:currentColor}.text-diff-add-ink{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-diff-del-ink{--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-300{--tw-text-opacity: 1;color:rgb(171 175 184 / 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-probe-ok{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.accent-accent{accent-color:#1348dc}.opacity-50{opacity:.5}.opacity-80{opacity:.8}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px 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-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)}.ring-2{--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)}.ring-accent{--tw-ring-opacity: 1;--tw-ring-color: rgb(19 72 220 / var(--tw-ring-opacity, 1))}.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}.scrollbar-none{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-none::-webkit-scrollbar{display:none}.\[max-height\:70vh\]{max-height:70vh}@media(pointer:coarse){input:not([type=checkbox]):not([type=radio]):not([type=button]):not([type=submit]):not([type=file]),select,textarea{font-size:16px!important}}@keyframes breathe{0%,to{opacity:1}50%{opacity:.35}}.placeholder\:text-og-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.placeholder\:text-og-400::placeholder{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.hover\: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-accent-hover:hover{--tw-text-opacity: 1;color:rgb(15 59 184 / var(--tw-text-opacity, 1))}.hover\:text-og-1000:hover{--tw-text-opacity: 1;color:rgb(13 13 15 / 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\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-80:hover{opacity:.8}.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))}.active\:bg-og-200:active{--tw-bg-opacity: 1;background-color:rgb(192 195 202 / var(--tw-bg-opacity, 1))}.disabled\:cursor-default:disabled{cursor:default}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:640px){.sm\:inline-block{display:inline-block}.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media(min-width:1024px){.lg\:w-\[340px\]{width:340px}.lg\:shrink-0{flex-shrink:0}.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))}.lg\:flex-row{flex-direction:row}.lg\:items-start{align-items:flex-start}}@media(min-width:1280px){.xl\:w-\[380px\]{width:380px}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
@@ -1,9 +1,9 @@
1
- var Ks=Object.defineProperty;var Vs=(e,s,n)=>s in e?Ks(e,s,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[s]=n;var te=(e,s,n)=>Vs(e,typeof s!="symbol"?s+"":s,n);import{r as a,j as t,a as Js,c as Ys}from"./react-BFCkCmbU.js";import{x as Xs,a as Zs}from"./xterm-D5X2JljJ.js";import{L as Be,u as pe,a as He,b as ms,B as en,R as tn,c as $e}from"./router-BgSDZqI0.js";(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))i(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const l of o.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&i(l)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function i(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();function he({className:e,...s}){return t.jsx("button",{type:"button",role:"menuitem",className:`block w-full px-3 py-1.5 text-left text-sm text-og-1000 hover:bg-og-50 disabled:opacity-50 disabled:cursor-not-allowed ${e??""}`,...s})}function St({ariaLabel:e,children:s,placement:n="down",autoFocusFirstItem:i=!1,menuClassName:r="min-w-[140px]",className:o,disabled:l=!1,triggerRef:u}){const[m,h]=a.useState(!1),v=a.useRef(null),d=a.useRef(null),f=a.useId(),p=a.useId();return a.useEffect(()=>{if(!m)return;const x=j=>{var R,E;const k=j.target;k&&((R=d.current)!=null&&R.contains(k)||(E=v.current)!=null&&E.contains(k)||h(!1))},N=j=>{var k;j.key==="Escape"&&(h(!1),(k=v.current)==null||k.focus())};return document.addEventListener("mousedown",x),document.addEventListener("keydown",N),()=>{document.removeEventListener("mousedown",x),document.removeEventListener("keydown",N)}},[m]),a.useEffect(()=>{var N;if(!m||!i)return;const x=(N=d.current)==null?void 0:N.querySelector('[role="menuitem"]:not([disabled])');x==null||x.focus()},[m,i]),t.jsxs("div",{className:`relative ${o??""}`,children:[t.jsx("button",{ref:x=>{v.current=x,u&&(u.current=x)},id:p,type:"button",onClick:()=>h(x=>!x),disabled:l,"aria-haspopup":"menu","aria-expanded":m,"aria-controls":m?f:void 0,"aria-label":e,className:"flex h-8 w-8 items-center justify-center rounded text-og-500 transition-colors hover:bg-og-50 hover:text-og-1000 disabled:cursor-not-allowed disabled:opacity-50",children:t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[t.jsx("circle",{cx:"12",cy:"12",r:"1"}),t.jsx("circle",{cx:"12",cy:"5",r:"1"}),t.jsx("circle",{cx:"12",cy:"19",r:"1"})]})}),m&&t.jsx("div",{ref:d,id:f,role:"menu","aria-labelledby":p,className:`absolute right-0 z-10 rounded-md border border-hairline bg-surface py-1 shadow-md ${n==="up"?"bottom-full mb-1":"top-full mt-1"} ${r}`,children:s(()=>{var x;h(!1),(x=v.current)==null||x.focus()})})]})}const sn={"claude-code":"Claude Code",codex:"Codex"};function fs(e){return e?sn[e]:null}function hs(e,s){const n=fs(s);return n?`${e} (${n})`:e}const xs=new Set(["merged","done","failed","cancelled"]),ps=new Set(["in_progress","review","fixing","spec-ready","approved","merge-ready","ready","max_rounds"]),at=20,nt=5*1024*1024,qe=4,gs=600*1e3,nn=1536,rn=1872,bs=192,vs=208,De="/api",kt="baxian.token",Je="baxian:unauthorized";function Et(){try{return typeof localStorage<"u"?localStorage.getItem(kt):null}catch{return null}}function an(e){try{localStorage.setItem(kt,e)}catch(s){console.error("Failed to save auth token to localStorage",s)}}function on(){try{localStorage.removeItem(kt)}catch(e){console.error("Failed to clear auth token from localStorage",e)}}function Ee(e){const s=Et();return{...e??{},...s?{Authorization:`Bearer ${s}`}:{}}}class Pe extends Error{constructor(s,n,i){super(n),this.status=s,this.details=i,this.name="ApiError"}}async function Re(e){const s=await e.text();let n=s||`HTTP ${e.status}`,i;try{const r=JSON.parse(s);typeof r.error=="string"&&(n=r.error),Array.isArray(r.details)&&(i=r.details)}catch{}throw e.status===401&&typeof window<"u"&&window.dispatchEvent(new CustomEvent(Je)),new Pe(e.status,n,i)}async function xe(e){const s=await fetch(`${De}${e}`,{headers:Ee()});return s.ok||await Re(s),s.json()}async function cn(){const e=await fetch("/health");return e.ok||await Re(e),e.json()}async function ne(e,s,n){const i=s!==void 0,r=await fetch(`${De}${e}`,{method:"POST",headers:i?Ee({"Content-Type":"application/json"}):Ee(),body:i?JSON.stringify(s):void 0,signal:n==null?void 0:n.signal});return r.ok||await Re(r),r.json()}async function Ht(e,s,n){const i=await fetch(`${De}${e}`,{method:"PATCH",headers:Ee({"Content-Type":"application/json"}),body:s?JSON.stringify(s):void 0,signal:n==null?void 0:n.signal});if(i.ok||await Re(i),i.status===204)return;const r=await i.text();if(r)return JSON.parse(r)}async function ln(e,s){const n=await fetch(`${De}${e}`,{method:"PUT",headers:Ee({"Content-Type":"application/json"}),body:JSON.stringify(s??null)});if(n.ok||await Re(n),n.status===204)return;const i=await n.text();if(i)return JSON.parse(i)}async function Le(e){const s=await fetch(`${De}${e}`,{method:"DELETE",headers:Ee()});if(s.ok||await Re(s),s.status===204)return;const n=await s.text();if(n)return JSON.parse(n)}const W=encodeURIComponent;function bt(e){return new Promise((s,n)=>{const i=new FileReader;i.onerror=()=>n(i.error??new Error("file read failed")),i.onload=()=>{const r=i.result;if(typeof r!="string"){n(new Error("unexpected FileReader result"));return}const o=r.indexOf(",");s(o>=0?r.slice(o+1):r)},i.readAsDataURL(e)})}const I={agents:{list:()=>xe("/agents"),get:e=>xe(`/agents/${W(e)}`),stop:e=>Le(`/agents/${W(e)}/session`),compact:e=>ne(`/agents/${W(e)}/compact`),clear:e=>ne(`/agents/${W(e)}/clear`),probe:(e,s={},n)=>ne("/agents/probe",{mode:e,host:s.host,hostId:s.hostId},n),installTmux:(e,s={})=>ne("/agents/install-tmux",{mode:e,host:s.host,hostId:s.hostId}),uploadImage:async(e,s)=>ne(`/agents/${W(e)}/images`,{dataBase64:await bt(s)}),setPet:(e,s)=>ln(`/agents/${W(e)}/pet`,{petId:s})},pets:{list:()=>xe("/pets"),create:async(e,s)=>ne("/pets",{petJson:e,spritesheetBase64:await bt(s)}),remove:e=>Le(`/pets/${W(e)}`),fetchSpritesheet:async e=>{const s=await fetch(`${De}/pets/${W(e)}/spritesheet`,{headers:Ee()});return s.ok||await Re(s),s.blob()}},tasks:{list:async e=>{const s=new Map;for(const n of["active","pending"]){let i=0;for(;;){const r=await I.tasks.page(e,{category:n,offset:i});for(const o of r.tasks)s.set(o.id,o);if(!r.hasMore||r.tasks.length===0)break;i=r.nextOffset}}return[...s.values()]},page:(e,s={})=>{const n=[`projectId=${W(e)}`];return s.category&&n.push(`category=${s.category}`),n.push(`offset=${s.offset??0}`),xe(`/tasks?${n.join("&")}`)},get:e=>xe(`/tasks/${W(e)}`),create:e=>ne("/tasks",e),update:(e,s)=>Ht(`/tasks/${W(e)}`,s),retry:e=>ne(`/tasks/${W(e)}/retry`),review:e=>ne(`/tasks/${W(e)}/review`),complete:e=>ne(`/tasks/${W(e)}/complete`),continue:e=>ne(`/tasks/${W(e)}/continue`),spec:(e,s)=>ne(`/tasks/${W(e)}/spec`,s),reviews:e=>xe(`/tasks/${W(e)}/reviews`),githubReview:e=>xe(`/tasks/${W(e)}/github-review`),dispatch:(e,s)=>ne(`/tasks/${W(e)}/dispatch`,s)},projects:{list:()=>xe("/projects"),get:e=>xe(`/projects/${W(e)}`),create:e=>ne("/projects",e),delete:e=>Le(`/projects/${W(e)}`),addAgent:(e,s)=>ne(`/projects/${W(e)}/agents`,s),deleteAgent:(e,s)=>Le(`/projects/${W(e)}/agents/${W(s)}`),resumeAgent:(e,s)=>ne(`/projects/${W(e)}/agents/${W(s)}/resume`),restartRepl:(e,s)=>ne(`/projects/${W(e)}/agents/${W(s)}/restart-repl`),retryAgent:(e,s)=>ne(`/projects/${W(e)}/agents/${W(s)}/retry`),bootstrap:e=>ne(`/projects/${W(e)}/bootstrap`)},hosts:{list:()=>xe("/hosts"),create:e=>ne("/hosts",e),update:(e,s)=>Ht(`/hosts/${W(e)}`,s),delete:e=>Le(`/hosts/${W(e)}`),check:e=>ne("/hosts/check",e)},config:{get:()=>xe("/config")},health:{get:cn},server:{restart:()=>ne("/restart")}};function Rt(e){return{xmlns:"http://www.w3.org/2000/svg",width:16,height:16,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,...e}}function dn(e){return t.jsxs("svg",{...Rt(e),children:[t.jsx("path",{d:"M21.801 10A10 10 0 1 1 17 3.335"}),t.jsx("path",{d:"m9 11 3 3L22 4"})]})}function un(e){return t.jsxs("svg",{...Rt(e),children:[t.jsx("path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"}),t.jsx("path",{d:"M12 9v4"}),t.jsx("path",{d:"M12 17h.01"})]})}function mn(e){return t.jsxs("svg",{...Rt(e),children:[t.jsx("circle",{cx:"12",cy:"12",r:"10"}),t.jsx("path",{d:"m15 9-6 6"}),t.jsx("path",{d:"m9 9 6 6"})]})}const js=a.createContext(null),fn={success:"border-hairline bg-surface text-og-800",warn:"border-accent/25 bg-accent-soft text-accent",error:"border-accent/25 bg-accent-soft text-accent"},hn={success:dn,warn:un,error:mn};let xn=1;function pn({children:e}){const[s,n]=a.useState([]),i=a.useRef(new Map),r=a.useRef(new Map);a.useEffect(()=>{const d=i.current,f=r.current;return()=>{for(const p of d.values())clearTimeout(p);d.clear(),f.clear()}},[]);const o=a.useCallback(d=>{const f=i.current.get(d);f&&clearTimeout(f),i.current.delete(d)},[]),l=a.useCallback(d=>{o(d),r.current.delete(d),n(f=>f.filter(p=>p.id!==d))},[o]),u=a.useCallback((d,f)=>{o(d),i.current.set(d,setTimeout(()=>l(d),f))},[o,l]),m=a.useCallback((d,f)=>{const p=r.current.get(d)??new Set;p.add(f),r.current.set(d,p),o(d)},[o]),h=a.useCallback((d,f,p)=>{const x=r.current.get(d);x==null||x.delete(f),(!x||x.size===0)&&u(d,p)},[u]),v=a.useCallback(d=>{const f=xn++,p=d.durationMs??3e3;n(x=>[...x,{...d,id:f,durationMs:p}]),u(f,p)},[u]);return t.jsxs(js.Provider,{value:{show:v},children:[e,t.jsx("div",{className:"pointer-events-none fixed inset-x-4 top-4 z-[60] flex flex-col items-end gap-2",children:s.map(d=>t.jsx("div",{className:`pointer-events-auto w-full max-w-xs rounded-lg border px-4 py-3 shadow-toast ${fn[d.kind]}`,role:"status",onMouseEnter:()=>m(d.id,"hover"),onMouseLeave:()=>h(d.id,"hover",d.durationMs),onFocus:()=>m(d.id,"focus"),onBlur:f=>{f.currentTarget.contains(f.relatedTarget)||h(d.id,"focus",d.durationMs)},children:t.jsxs("div",{className:"flex items-start gap-2",children:[(()=>{const f=hn[d.kind];return t.jsx(f,{className:"mt-0.5 shrink-0",width:14,height:14})})(),t.jsxs("div",{className:"flex-1",children:[t.jsx("div",{className:"text-sm font-semibold",children:d.title}),d.body&&t.jsx("div",{className:"mt-1 whitespace-pre-line text-xs text-og-700",children:d.body})]}),t.jsx("button",{type:"button",onClick:()=>l(d.id),className:"text-current opacity-50 transition-opacity hover:opacity-100","aria-label":"关闭通知",children:"✕"})]})},d.id))})]})}function ve(){const e=a.useContext(js);if(!e)throw new Error("useToast must be inside <ToastProvider>");return e}const gn={sm:"max-w-md",md:"max-w-lg",lg:"max-w-2xl"},Ut='input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])',ke=[];function Ne({open:e,onClose:s,title:n,titleContent:i,children:r,footer:o,size:l="md",dismissOnBackdrop:u=!0}){const m=a.useRef(null),h=a.useRef();h.current||(h.current=Symbol("modal"));const v=a.useRef(null),d=a.useRef(!1),f=a.useRef(s);return a.useEffect(()=>{f.current=s},[s]),a.useEffect(()=>{if(!e)return;const p=h.current;ke.push(p);const x=()=>ke[ke.length-1]===p;v.current=document.activeElement;const N=R=>{if(!x())return;if(R.key==="Escape"){f.current();return}if(R.key!=="Tab")return;const E=m.current;if(!E)return;const b=Array.from(E.querySelectorAll(Ut)).filter(L=>L.offsetParent!==null||L===document.activeElement);if(b.length===0){R.preventDefault();return}const y=b[0],w=b[b.length-1],_=document.activeElement;R.shiftKey&&(_===y||!E.contains(_))?(R.preventDefault(),w.focus()):!R.shiftKey&&(_===w||!E.contains(_))&&(R.preventDefault(),y.focus())};document.addEventListener("keydown",N);const j=document.body.style.overflow;document.body.style.overflow="hidden";const k=m.current;if(k){const R=k.querySelector(Ut);R==null||R.focus()}return()=>{var E,b;const R=ke.indexOf(p);R>=0&&ke.splice(R,1),document.removeEventListener("keydown",N),document.body.style.overflow=j,(b=(E=v.current)==null?void 0:E.focus)==null||b.call(E)}},[e]),e?t.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-og-1000/45 px-3 sm:px-4",onMouseDown:u?p=>{d.current=p.target===p.currentTarget&&ke[ke.length-1]===h.current}:void 0,onClick:u?p=>{p.target===p.currentTarget&&d.current&&f.current()}:void 0,role:"presentation",children:t.jsxs("div",{ref:m,className:`flex w-full ${gn[l]} max-h-[90dvh] flex-col overflow-hidden rounded-lg border border-og-100 bg-surface shadow-modal`,onClick:p=>p.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":n,children:[t.jsxs("div",{className:"flex shrink-0 items-center justify-between gap-3 border-b border-hairline px-5 py-3",children:[t.jsx("h2",{title:n,className:"min-w-0 truncate font-display text-sm font-semibold tracking-tight text-og-1000",children:i??n}),t.jsx("button",{type:"button",onClick:()=>f.current(),className:"-mr-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-og-400 transition-colors hover:bg-og-50 hover:text-og-800","aria-label":"关闭",children:"✕"})]}),t.jsx("div",{className:"min-h-0 flex-1 overflow-auto px-5 py-4",children:r}),o&&t.jsx("div",{className:"flex shrink-0 flex-wrap items-center justify-end gap-2 border-t border-hairline px-5 py-3",children:o})]})}):null}const ws=a.createContext(null);function bn({children:e}){const[s,n]=a.useState(null),i=a.useRef(null),r=a.useCallback(l=>new Promise(u=>{var h;(h=i.current)==null||h.resolve(!1);const m={...l,resolve:u};i.current=m,n(m)}),[]),o=a.useCallback(l=>{const u=i.current;u&&(i.current=null,n(null),u.resolve(l))},[]);return t.jsxs(ws.Provider,{value:r,children:[e,s&&t.jsx(Ne,{open:!0,title:s.title,onClose:()=>o(!1),size:"sm",footer:t.jsxs("div",{className:"flex justify-end gap-2",children:[t.jsx("button",{type:"button",onClick:()=>o(!1),className:"btn-secondary",children:s.cancelLabel??"取消"}),t.jsx("button",{type:"button",onClick:()=>o(!0),className:"btn-primary",children:s.confirmLabel??"确认"})]}),children:s.body?t.jsx("p",{className:"whitespace-pre-line text-sm text-og-700",children:s.body}):null})]})}function Ct(){const e=a.useContext(ws);if(!e)throw new Error("useConfirm must be inside <ConfirmProvider>");return e}const Ye="baxian.pendingRestart",vn=500,jn=3e4,ys=a.createContext(null);function wn(){try{const e=localStorage.getItem(Ye);if(!e)return{count:0,baselineStartedAt:null};const s=JSON.parse(e);return{count:typeof s.count=="number"?s.count:0,baselineStartedAt:typeof s.baselineStartedAt=="string"?s.baselineStartedAt:null}}catch{return{count:0,baselineStartedAt:null}}}function yn(e){try{e.count<=0?localStorage.removeItem(Ye):localStorage.setItem(Ye,JSON.stringify(e))}catch{}}function Nn({children:e}){const s=wn(),[n,i]=a.useState(s.count),[r,o]=a.useState(s.baselineStartedAt),[l,u]=a.useState(s.count>0?"pending":"idle"),[m,h]=a.useState(),v=a.useRef(s.count),d=a.useRef(s.count>0?"pending":"idle"),f=a.useRef(0),p=a.useCallback(E=>{v.current=E,i(E)},[]),x=a.useCallback(E=>{i(b=>{const y=E(b);return v.current=y,y})},[]),N=a.useCallback(E=>{d.current=E,u(E)},[]);a.useEffect(()=>{yn({count:n,baselineStartedAt:r})},[n,r]),a.useEffect(()=>{let E=!1;(async()=>{try{const y=await I.health.get();if(E)return;o(w=>w!==null&&y.startedAt!==w?(p(0),N("idle"),null):w)}catch{}})();const b=y=>{if(y.key===Ye){if(y.newValue===null){if(d.current==="restarting"&&f.current>0){p(f.current),o(null);return}p(0),o(null),d.current!=="restarting"&&N("idle");return}try{const w=JSON.parse(y.newValue);typeof w.count=="number"&&(d.current==="restarting"&&w.count>v.current&&(f.current+=w.count-v.current),p(w.count),d.current!=="restarting"&&N(w.count>0?"pending":"idle")),typeof w.baselineStartedAt=="string"?o(w.baselineStartedAt):w.baselineStartedAt===null&&o(null)}catch{}}};return window.addEventListener("storage",b),()=>{E=!0,window.removeEventListener("storage",b)}},[p,N]);const j=a.useRef(!1),k=a.useCallback(()=>{x(E=>E+1),d.current==="restarting"?f.current+=1:N("pending"),o(E=>(E!==null||j.current||(j.current=!0,(async()=>{try{const b=await I.health.get();o(y=>y??b.startedAt)}catch{}finally{j.current=!1}})()),E))},[N,x]),R=a.useCallback(async()=>{f.current=0,h(void 0),N("restarting");let E;try{E=(await I.health.get()).startedAt}catch(y){N("failed"),h(`获取重启前 startedAt 失败: ${y instanceof Error?y.message:String(y)}`);return}try{await I.server.restart()}catch(y){if(!(y instanceof Pe&&y.status===409)){N("failed"),h(`触发重启失败: ${y instanceof Error?y.message:String(y)}`);return}}const b=Date.now();for(;Date.now()-b<jn;){await new Promise(y=>setTimeout(y,vn));try{const y=await I.health.get();if(y.startedAt!==E){const w=f.current;f.current=0,o(w>0?y.startedAt:null),p(w),N(w>0?"pending":"idle");return}}catch{}}N("failed"),h("重启超时(30s 未恢复)。请检查日志或手动 baxian start -c <path>")},[p,N]);return t.jsx(ys.Provider,{value:{phase:l,count:n,error:m,flagDirty:k,triggerRestart:R},children:e})}function rt(){const e=a.useContext(ys);if(!e)throw new Error("usePendingRestart must be used inside PendingRestartProvider");return e}const Sn=[500,1e3,2e3,4e3,8e3,15e3,3e4];class Ns{constructor(s){te(this,"attempts",0);te(this,"timer",null);te(this,"delaysMs");this.opts=s,this.delaysMs=s.delaysMs??Sn}schedule(){if(this.timer||!this.shouldReconnect())return;const s=this.delaysMs[Math.min(this.attempts,this.delaysMs.length-1)];this.attempts+=1,this.timer=setTimeout(()=>{this.timer=null,this.shouldReconnect()&&this.opts.reconnect()},s)}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null)}reset(){this.attempts=0}shouldReconnect(){return this.opts.shouldReconnect?this.opts.shouldReconnect():!0}}let qt=0;function kn(){qt++;const e=Math.random().toString(36).slice(2,8);return`sub-${Date.now().toString(36)}-${qt}-${e}`}function En(e){return Array.from(new TextEncoder().encode(e)).map(s=>s.toString(16).padStart(2,"0")).join("")}function Rn(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/stream`}const Cn=(e,s)=>s&&s.length>0?new WebSocket(e,s):new WebSocket(e);class An{constructor(s={}){te(this,"wsUrl");te(this,"wsFactory");te(this,"tokenProvider");te(this,"ws",null);te(this,"subs",new Map);te(this,"snapshotPending",new Set);te(this,"preSubscribeQueue",new Map);te(this,"outbox",[]);te(this,"reconnectScheduler");te(this,"explicitlyClosed",!1);this.wsUrl=s.wsUrl??Rn(),this.wsFactory=s.wsFactory??Cn,this.tokenProvider=s.tokenProvider??Et,this.reconnectScheduler=new Ns({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.subs.size>0})}subscribe(s){const n=kn(),i={subscriberId:n,agentId:s.agentId,mode:s.mode,onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone};return this.subs.set(n,i),this.snapshotPending.add(n),this.preSubscribeQueue.set(n,[]),this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",subscriberId:n,agentId:s.agentId,mode:s.mode}),{subscriberId:n,unsubscribe:()=>this.unsubscribe(n)}}send(s,n){if(this.subs.has(s)){if(this.snapshotPending.has(s)){this.outbox.push({op:"input",subscriberId:s,data:n});return}this.wsSendOrQueue({op:"input",subscriberId:s,data:n})}}resize(s,n,i){const r=this.subs.get(s);r&&(r.lastSize={cols:n,rows:i},!this.snapshotPending.has(s)&&this.wsSendOrQueue({op:"resize",subscriberId:s,cols:n,rows:i}))}ping(){this.wsSendOrQueue({op:"ping"})}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.subs.clear(),this.snapshotPending.clear(),this.preSubscribeQueue.clear(),this.outbox=[]}unsubscribe(s){this.subs.has(s)&&(this.subs.delete(s),this.snapshotPending.delete(s),this.preSubscribeQueue.delete(s),this.wsSendOrQueue({op:"unsubscribe",subscriberId:s}),this.subs.size===0&&this.teardownSocket())}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const s=this.tokenProvider(),n=s?[`baxian.token.${En(s)}`]:void 0;let i;try{i=this.wsFactory(this.wsUrl,n)}catch(r){console.warn("[pane-stream] WebSocket constructor threw:",r),this.scheduleReconnect();return}this.ws=i,i.onopen=()=>{if(i!==this.ws)return;this.reconnectScheduler.reset();for(const o of this.subs.values()){this.snapshotPending.add(o.subscriberId),this.preSubscribeQueue.set(o.subscriberId,[]),o.snapshotSeq=void 0;try{i.send(JSON.stringify({op:"subscribe",subscriberId:o.subscriberId,agentId:o.agentId,mode:o.mode}))}catch(l){console.warn("[pane-stream] resubscribe send failed:",l)}}const r=this.outbox;this.outbox=[];for(const o of r)if(o.op!=="subscribe"){if("subscriberId"in o&&o.subscriberId){if(!this.subs.has(o.subscriberId))continue;if(this.snapshotPending.has(o.subscriberId)&&o.op!=="unsubscribe"){this.outbox.push(o);continue}}try{i.send(JSON.stringify(o))}catch(l){console.warn("[pane-stream] outbox flush failed:",l)}}},i.onmessage=r=>{if(i!==this.ws)return;let o;try{const l=typeof r.data=="string"?r.data:String(r.data);o=JSON.parse(l)}catch{return}this.handleMessage(o)},i.onclose=()=>{i===this.ws&&(this.ws=null,!this.explicitlyClosed&&this.subs.size!==0&&this.scheduleReconnect())},i.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}wsSendOrQueue(s){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(s));return}catch(n){console.warn("[pane-stream] send failed, will queue:",n)}this.outbox.push(s)}handleMessage(s){var n,i;switch(s.type){case"snapshot":this.handleSnapshot(s);break;case"subscribed":this.handleSubscribed(s);break;case"data":this.dispatch(s);break;case"session_gone":for(const r of[...this.subs.values()])r.agentId===s.agentId&&((n=r.onSessionGone)==null||n.call(r));break;case"error":{if(s.subscriberId){const r=this.subs.get(s.subscriberId);(i=r==null?void 0:r.onError)==null||i.call(r,{code:s.code,message:s.message})}else console.warn("[pane-stream] connection-level error:",s.code,s.message);break}}}handleSnapshot(s){const n=this.subs.get(s.subscriberId);n&&n.onSnapshot({cols:s.cols,rows:s.rows,data:s.data})}handleSubscribed(s){const n=this.subs.get(s.subscriberId);if(!n)return;n.snapshotSeq=s.snapshotSeq,n.lastSize||(n.lastSize={cols:s.cols,rows:s.rows}),this.snapshotPending.delete(s.subscriberId);const i=this.preSubscribeQueue.get(s.subscriberId);if(this.preSubscribeQueue.delete(s.subscriberId),i)for(const r of i)r.seq>s.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(s.subscriberId)}flushOutboxForSub(s){if(this.outbox.length===0||!this.ws||this.ws.readyState!==WebSocket.OPEN)return;const n=[];for(const i of this.outbox)if("subscriberId"in i&&i.subscriberId===s&&i.op!=="subscribe")try{this.ws.send(JSON.stringify(i))}catch(r){console.warn("[pane-stream] flushOutboxForSub send failed:",r)}else n.push(i);this.outbox=n}dispatch(s){for(const n of this.subs.values())if(n.agentId===s.agentId)if(this.snapshotPending.has(n.subscriberId)){const i=this.preSubscribeQueue.get(n.subscriberId);i&&i.push({seq:s.seq,data:s.data})}else n.onData(s.data)}}let ot=null;function ct(){return ot||(ot=new An),ot}function $n(e){const{agentId:s,mode:n}=e,i=a.useRef(null),r=a.useRef({onSnapshot:e.onSnapshot,onData:e.onData,onError:e.onError,onSessionGone:e.onSessionGone});r.current={onSnapshot:e.onSnapshot,onData:e.onData,onError:e.onError,onSessionGone:e.onSessionGone},a.useEffect(()=>{const m=ct().subscribe({agentId:s,mode:n,onSnapshot:h=>r.current.onSnapshot(h),onData:h=>r.current.onData(h),onError:h=>{var v,d;return(d=(v=r.current).onError)==null?void 0:d.call(v,h)},onSessionGone:()=>{var h,v;return(v=(h=r.current).onSessionGone)==null?void 0:v.call(h)}});return i.current=m.subscriberId,()=>{i.current=null,m.unsubscribe()}},[s,n]);const o=a.useCallback(u=>{const m=i.current;m&&ct().send(m,u)},[]),l=a.useCallback((u,m)=>{const h=i.current;h&&ct().resize(h,u,m)},[]);return{send:o,resize:l}}const Tn=[{key:"up",label:"上",path:"M12 5l-6 6m6-6l6 6m-6-6v14"},{key:"down",label:"下",path:"M12 19l6-6m-6 6l-6-6m6 6V5"},{key:"left",label:"左",path:"M5 12l6-6m-6 6l6 6m-6-6h14"},{key:"right",label:"右",path:"M19 12l-6-6m6 6l-6 6m6-6H5"}],We=Object.fromEntries(Tn.map(e=>[e.key,e]));function ze({arrow:e,onPress:s}){return t.jsx("button",{type:"button","aria-label":`方向键 ${e.label}`,"data-arrow":e.key,onMouseDown:n=>n.preventDefault(),onClick:()=>s(e.key),className:"flex h-8 w-8 items-center justify-center rounded border border-hairline bg-surface text-og-700 transition-colors hover:bg-og-50 hover:text-og-1000 active:bg-og-200",children:t.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:t.jsx("path",{d:e.path})})})}function In({onKey:e,onEscape:s,className:n}){return t.jsxs("div",{role:"group","aria-label":"终端按键",className:n??"flex flex-none items-center justify-center gap-1 border-t border-hairline bg-page px-3 py-2",children:[s&&t.jsx("button",{type:"button","aria-label":"Esc 键","data-key":"escape",onMouseDown:i=>i.preventDefault(),onClick:s,className:"mr-2 flex h-8 items-center justify-center rounded border border-hairline bg-surface px-2.5 font-mono text-xs text-og-700 transition-colors hover:bg-og-50 hover:text-og-1000 active:bg-og-200",children:"ESC"}),t.jsx(ze,{arrow:We.left,onPress:e}),t.jsx(ze,{arrow:We.up,onPress:e}),t.jsx(ze,{arrow:We.down,onPress:e}),t.jsx(ze,{arrow:We.right,onPress:e})]})}const Pn=Math.floor(nt/1024/1024);function Dn({agentId:e,className:s}){const n=a.useRef(null),[i,r]=a.useState(!1),{show:o}=ve(),l=async u=>{var h;const m=(h=u.target.files)==null?void 0:h[0];if(u.target.value="",!!m){if(m.size>nt){o({kind:"error",title:"图片过大",body:`单张图片不能超过 ${Pn} MiB`});return}r(!0);try{await I.agents.uploadImage(e,m),o({kind:"success",title:"图片已插入",body:"路径已粘贴到终端输入,补充说明后回车"})}catch(v){const d=v instanceof Pe||v instanceof Error?v.message:String(v);o({kind:"error",title:"图片上传失败",body:d})}finally{r(!1)}}};return t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button","aria-label":"上传图片",disabled:i,onMouseDown:u=>u.preventDefault(),onClick:()=>{var u;return(u=n.current)==null?void 0:u.click()},className:s??"flex h-8 w-8 items-center justify-center rounded border border-hairline bg-surface text-og-700 transition-colors hover:bg-og-50 hover:text-og-1000 active:bg-og-200 disabled:cursor-not-allowed disabled:opacity-50",children:t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[t.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),t.jsx("circle",{cx:"9",cy:"9",r:"2"}),t.jsx("path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"})]})}),t.jsx("input",{ref:n,type:"file",accept:"image/*",className:"hidden",onChange:l})]})}const Ln={up:"A",down:"B",right:"C",left:"D"};function Mn(e,s){return(s?"\x1BO":"\x1B[")+Ln[e]}const Wt=18,_n=250,On=256*1024,zt="#fdfdfd",Fn='ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',Bn={background:zt,foreground:"#474c55",cursor:"#1348dc",cursorAccent:zt,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"},Hn=/\x1b\[(?:\?[\d;]*c|>[\d;]*c|\??\d+;\d+R|\d+n)/g;function Un(e){return e.replace(Hn,"")}const qn=1024*1024;function Wn(e){const s=e.indexOf(";");if(s===-1)return null;const n=e.slice(s+1);if(n.length===0||n==="?"||n.length>qn)return null;try{const i=atob(n),r=new Uint8Array(i.length);for(let o=0;o<i.length;o++)r[o]=i.charCodeAt(o);return new TextDecoder().decode(r)}catch{return null}}function _e({agentId:e,mode:s,interactive:n=!1,maxLines:i,className:r,autoFocus:o=!0,deferFullUntilFocus:l=!1,arrowKeys:u=!1}){const m=a.useRef(null),h=a.useRef(null),v=a.useRef(null),d=a.useRef(null),f=a.useRef(!1),p=a.useRef(""),x=a.useRef([]),N=a.useRef(0),j=a.useRef(null),k=a.useRef(null),R=a.useRef(null),E=a.useRef(Promise.resolve()),b=a.useRef(0),[y,w]=a.useState(null),[_,L]=a.useState(!1),T=`${e}\0${s}\0${l?"1":"0"}`,[F,O]=a.useState({key:T,active:!1}),M=F.key===T&&F.active,z=s==="full"&&l,X=z&&!M?"preview":s,$=n&&X==="full",Z=(c,g)=>g.length===0?Promise.resolve():new Promise(S=>{try{c.write(g,()=>S())}catch(P){console.warn("[pane-terminal] write failed:",P),S()}}),q=X==="preview",V=()=>{if(!q)return;const c=m.current,g=h.current;if(!c||!g||c.clientHeight<=0)return;const P=(g.buffer.active.cursorY+1)*Wt;c.scrollTop=Math.max(0,P-c.clientHeight)},U=()=>{if(!q||R.current!==null)return;let c=!1;const g=requestAnimationFrame(()=>{c=!0,R.current=null,V()});c||(R.current=g)},Q=(c,g)=>{E.current=E.current.then(async()=>{const S=h.current;if(!(!S||g!==b.current))try{await c(S),$&&S.scrollToBottom(),U()}catch(P){console.warn("[pane-terminal] terminal task failed:",P)}}).catch(S=>{console.warn("[pane-terminal] write chain failed:",S)})},se=(c,g)=>{Q(S=>Z(S,c),g)},de=()=>{j.current!==null&&(cancelAnimationFrame(j.current),j.current=null),k.current!==null&&(clearTimeout(k.current),k.current=null)},B=()=>{de(),x.current=[],N.current=0},ie=()=>{de();const c=x.current;c.length!==0&&(x.current=[],N.current=0,se(c.join(""),b.current))},re=c=>{if(c.length!==0){if(x.current.push(c),N.current+=c.length,N.current>=On){ie();return}j.current===null&&(j.current=requestAnimationFrame(ie)),k.current===null&&(k.current=setTimeout(ie,_n))}},{send:le,resize:oe}=$n({agentId:e,mode:X,onSnapshot:({cols:c,rows:g,data:S})=>{if(h.current)try{const K=b.current+1;b.current=K,B(),Q(async J=>{var C;J.reset(),$?((C=d.current)==null||C.call(d),await Z(J,S)):(c>0&&g>0&&J.resize(c,g),await Z(J,S))},K)}catch(K){console.warn("[pane-terminal] snapshot write failed:",K)}},onData:c=>{re(c)},onError:c=>w(`${c.code}: ${c.message}`),onSessionGone:()=>L(!0)});a.useEffect(()=>{w(null),L(!1)},[e,X]),a.useEffect(()=>{p.current=""},[T]),a.useEffect(()=>{if(X!=="full")return;const c=p.current;c.length!==0&&(p.current="",le(c))},[le,X]);const me=a.useCallback(()=>{!n||!z||M||(f.current=!0,O({key:T,active:!0}))},[T,M,n,z]),ce=a.useCallback(c=>{const g=Un(c);if(g.length!==0){if(z&&(!M||p.current.length>0)){p.current+=g,me();return}le(g)}},[me,M,le,z]);a.useEffect(()=>{const c=m.current;if(!c)return;let g=!1;const S=new Xs.Terminal({cursorBlink:n,disableStdin:!n,theme:Bn,fontFamily:Fn,fontSize:13,lineHeight:1.4,scrollback:X==="full"?5e3:1e3}),P=new Zs.FitAddon;S.loadAddon(P),S.open(c),h.current=S,v.current=P;const K=q?S.onRender(()=>U()):null;if(n&&(o||f.current)){f.current=!1;try{S.focus()}catch{}}n&&(S.onData(ce),X==="full"&&S.parser.registerOscHandler(52,be=>{var Se;const we=Wn(be);return we!==null&&((Se=navigator.clipboard)==null||Se.writeText(we).catch(()=>{})),!0}));const J=()=>c.clientWidth>0&&c.clientHeight>0,C=(be=!1)=>{if(!J())return!1;const we=S.cols,Se=S.rows;try{P.fit()}catch{return!1}return $&&S.scrollToBottom(),S.cols>0&&S.rows>0&&(be||S.cols!==we||S.rows!==Se)&&oe(S.cols,S.rows),!0};d.current=$?()=>C(!0):null;let D=null,Y=null,G=null,je=0;const ge=()=>{D||(D=new ResizeObserver(()=>{Y&&clearTimeout(Y),Y=setTimeout(()=>{Y=null,$?C():q&&U()},100)}),D.observe(c))},Ae=()=>{G=requestAnimationFrame(()=>{if(G=null,!g){if(!$){q&&(ge(),U());return}if(C(!0)){ge();return}if(je++<5){Ae();return}ge()}})};return Ae(),()=>{g=!0,G!==null&&cancelAnimationFrame(G),j.current!==null&&(cancelAnimationFrame(j.current),j.current=null),k.current!==null&&(clearTimeout(k.current),k.current=null),R.current!==null&&(cancelAnimationFrame(R.current),R.current=null),b.current++,x.current=[],N.current=0,E.current=Promise.resolve(),Y&&clearTimeout(Y),D==null||D.disconnect(),K==null||K.dispose(),h.current=null,v.current=null,d.current=null;try{S.dispose()}catch(be){console.warn("[pane-terminal] dispose failed:",be)}}},[e,o,$,ce,n,X,oe]);const ue=()=>{var c;if(n){me();try{(c=h.current)==null||c.focus()}catch{}}};a.useEffect(()=>{if(n)return;const c=m.current;if(!c)return;const g=S=>{S.stopPropagation()};return c.addEventListener("wheel",g,{capture:!0,passive:!0}),()=>c.removeEventListener("wheel",g,{capture:!0})},[n]);const A=i&&i>0?{maxHeight:`${i*Wt}px`}:void 0;return t.jsxs("div",{className:r??"flex flex-col h-full w-full min-h-0 bg-term",children:[(y||_)&&t.jsx("div",{className:"border-b border-accent/25 bg-accent-soft px-3 py-1 font-mono text-xs text-accent",children:_?"会话已结束":y}),t.jsx("div",{className:"flex flex-1 min-h-0 px-2 py-1.5",style:A,children:t.jsx("div",{ref:m,className:"flex-1 min-h-0 overflow-hidden",onMouseDown:ue})}),n&&u&&t.jsxs("div",{className:"grid grid-cols-[1fr_auto_1fr] gap-2 flex-none items-center border-t border-hairline bg-page px-3 py-2",children:[t.jsx("div",{className:"flex items-center",children:t.jsx(Dn,{agentId:e})}),t.jsx(In,{className:"flex items-center justify-center gap-1",onKey:c=>{var S,P;const g=!!((P=(S=h.current)==null?void 0:S.modes)!=null&&P.applicationCursorKeysMode);ce(Mn(c,g))},onEscape:()=>ce("\x1B")})]})]})}function zn(){const[e,s]=a.useState([]),[n,i]=a.useState(!0),[r,o]=a.useState(null),l=a.useCallback(async()=>{i(!0);try{s(await I.pets.list()),o(null)}catch(u){o(u instanceof Error?u.message:String(u))}finally{i(!1)}},[]);return a.useEffect(()=>{l()},[l]),{pets:e,loading:n,error:r,refresh:l}}const lt=new Map,dt=new Map;function Gn(e){const[s,n]=a.useState(()=>e?dt.get(e)??null:null);return a.useEffect(()=>{if(!e){n(null);return}const i=dt.get(e);if(n(i??null),i)return;let r=!1,o=lt.get(e);return o||(o=I.pets.fetchSpritesheet(e).then(l=>{const u=URL.createObjectURL(l);return dt.set(e,u),u}),lt.set(e,o)),o.then(l=>{r||n(l)},()=>{r||n(null),lt.delete(e)}),()=>{r=!0}},[e]),s}const Qn=[{state:"idle",row:0,durations:[280,110,110,140,140,320]},{state:"running-right",row:1,durations:[120,120,120,120,120,120,120,220]},{state:"running-left",row:2,durations:[120,120,120,120,120,120,120,220]},{state:"waving",row:3,durations:[140,140,140,280]},{state:"jumping",row:4,durations:[140,140,140,140,280]},{state:"failed",row:5,durations:[140,140,140,140,140,140,140,240]},{state:"waiting",row:6,durations:[150,150,150,150,150,260]},{state:"running",row:7,durations:[120,120,120,120,120,220]},{state:"review",row:8,durations:[150,150,150,150,150,280]}];function Kn(e,s){if(s)return 3;switch(e){case"working":return 7;case"waiting":return 6;case"pending":return 6;case"error":return 5;case"idle":return 0;case"unknown":return 0;default:return 0}}const At=36,Vn=At/vs,Jn=bs*Vn;function Yn(){return typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}function Ss({petId:e,status:s,bootstrapping:n=!1,label:i,displayHeight:r=At,className:o}){const l=Gn(e),u=Kn(s,n),m=Qn[u],h=m.durations.length,[v,d]=a.useState(0),f=r/vs,p=bs*f;return a.useEffect(()=>{if(d(0),!l||h<=1||Yn())return;let x,N=0;const j=()=>{N=(N+1)%h,d(N),x=setTimeout(j,m.durations[N])};return x=setTimeout(j,m.durations[0]),()=>clearTimeout(x)},[l,u,h,m]),l?t.jsx("span",{role:"img","aria-label":i,title:i,"data-pet-row":u,"data-pet-col":v,className:["inline-block shrink-0",o].filter(Boolean).join(" "),style:{width:`${p}px`,height:`${r}px`,backgroundImage:`url(${l})`,backgroundRepeat:"no-repeat",backgroundSize:`${nn*f}px ${rn*f}px`,backgroundPositionX:`${-(v*p)}px`,backgroundPositionY:`${-(u*r)}px`,imageRendering:"pixelated"}}):t.jsx("span",{className:"pill pill-idle",title:i,children:i})}class Ve extends Error{constructor(s){super(s),this.name="PetPackageError"}}const Ge=e=>e.split("/").pop()??e;function Xn(e){return typeof e.text=="function"?e.text():new Promise((s,n)=>{const i=new FileReader;i.onerror=()=>n(i.error??new Error("file read failed")),i.onload=()=>s(typeof i.result=="string"?i.result:""),i.readAsText(e)})}async function Zn(e){const s=e.find(l=>Ge(l.name)==="pet.json"||Ge(l.webkitRelativePath||"")==="pet.json");if(!s)throw new Ve("文件包中未找到 pet.json");let n;try{n=JSON.parse(await Xn(s))}catch{throw new Ve("pet.json 解析失败")}const i=n&&typeof n=="object"&&typeof n.spritesheetPath=="string"?n.spritesheetPath:"",r=i?Ge(i):"",o=(r?e.find(l=>Ge(l.name)===r):void 0)??e.find(l=>/\.(png|webp)$/i.test(l.name));if(!o)throw new Ve("文件包中未找到精灵图(png/webp)");return{manifest:n,spritesheet:o}}function er({children:e,style:s}){const n=a.useRef(null),[i,r]=a.useState(typeof IntersectionObserver>"u");return a.useEffect(()=>{if(i||typeof IntersectionObserver>"u")return;const o=n.current;if(!o)return;const l=new IntersectionObserver(u=>{u.some(m=>m.isIntersecting)&&(r(!0),l.disconnect())});return l.observe(o),()=>l.disconnect()},[i]),t.jsx("span",{ref:n,className:"inline-block shrink-0",style:s,children:i?e:null})}function tr({agentId:e,currentPetId:s,onClose:n}){const{show:i}=ve(),r=Ct(),{pets:o,loading:l,refresh:u}=zn(),[m,h]=a.useState(!!s),[v,d]=a.useState(s),[f,p]=a.useState(!1),x=a.useRef(null);a.useEffect(()=>{d(s)},[s]),a.useEffect(()=>{const b=x.current;b&&(b.setAttribute("webkitdirectory",""),b.setAttribute("directory",""))},[m]);const N=b=>b instanceof Pe||b instanceof Error?b.message:String(b),j=async b=>{if(h(b),!b&&v){p(!0);try{await I.agents.setPet(e,null),d(null),i({kind:"success",title:"已关闭 Agent Pet"})}catch(y){i({kind:"error",title:"关闭失败",body:N(y)}),h(!0)}finally{p(!1)}}},k=async b=>{p(!0);try{await I.agents.setPet(e,b),d(b),i({kind:"success",title:"已选择 Pet"})}catch(y){i({kind:"error",title:"选择失败",body:N(y)})}finally{p(!1)}},R=async(b,y)=>{if(await r({title:`删除 Pet「${y}」?`,body:"使用它的 Agent 会回到默认状态显示。",confirmLabel:"删除"})){p(!0);try{await I.pets.remove(b),await u(),i({kind:"success",title:`Pet「${y}」已删除`})}catch(w){i({kind:"error",title:"删除失败",body:N(w)})}finally{p(!1)}}},E=async b=>{const y=b.target.files?Array.from(b.target.files):[];if(b.target.value="",!!y.length){p(!0);try{const{manifest:w,spritesheet:_}=await Zn(y);await I.pets.create(w,_),await u(),i({kind:"success",title:"Pet 上传成功"})}catch(w){const _=w instanceof Ve?w.message:N(w);i({kind:"error",title:"Pet 上传失败",body:_})}finally{p(!1)}}};return t.jsx(Ne,{open:!0,onClose:n,title:"Agent Pet",size:"md",children:t.jsxs("div",{className:"space-y-4",children:[t.jsxs("label",{className:"flex items-center gap-2 text-sm text-og-1000",children:[t.jsx("input",{type:"checkbox",checked:m,disabled:f,onChange:b=>void j(b.target.checked)}),"启用 Agent Pet"]}),m?t.jsxs(t.Fragment,{children:[t.jsxs("div",{children:[t.jsx("button",{type:"button",onClick:()=>{var b;return(b=x.current)==null?void 0:b.click()},disabled:f,className:"btn-secondary",children:"上传 Pet 文件包"}),t.jsx("input",{ref:x,type:"file","aria-label":"上传 Codex Pet 文件包",className:"hidden",onChange:b=>void E(b)}),t.jsx("p",{className:"mt-1 text-xs text-og-400",children:"选择 Codex Pet 目录(含 pet.json 与精灵图)。"})]}),l?t.jsx("p",{className:"text-sm text-og-500",children:"加载中…"}):o.length===0?t.jsx("p",{className:"text-sm text-og-500",children:"还没有上传过 Pet,点击上方按钮上传。"}):t.jsx("ul",{className:"grid grid-cols-2 gap-2",children:o.map(b=>{const y=b.id===v;return t.jsxs("li",{className:`flex items-center gap-2 rounded-md border p-2 ${y?"border-accent bg-accent-soft/40":"border-hairline"}`,children:[t.jsx(er,{style:{width:`${Jn}px`,height:`${At}px`},children:t.jsx(Ss,{petId:b.id,status:"idle",label:b.displayName})}),t.jsxs("button",{type:"button",onClick:()=>void k(b.id),disabled:f||y,title:b.description||b.displayName,className:"min-w-0 flex-1 truncate text-left text-sm text-og-1000 hover:text-accent-hover disabled:cursor-default",children:[b.displayName,y&&t.jsx("span",{className:"ml-1 text-xs text-accent",children:"(当前)"})]}),t.jsx("button",{type:"button","aria-label":`删除 ${b.displayName}`,onClick:()=>void R(b.id,b.displayName),disabled:f,className:"shrink-0 text-xs text-accent hover:underline disabled:opacity-50",children:"删除"})]},b.id)})})]}):t.jsx("p",{className:"text-xs text-og-500",children:"开启后可上传 Codex Pet 文件包,或选择已上传过的 Pet 替换 Agent 卡片上的状态显示。"})]})})}const sr={unknown:{label:"未知",cls:"pill pill-idle"},idle:{label:"空闲",cls:"pill pill-idle"},pending:{label:"待人工",cls:"pill pill-warn"},working:{label:"工作中",cls:"pill pill-live"},waiting:{label:"等待中",cls:"pill pill-review"},error:{label:"异常",cls:"pill pill-warn"}},nr=72,rr={absent:{label:"无会话",modifier:"status-dot--warn"},unreachable:{label:"主机不可达",modifier:"status-dot--danger"},unknown:{label:"会话状态未知",modifier:"status-dot--warn"},starting:{label:"会话启动中",modifier:"status-dot--info"}};function ir({state:e}){if(e==="present")return null;const{label:s,modifier:n}=rr[e];return t.jsx("span",{role:"img","aria-label":s,title:s,className:`status-dot ml-2 ${n}`})}function ks({agent:e,projectId:s,role:n,runtime:i,onDeleted:r,pendingRestart:o=!1,terminalLoading:l=!1,showTaskBinding:u=!0,terminalMode:m="activity-preview",active:h,onActivate:v}){var be,we,Se,Mt,_t,Ot,Ft,Bt;const[d,f]=a.useState(!1),[p,x]=a.useState(null),{show:N}=ve(),j=Ct(),{flagDirty:k}=rt(),[R,E]=a.useState(!1),[b,y]=a.useState(null),[w,_]=a.useState(!1),[L,T]=a.useState(!1),[F,O]=a.useState(!1),[M,z]=a.useState(!1),[X,$]=a.useState(!1),[Z,q]=a.useState(!1),V=(be=e.binding)==null?void 0:be.taskId,U=((we=e.binding)==null?void 0:we.status)==="awaiting_human",Q=U&&((Se=e.binding)==null?void 0:Se.awaitingPhase)==="greeting_failed",se=!!((Mt=e.binding)!=null&&Mt.creationToken)&&!((_t=e.binding)!=null&&_t.paneId)&&!U&&e.reason!=="PENDING_HUMAN",de=se&&e.tmuxSessionStatus!=="present",B=se?{label:"启动中",cls:"pill pill-review"}:sr[e.runtimeStatus],ie=se?"starting":e.tmuxSessionStatus,re=m==="activity-preview"&&!de&&(e.runtimeStatus==="working"||e.runtimeStatus==="pending"),le=m==="embedded-full",oe=le&&typeof v=="function",me=oe&&h===!0,ce=l||o||de,ue=l?"Agent 状态加载中":o?"重启 baxian server 后可用":"Agent 正在启动",A=fs(i),c=async()=>{f(!0),x(null);try{await I.agents.stop(e.id)}catch(H){x(H instanceof Error?H.message:String(H))}finally{f(!1)}},g=async()=>{if(!(!V||!await j({title:"发起 QA 重审?",body:`QA agent 将对任务 ${V} 立即开始新一轮 review(reviewRound +1)。`,confirmLabel:"发起重审"}))){O(!0);try{const fe=await I.tasks.review(V);N({kind:"success",title:`已发起 QA 重审(第 ${fe.reviewRound} 轮)`})}catch(fe){N({kind:"error",title:"发起评审失败",body:fe instanceof Error?fe.message:String(fe)})}finally{O(!1)}}},S=async()=>{$(!0);try{(await I.projects.bootstrap(s)).ok?N({kind:"success",title:"重试 bootstrap 完成",body:"agent 状态将在下一次刷新生效。"}):N({kind:"warn",title:"重试 bootstrap 仍失败",body:"看一下红色错误卡的最新原因,按提示修复后再试。"})}catch(H){N({kind:"error",title:"重试 bootstrap 失败",body:H instanceof Error?H.message:String(H)})}finally{$(!1)}},P=async()=>{if(await j({title:`恢复 Agent ${e.id}?`,body:Q?"greeting 能力未通过,baxian 会重跑能力握手(会话存活则重启 REPL,已丢失则重建);握手通过才解除挂起。":"baxian 会清除 awaiting_human 状态,agent 恢复可用。",confirmLabel:"恢复"})){z(!0);try{if(Q){e.tmuxSessionStatus==="present"?await I.projects.restartRepl(s,e.id):await I.projects.retryAgent(s,e.id),N({kind:"success",title:`Agent ${e.id} 正在重跑能力握手`,body:"握手通过后 Held 会在下一次刷新自动解除,仍失败则按提示修复 runtime 后再试。"});return}const fe=await I.projects.resumeAgent(s,e.id);N({kind:"success",title:`Agent ${e.id} 已 Resume`,body:fe.releasedBinding?"原任务已释放,agent 可接新任务。":"保留绑定(原任务仍 active)。"})}catch(fe){N({kind:"error",title:"Resume 失败",body:fe instanceof Error?fe.message:String(fe)})}finally{z(!1)}}},K=async()=>{_(!0);try{await I.agents.compact(e.id),N({kind:"success",title:`已向 Agent ${e.id} 发送 /compact`})}catch(H){N({kind:"error",title:"压缩上下文失败",body:H instanceof Error?H.message:String(H)})}finally{_(!1)}},J=async()=>{if(await j({title:`清空 Agent ${e.id} 的上下文?`,body:"将发送 /clear,整个会话上下文不可恢复。",confirmLabel:"清空"})){T(!0);try{await I.agents.clear(e.id),N({kind:"success",title:`已向 Agent ${e.id} 发送 /clear`})}catch(H){N({kind:"error",title:"清空上下文失败",body:H instanceof Error?H.message:String(H)})}finally{T(!1)}}},C=async()=>{if(await j({title:`删除 Agent ${e.id}?`,body:"此操作不可撤销。",confirmLabel:"删除"})){E(!0),y(null);try{const H=await I.projects.deleteAgent(s,e.id);H!=null&&H.restartRequired&&k();const fe=(H==null?void 0:H.removed)??[e.id];if(fe.length>1){const Gs=fe.filter(Qs=>Qs!==e.id).join(", ");N({kind:"warn",title:`已删除 Agent ${e.id}`,body:`配对的 QA agent ${Gs} 也被一并移除。`})}else N({kind:"success",title:`Agent ${e.id} 已删除`});r==null||r()}catch(H){y(H instanceof Error?H.message:String(H))}finally{E(!1)}}},D=oe&&!ce&&!me,Y=["card relative flex h-full min-w-0 flex-col overflow-visible p-4",me?"ring-2 ring-accent":""].filter(Boolean).join(" "),G=["mb-3 flex items-start justify-between gap-2",e.petId?"pr-28":""].filter(Boolean).join(" "),je=["mb-2 mt-3 h-80 min-h-0 overflow-hidden border border-hairline bg-surface",D?"cursor-pointer":""].filter(Boolean).join(" "),ge=D?()=>v==null?void 0:v():void 0,Ae=D?H=>{(H.key==="Enter"||H.key===" ")&&(H.preventDefault(),v==null||v())}:void 0;return t.jsxs("div",{className:Y,"data-agent-card":oe?e.id:void 0,children:[e.petId&&t.jsx("div",{className:"absolute -top-4 right-7 z-10",children:t.jsx(Ss,{petId:e.petId,status:e.runtimeStatus,bootstrapping:se,label:B.label,displayHeight:nr})}),t.jsxs("div",{className:G,children:[t.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[t.jsx("span",{className:"shrink-0 font-mono text-xs font-medium tracking-[0.05em] text-og-500",children:n==="qa"?"QA":"Dev"}),t.jsx("span",{className:"min-w-0 truncate whitespace-nowrap font-display text-sm font-semibold text-og-1000",title:hs(e.id,i),children:e.id}),A&&t.jsxs("span",{className:"hidden shrink-0 whitespace-nowrap text-xs text-og-400 sm:inline",title:A,children:["(",A,")"]})]}),t.jsxs("div",{className:"flex flex-wrap items-center justify-end gap-1",children:[U&&t.jsx("span",{className:"pill pill-warn",title:((Ot=e.binding)==null?void 0:Ot.awaitingReason)??"需人工处理",children:"挂起"}),!e.petId&&t.jsx("span",{className:B.cls,children:B.label}),e.stale&&t.jsx("span",{className:"pill pill-warn",title:e.observedAt?`Last observed at ${e.observedAt}`:void 0,children:"失联"}),t.jsx(ir,{state:ie})]})]}),de&&t.jsx("div",{className:"mb-2 rounded-md border border-accent-soft bg-accent-soft/40 px-2.5 py-2 text-xs text-accent",children:"Agent 正在启动,终端可用后会自动刷新。"}),U&&t.jsxs("div",{className:"mb-2 rounded-md border border-accent/25 bg-accent-soft/60 px-2.5 py-2 text-xs text-accent",children:[t.jsx("span",{className:"font-mono",children:(Ft=e.binding)==null?void 0:Ft.awaitingPhase}),((Bt=e.binding)==null?void 0:Bt.awaitingReason)&&t.jsxs("span",{children:[" · ",e.binding.awaitingReason]})]}),!se&&e.runtimeStatus==="pending"&&t.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-accent/25 bg-accent-soft/60 px-2.5 py-2 text-xs text-accent",children:[t.jsx("div",{className:"font-medium",children:"等待人工介入"}),t.jsxs("div",{children:["请打开 ",t.jsx(Be,{to:`/terminal/${e.id}`,className:"text-accent hover:text-accent-hover underline",children:"终端"})," 处理。"]})]}),e.latestError&&t.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-accent/25 bg-accent-soft px-2.5 py-2 text-xs text-accent",children:[t.jsx("div",{className:"break-words font-medium",children:e.latestError.message}),t.jsxs("div",{className:"font-mono text-xs opacity-80",children:[e.latestError.reason," · ",e.latestError.occurredAt]})]}),e.latestBootstrapError&&t.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-accent/25 bg-accent-soft px-2.5 py-2 text-xs text-accent",children:[t.jsx("div",{className:"break-words font-medium",children:e.latestBootstrapError.message}),e.latestBootstrapError.recommendation&&t.jsx("div",{className:"break-words",children:e.latestBootstrapError.recommendation}),t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsxs("div",{className:"truncate font-mono text-xs opacity-80",children:[e.latestBootstrapError.reason," · ",e.latestBootstrapError.occurredAt]}),t.jsx("button",{type:"button",onClick:S,disabled:X,className:"btn-primary shrink-0",children:X?"重试中…":"重试 bootstrap"})]})]}),u&&V&&t.jsxs("div",{className:"mb-2 text-xs text-og-500",children:["任务:",t.jsx("span",{className:"font-mono text-og-700",children:V})]}),re&&t.jsx("div",{className:"mb-2 overflow-hidden border border-hairline bg-surface",children:t.jsx(_e,{agentId:e.id,mode:"preview",maxLines:6,interactive:!1})}),le&&t.jsx("div",{className:je,role:D?"button":void 0,tabIndex:D?0:void 0,"aria-label":D?`激活 ${e.id} 终端`:void 0,onClick:ge,onKeyDown:Ae,children:ce?t.jsx("div",{className:"flex h-full items-center justify-center px-3 text-sm text-og-500",children:ue}):oe?me?t.jsx(_e,{agentId:e.id,mode:"full",interactive:!0,autoFocus:!0}):t.jsx(_e,{agentId:e.id,mode:"preview",interactive:!1}):t.jsx(_e,{agentId:e.id,mode:"full",interactive:!0,autoFocus:!1,deferFullUntilFocus:!0})}),o&&t.jsx("div",{className:"mb-2 rounded-md border border-accent/25 bg-accent-soft/60 px-2.5 py-1.5 text-xs text-accent",children:"重启 baxian server 后生效"}),t.jsxs("div",{className:"mt-3 flex items-center gap-2",children:[t.jsxs("div",{className:"flex min-w-0 flex-1 items-center gap-2 overflow-x-auto scrollbar-none",children:[ce?t.jsx("span",{className:"shrink-0 cursor-not-allowed text-sm text-og-400",title:ue,children:"终端"}):t.jsx(Be,{to:`/terminal/${e.id}`,className:"btn-secondary shrink-0",children:"终端"}),!o&&e.runtimeStatus==="working"&&t.jsx("button",{onClick:c,disabled:d,className:"btn-ghost shrink-0",children:d?"停止中…":"停止"}),U&&t.jsx("button",{type:"button",onClick:P,disabled:M,title:Q?"重跑 greeting 能力握手以恢复(会话存活则重启 REPL,已丢失则重建;greeting_failed 无法靠清状态解除)":"清除 awaiting_human 状态,让 agent 恢复可用",className:"btn-primary shrink-0",children:M?"恢复中…":"恢复"})]}),t.jsx(St,{ariaLabel:`Agent ${e.id} 操作菜单`,className:"shrink-0",placement:"up",autoFocusFirstItem:!0,disabled:R,children:H=>t.jsxs(t.Fragment,{children:[t.jsx(he,{onClick:()=>{H(),q(!0)},disabled:w||L||R,title:"配置 Agent Pet(在状态位置显示动画宠物)",children:"Agent Pet"}),t.jsx(he,{onClick:()=>{H(),K()},disabled:w||L||R,title:"向 agent runtime 发送 /compact 压缩上下文",children:w?"压缩中…":"压缩上下文"}),t.jsx(he,{onClick:()=>{H(),J()},disabled:L||w||R,title:"向 agent runtime 发送 /clear 清空上下文",children:L?"清空中…":"清空上下文"}),!o&&V&&n==="dev"&&t.jsx(he,{onClick:()=>{H(),g()},disabled:F||R,title:`让 QA agent 立即对任务 ${V} 跑一轮 review(需要该任务已有 PR)`,children:F?"发起中…":"发起评审"}),t.jsx(he,{onClick:()=>{H(),C()},disabled:R||w||L,children:R?"删除中…":"删除"})]})})]}),p&&t.jsx("div",{className:"mt-1.5 break-words text-xs text-accent",children:p}),b&&t.jsx("div",{className:"mt-1.5 break-words text-xs text-accent",children:b}),Z&&t.jsx(tr,{agentId:e.id,currentPetId:e.petId??null,onClose:()=>q(!1)})]})}const ut="baxian:terminal-activated";function Es({coordinateAcrossInstances:e=!0}={}){const s=a.useId(),[n,i]=a.useState(null);a.useEffect(()=>{if(n===null)return;const o=m=>{m.composedPath().some(d=>d instanceof Element&&d.hasAttribute("data-agent-card"))||i(null)},l=m=>{if(m.key!=="Escape")return;const h=document.activeElement;h instanceof Element&&h.closest("[data-agent-card]")||i(null)},u=m=>{const h=m.detail;(h==null?void 0:h.ownerId)!==s&&i(null)};return document.addEventListener("click",o),document.addEventListener("keydown",l),e&&document.addEventListener(ut,u),()=>{document.removeEventListener("click",o),document.removeEventListener("keydown",l),e&&document.removeEventListener(ut,u)}},[n,e,s]);const r=a.useCallback(o=>{i(o),e&&document.dispatchEvent(new CustomEvent(ut,{detail:{ownerId:s}}))},[e,s]);return{activeAgentId:n,activateAgentCard:r}}const ar={pending:"待处理",in_progress:"进行中",review:"评审中",fixing:"修订中","spec-ready":"Spec 待批",approved:"已通过","merge-ready":"待确认",ready:"待确认",merged:"已合并",done:"已完成",failed:"失败",max_rounds:"轮次达上限",cancelled:"已取消"};function Ie(e){return ar[e]??e}const Rs={pending:"pill",in_progress:"pill pill-live",review:"pill pill-review",fixing:"pill pill-live","spec-ready":"pill pill-warn",approved:"pill pill-review","merge-ready":"pill pill-warn",ready:"pill pill-warn",merged:"pill pill-live",done:"pill pill-live",failed:"pill pill-warn",max_rounds:"pill pill-warn",cancelled:"pill"},or={pending:"bg-og-300",in_progress:"bg-og-1000",review:"bg-og-400",fixing:"bg-og-1000","spec-ready":"bg-accent",approved:"bg-og-400","merge-ready":"bg-accent",ready:"bg-accent",merged:"bg-og-1000",done:"bg-og-1000",failed:"bg-accent",max_rounds:"bg-accent",cancelled:"bg-og-300"};function cr({status:e}){return t.jsx("span",{role:"img","aria-label":e,title:e,className:`inline-block h-2 w-2 shrink-0 rounded-full ${or[e]??"bg-og-300"}`})}function $t(e){if(!e)return"";const s=e.match(/^task-(\d+)$/);return s?s[1]:e}function mt(e,s=!0){if(e==null)return"";const n=String(e).trim();if(!n)return"";const i=new Date(n.replace(/^(\d{4}-\d{2}-\d{2}) /,"$1T"));if(Number.isNaN(i.getTime()))return n;const r=u=>String(u).padStart(2,"0"),o=`${i.getFullYear()}-${r(i.getMonth()+1)}-${r(i.getDate())}`,l=`${r(i.getHours())}:${r(i.getMinutes())}`;return s?`${o} ${l}:${r(i.getSeconds())}`:`${o} ${l}`}function Ce(e,s){return`/project/${encodeURIComponent(e)}/task/${encodeURIComponent(s)}`}function Cs({group:e,projectId:s,agentsById:n,agentsLoaded:i,agentsError:r=!1,tasks:o,onDeleted:l,terminalMode:u="activity-preview"}){var w,_,L;const m=e.find(T=>T.role==="dev")??e[0],h=e.find(T=>T.role==="qa"),v=o.filter(T=>dr(T,m==null?void 0:m.id,h==null?void 0:h.id)),d=m?o.filter(T=>ur(T,s,m.id)).sort((T,F)=>T.createdAt.localeCompare(F.createdAt)):[],f=m?n.get(m.id):void 0,p=!!f&&f.runtimeStatus==="idle"&&((w=f.binding)==null?void 0:w.status)!=="awaiting_human"&&!((_=f.binding)!=null&&_.creationToken)&&!((L=f.binding)!=null&&L.taskId),x=`Agent group ${e.map(T=>T.id).join(" / ")}`,N=pe(),j=u==="embedded-full",{activeAgentId:k,activateAgentCard:R}=Es({coordinateAcrossInstances:j}),E=u==="embedded-full"?e.length<=1?"lg:grid-cols-1":e.length===2?"lg:grid-cols-2":e.length===3?"lg:grid-cols-3":"lg:grid-cols-4":"sm:grid-cols-2",b=!!m&&d.length>0,y=v.length===0&&!b;return t.jsxs("div",{role:"group","aria-label":x,className:"min-w-0",children:[b&&m&&t.jsx(lr,{tasks:d,devId:m.id,dispatchReady:p,label:x}),v.length>0&&t.jsx("div",{className:"card mb-2 max-h-28 overflow-y-auto divide-y divide-hairline",children:v.map(T=>{const F=T.phase==="spec"?T.specReviewRound??0:T.reviewRound;return t.jsxs("button",{type:"button",onClick:()=>N(Ce(T.projectId,T.id)),className:"flex w-full items-center gap-3 px-3 py-2 text-left text-sm transition-colors hover:bg-og-50/60",children:[t.jsxs("div",{className:"min-w-0 flex-1 flex items-center gap-2",children:[t.jsx("span",{className:"shrink-0 font-mono text-xs text-og-500",title:T.id,children:$t(T.id)}),t.jsx("span",{className:"truncate text-og-1000",children:T.title})]}),t.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[t.jsxs("span",{className:"shrink-0 text-xs text-og-500",children:["第 ",F," 轮"]}),t.jsx("span",{className:`${Rs[T.status]} shrink-0`,title:T.status,children:Ie(T.status)})]})]},T.id)})}),y&&t.jsx("div",{className:"mb-2 rounded-lg border border-hairline bg-surface px-3 py-2 text-sm text-og-400","aria-label":`${x} no active task`,children:"暂无任务"}),t.jsx("div",{className:`grid grid-cols-1 ${E} gap-4`,children:e.map(T=>{const F=n.get(T.id),O=F??{id:T.id,projectId:s,runtimeStatus:"unknown",tmuxSessionStatus:"unknown",stale:!0};return t.jsx(ks,{agent:O,projectId:s,role:T.role,runtime:T.runtime,pendingRestart:i&&!F,terminalLoading:!i&&!F&&!r,onDeleted:l,showTaskBinding:!1,terminalMode:u,...j?{active:k===T.id,onActivate:()=>R(T.id)}:{}},T.id)})})]})}function lr({tasks:e,devId:s,dispatchReady:n,label:i}){const{show:r}=ve(),o=pe(),[l,u]=a.useState(null),m=async h=>{u(h);try{await I.tasks.dispatch(h,{agentId:s}),r({kind:"success",title:`任务 ${h} 已交给 ${s}`})}catch(v){r({kind:"error",title:"发起失败",body:v instanceof Error?v.message:String(v)})}finally{u(null)}};return t.jsx("div",{role:"group",className:"card mb-2 max-h-28 overflow-y-auto divide-y divide-hairline","aria-label":`${i} claimable tasks for ${s}`,children:e.map(h=>{const v=h.preferredAgentId==="",d=l!==null;return t.jsxs("div",{className:"flex items-center gap-3 px-3 py-2 text-sm",children:[t.jsxs("button",{type:"button",onClick:()=>o(Ce(h.projectId,h.id)),className:"min-w-0 flex-1 flex items-center gap-2 text-left transition-colors hover:text-accent-hover",children:[t.jsx("span",{className:"shrink-0 font-mono text-xs text-og-500",title:h.id,children:$t(h.id)}),t.jsx("span",{className:"truncate text-og-1000",title:h.title,children:h.title}),v&&t.jsx("span",{className:"pill shrink-0",children:"未分配"})]}),t.jsx("button",{type:"button",onClick:()=>void m(h.id),disabled:!n||d,title:n?`交给 ${s} 并立即开始`:"Dev agent 当前不可用",className:"shrink-0 text-sm font-medium text-accent transition-colors hover:text-accent-hover disabled:opacity-50 disabled:cursor-not-allowed",children:l===h.id?"发起中…":"发起"})]},h.id)})})}function dr(e,s,n){return!(!s||!ps.has(e.status)||!(e.agentId===s||e.preferredAgentId===s)||n&&e.qaAgentId&&e.qaAgentId!==n)}function ur(e,s,n){return e.projectId!==s||e.status!=="pending"?!1:e.preferredAgentId===n||e.preferredAgentId===""}const ae="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-sm 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",ee="mb-1.5 block text-xs font-medium text-og-700",Xe="mt-1 text-xs text-accent",ft="mt-1 text-xs text-og-500",Te="h-3.5 w-3.5 accent-accent",mr=/^[a-z][a-z0-9-]{1,31}$/,fr=[/^https?:\/\/[^/\s]+\/[^\s]+$/,/^ssh:\/\/[^/\s]+\/[^\s]+$/,/^[^@/\s]+@[^:/\s]+:[^\s]+$/,/^[^/\s:@]+\/[^/\s]+$/];function hr({open:e,onClose:s,onCreated:n}){const[i,r]=a.useState(""),[o,l]=a.useState(""),[u,m]=a.useState(null),[h,v]=a.useState(null),[d,f]=a.useState(""),[p,x]=a.useState(!1),[N,j]=a.useState(null),[k,R]=a.useState({}),[E,b]=a.useState(new Set),y=a.useRef(0),{show:w}=ve(),{flagDirty:_}=rt();a.useEffect(()=>{if(!e)return;y.current+=1;const O=y.current;r(""),l(""),m(null),v(null),f(""),j(null),R({}),b(new Set),I.config.get().then(M=>{O===y.current&&b(new Set(M.project.map(z=>z.id)))}).catch(()=>{})},[e]);const L=()=>{p||s()},T=()=>{const O={};return i?mr.test(i)?E.has(i)&&(O.id="该 id 已被占用"):O.id="小写字母开头,只含 a-z 0-9 -,长度 2-32":O.id="必填",o?fr.some(M=>M.test(o.trim()))||(O.repo="需为 git URL(https / ssh / scp,如 https://gitlab.example.com/group/proj.git)或 owner/repo"):O.repo="必填",R(O),Object.keys(O).length===0},F=async O=>{if(O.preventDefault(),!!T()){x(!0),j(null);try{const M=await I.projects.create({id:i,repo:o.trim(),merge:u,...h?{specApproval:h}:{},...d?{review:{mode:d}}:{}});M.restartRequired&&_(),w({kind:"success",title:`项目 ${M.project.id} 已创建`}),n(M.project.id)}catch(M){j(M instanceof Error?M.message:String(M))}finally{x(!1)}}};return t.jsx(Ne,{open:e,onClose:L,title:"新建项目",size:"md",footer:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:L,disabled:p,className:"btn-secondary",children:"取消"}),t.jsx("button",{type:"submit",form:"create-project-form",disabled:p,className:"btn-primary",children:p?"创建中…":"创建"})]}),children:t.jsxs("form",{id:"create-project-form",onSubmit:F,className:"space-y-3",children:[N&&t.jsx("div",{className:"rounded-md border border-accent/25 bg-accent-soft px-3 py-2 text-sm text-accent",children:N}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"proj-id",children:"项目 ID"}),t.jsx("input",{id:"proj-id",type:"text",value:i,onChange:O=>r(O.target.value),className:ae,placeholder:"kongkong",disabled:p}),k.id&&t.jsx("div",{className:Xe,children:k.id})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"proj-repo",children:"Git 仓库地址"}),t.jsx("input",{id:"proj-repo",type:"text",value:o,onChange:O=>l(O.target.value),className:ae,placeholder:"https://github.com/baxian-ai/baxian.git",disabled:p}),k.repo&&t.jsx("div",{className:Xe,children:k.repo})]}),t.jsxs("div",{children:[t.jsx("span",{className:ee,children:"合并策略"}),t.jsxs("label",{className:"mb-1 flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"merge",checked:u===null,onChange:()=>m(null),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"人类合并(默认)"})]}),t.jsxs("label",{className:"flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"merge",checked:u==="auto",onChange:()=>m("auto"),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"QA Approve 后自动合并"})]})]}),t.jsxs("div",{children:[t.jsx("span",{className:ee,children:"Spec 审核"}),t.jsxs("label",{className:"flex items-center gap-2",children:[t.jsx("input",{type:"checkbox",checked:h==="human",onChange:O=>v(O.target.checked?"human":null),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"Spec 需由人类审核"})]}),t.jsx("div",{className:"mt-1 text-xs text-og-500",children:"勾选后,走 SDD 的任务在 QA agent 通过 Spec 后停驻,等你在任务页通过或打回;是否走 SDD 仍由 Dev agent 按任务复杂度判定。"})]}),t.jsxs("div",{children:[t.jsx("span",{className:ee,children:"Review 模式"}),t.jsxs("label",{className:"mb-1 flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"review-mode",checked:d==="",onChange:()=>f(""),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"跟随全局"})]}),t.jsxs("label",{className:"mb-1 flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"review-mode",checked:d==="github",onChange:()=>f("github"),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"GitHub PR"})]}),t.jsxs("label",{className:"flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"review-mode",checked:d==="server",onChange:()=>f("server"),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"Server"})]})]})]})})}const Gt=/^[a-z][a-z0-9-]{1,31}$/,xr=500,Qt={id:"",role:"dev",pairWith:"",mode:"local",host:"",runtime:"",workdir:"",yolo:!0,model:"",addDirs:""};function pr(e){return e.alias?e.alias:`${e.user?`${e.user}@`:""}${e.hostname}${e.port!=null?`:${e.port}`:""}`}function As({open:e,onClose:s,projectId:n,onCreated:i}){var c;const[r,o]=a.useState(Qt),[l,u]=a.useState(null),[m,h]=a.useState([]),[v,d]=a.useState(new Set),[f,p]=a.useState(null),[x,N]=a.useState(!1),[j,k]=a.useState(!1),[R,E]=a.useState(null),[b,y]=a.useState(!1),[w,_]=a.useState(null),[L,T]=a.useState(!1),F=a.useRef(null),O=a.useRef(null),M=a.useRef(0),z=a.useRef(0),{show:X}=ve(),{flagDirty:$}=rt();a.useEffect(()=>{if(!e)return;z.current+=1;const g=z.current;o(Qt),u(null),h([]),d(new Set),p(null),N(!1),k(!1),E(null),M.current+=1,_(null),T(!1),I.config.get().then(S=>{if(g!==z.current)return;const P=S.project.find(J=>J.id===n)??null;u(P),h(S.host??[]);const K=new Set;S.project.forEach(J=>J.agent.forEach(C=>C.forEach(D=>K.add(D.id)))),d(K)}).catch(()=>{})},[e,n]);const Z=()=>{b||s()},q=a.useCallback(()=>{F.current&&F.current.abort();const g=new AbortController;F.current=g,N(!0),_(null);const S=r.mode==="remote"?{hostId:r.host}:{};I.agents.probe(r.mode,S,{signal:g.signal}).then(P=>{g.signal.aborted||(p(P),_(null))}).catch(P=>{g.signal.aborted||(p(null),_(P instanceof Error?P.message:String(P)))}).finally(()=>{F.current===g&&N(!1)})},[r.mode,r.host]);a.useEffect(()=>{if(e&&(p(null),E(null),k(!1),M.current+=1,F.current&&F.current.abort(),!(r.mode==="remote"&&!r.host)))return O.current&&clearTimeout(O.current),O.current=setTimeout(q,xr),()=>{O.current&&clearTimeout(O.current)}},[e,r.mode,r.host,q]),a.useEffect(()=>{e||F.current&&F.current.abort()},[e]),a.useEffect(()=>()=>{F.current&&F.current.abort(),O.current&&clearTimeout(O.current)},[]);const V=()=>{if(j)return;const g=M.current;k(!0),E(null);const S=r.mode==="remote"?{hostId:r.host}:{};I.agents.installTmux(r.mode,S).then(P=>{M.current===g&&(E({ok:P.ok,message:P.message}),k(!1),P.ok&&q())}).catch(P=>{M.current===g&&(E({ok:!1,message:P instanceof Error?P.message:String(P)}),k(!1))})},U=(l==null?void 0:l.agent.filter(g=>g.length===1&&g[0].role==="dev").map(g=>g[0]))??[],Q=U.length>0,se=Gt.test(r.id)&&!v.has(r.id),de=r.mode==="local"||r.mode==="remote"&&r.host!=="",B=r.runtime!==""&&(r.runtime==="claude-code"?!!(f!=null&&f.runtimes["claude-code"].ok):!!(f!=null&&f.runtimes.codex.ok)),ie=!!(f!=null&&f.tmux.ok),re=r.mode==="local"||!!((c=f==null?void 0:f.ssh)!=null&&c.ok),le=r.role==="dev"||r.role==="qa"&&r.pairWith!=="",oe=!b&&se&&de&&le&&B&&ie&&re,me=async g=>{if(g.preventDefault(),!!oe){y(!0),_(null);try{const S=r.addDirs.split(`
2
- `).map(J=>J.trim()).filter(J=>J.length>0),P={id:r.id,role:r.role,runtime:r.runtime,mode:r.mode,...r.mode==="remote"?{host:r.host}:{},...r.workdir?{workdir:r.workdir}:{},yolo:r.yolo,...r.model.trim()?{model:r.model.trim()}:{},...S.length>0?{addDirs:S}:{},...r.role==="qa"?{pairWith:r.pairWith}:{}},K=await I.projects.addAgent(n,P);K.restartRequired&&$(),X({kind:"success",title:`Agent ${K.agent.id} 已添加到 ${n}`}),i(),s()}catch(S){_(S instanceof Error?S.message:String(S))}finally{y(!1)}}},ce=({rt:g})=>{if(r.mode==="remote"&&!r.host)return t.jsx("span",{className:"ml-2 text-xs text-og-400",children:"(请先选择 Host)"});if(x)return t.jsx("span",{className:"ml-2 text-xs text-og-400",children:"…探测中"});if(!f)return t.jsx("span",{className:"ml-2 text-xs text-og-400",children:"?"});const P=f.runtimes[g];return P.ok?t.jsxs("span",{className:"ml-2 text-xs text-og-800",children:["✓ ",P.path??""]}):t.jsxs("span",{className:"ml-2 text-xs text-accent",title:P.message,children:["⨯ ",P.message]})},ue=()=>{var S;if(r.mode==="remote"&&!r.host)return null;if(x&&!j)return t.jsx("div",{className:"text-xs text-og-400",children:"tmux: …探测中"});if(!f)return null;if(f.tmux.ok)return t.jsxs("div",{className:"text-xs text-og-800",children:["tmux: ✓ ",f.tmux.path??""]});const g=r.mode==="local"||!!((S=f.ssh)!=null&&S.ok);return t.jsxs("div",{className:"space-y-1",children:[t.jsxs("div",{className:"text-xs text-accent",children:["tmux: ⨯ ",f.tmux.message,g&&t.jsx("button",{type:"button",onClick:V,className:"ml-2 text-accent underline transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",disabled:j||b,children:j?"安装中…":"一键安装"})]}),j&&t.jsx("div",{className:"text-xs text-og-500",children:"正在安装 tmux,可能需要几分钟,请勿关闭窗口…"}),!j&&R&&t.jsxs("div",{className:`break-all text-xs ${R.ok?"text-og-800":"text-accent"}`,children:[R.ok?"✓ ":"⨯ ",R.message]})]})},A=()=>r.mode!=="remote"||!r.host||!(f!=null&&f.ssh)?null:f.ssh.ok?t.jsxs("div",{className:"text-xs text-og-800",children:["SSH: ✓ ",f.ssh.message]}):t.jsxs("div",{className:"text-xs text-accent",children:["SSH: ⨯ ",f.ssh.message]});return t.jsx(Ne,{open:e,onClose:Z,title:`添加 Agent 到 ${n}`,size:"lg",footer:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:Z,disabled:b,className:"btn-secondary",children:"取消"}),t.jsx("button",{type:"submit",form:"create-agent-form",disabled:!oe,className:"btn-primary",children:b?"添加中…":"添加 Agent"})]}),children:t.jsxs("form",{id:"create-agent-form",onSubmit:me,className:"space-y-3",children:[w&&t.jsx("div",{className:"rounded-md border border-accent/25 bg-accent-soft px-3 py-2 text-sm text-accent",children:w}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"agent-id",children:"Agent ID"}),t.jsx("input",{id:"agent-id",type:"text",value:r.id,onChange:g=>o({...r,id:g.target.value}),className:ae,placeholder:"kk-cc",disabled:b}),r.id&&!Gt.test(r.id)&&t.jsx("div",{className:Xe,children:"小写字母开头,只含 a-z 0-9 -,长度 2-32"}),r.id&&v.has(r.id)&&t.jsx("div",{className:Xe,children:"该 id 已被占用(全局唯一)"})]}),t.jsxs("div",{children:[t.jsx("span",{className:ee,children:"角色"}),t.jsxs("label",{className:"mr-4 inline-flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"role",checked:r.role==="dev",className:Te,onChange:()=>o({...r,role:"dev",pairWith:""}),disabled:b}),t.jsx("span",{className:"text-sm text-og-800",children:"Dev agent"})]}),t.jsxs("label",{className:"inline-flex items-center gap-2",title:Q?"":"请先创建一个 Dev agent",children:[t.jsx("input",{type:"radio",name:"role",checked:r.role==="qa",className:Te,onChange:()=>o({...r,role:"qa"}),disabled:b||!Q}),t.jsx("span",{className:`text-sm ${Q?"text-og-800":"text-og-400"}`,children:"QA agent"})]})]}),r.role==="qa"&&t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"pair-with",children:"配对 Dev agent"}),t.jsxs("select",{id:"pair-with",value:r.pairWith,onChange:g=>o({...r,pairWith:g.target.value}),className:ae,disabled:b,children:[t.jsx("option",{value:"",children:"请选择"}),U.map(g=>t.jsxs("option",{value:g.id,children:[g.id,"(",g.mode,")"]},g.id))]})]}),t.jsxs("div",{children:[t.jsx("span",{className:ee,children:"运行模式"}),t.jsxs("label",{className:"mr-4 inline-flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"mode",checked:r.mode==="local",className:Te,onChange:()=>o({...r,mode:"local",host:""}),disabled:b}),t.jsx("span",{className:"text-sm text-og-800",children:"本机"})]}),t.jsxs("label",{className:"inline-flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"mode",checked:r.mode==="remote",className:Te,onChange:()=>o({...r,mode:"remote"}),disabled:b}),t.jsx("span",{className:"text-sm text-og-800",children:"远程 (SSH)"})]})]}),r.mode==="remote"&&t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host",children:"Host"}),m.length===0?t.jsx("div",{className:"rounded-md border border-og-100 bg-og-50/40 px-3 py-2 text-xs text-og-600",children:"还没有配置 Host。请先在右上角菜单的「Host 管理」中添加。"}):t.jsxs("select",{id:"host",value:r.host,onChange:g=>o({...r,host:g.target.value}),className:ae,disabled:b,children:[t.jsx("option",{value:"",children:"请选择 Host"}),m.map(g=>t.jsx("option",{value:g.id,children:pr(g)},g.id))]}),t.jsx("div",{className:ft,children:"私钥/跳板机仍可在 ~/.ssh/config 配置;端口/密码在「Host 管理」里设置。"})]}),t.jsxs("div",{children:[t.jsxs("div",{className:"mb-1.5 flex items-center justify-between",children:[t.jsx("span",{className:"text-xs font-medium text-og-700",children:"运行时"}),t.jsx("button",{type:"button",onClick:q,className:"text-xs text-accent transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",disabled:b||x||r.mode==="remote"&&!r.host,children:"↻ 重新探测"})]}),t.jsxs("label",{className:"flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"runtime",checked:r.runtime==="claude-code",className:Te,onChange:()=>o({...r,runtime:"claude-code"}),disabled:b||(f?!f.runtimes["claude-code"].ok:!1)}),t.jsx("span",{className:"text-sm text-og-800",children:"Claude Code"}),t.jsx(ce,{rt:"claude-code"})]}),t.jsxs("label",{className:"mt-1 flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"runtime",checked:r.runtime==="codex",className:Te,onChange:()=>o({...r,runtime:"codex"}),disabled:b||(f?!f.runtimes.codex.ok:!1)}),t.jsx("span",{className:"text-sm text-og-800",children:"Codex"}),t.jsx(ce,{rt:"codex"})]}),t.jsx("div",{className:"mt-2",children:t.jsx(ue,{})}),t.jsx("div",{children:t.jsx(A,{})})]}),t.jsxs("div",{children:[t.jsxs("button",{type:"button",onClick:()=>T(g=>!g),"aria-expanded":L,"aria-controls":L?"advanced-options":void 0,className:"flex w-full items-center justify-between rounded-md px-1 py-1.5 text-left text-xs font-medium text-og-700 transition-colors hover:bg-og-50",children:[t.jsx("span",{children:"高级选项"}),t.jsx("span",{className:"text-og-400",children:L?"收起":"展开"})]}),L&&t.jsxs("div",{id:"advanced-options",className:"mt-3 space-y-3",children:[t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"workdir",children:"Workdir(可选)"}),t.jsx("input",{id:"workdir",type:"text",value:r.workdir,onChange:g=>o({...r,workdir:g.target.value}),className:ae,placeholder:"留空时自动 clone 到 ~/.baxian/repos/<owner>/<repo>",disabled:b})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"model",children:"Model(可选)"}),t.jsx("input",{id:"model",type:"text",value:r.model,onChange:g=>o({...r,model:g.target.value}),className:ae,placeholder:r.runtime==="codex"?"例: o3 / gpt-4o(留空走 default)":"例: sonnet / opus / claude-sonnet-4-6(留空走 default)",disabled:b}),t.jsx("div",{className:ft,children:"透传到 launch 命令的 --model 参数;留空跟随 CLI 默认。"})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"addDirs",children:"Additional Dirs(可选)"}),t.jsx("textarea",{id:"addDirs",value:r.addDirs,onChange:g=>o({...r,addDirs:g.target.value}),className:`${ae} font-mono text-xs`,rows:3,placeholder:`每行一个绝对路径,例:
1
+ var Ks=Object.defineProperty;var Vs=(e,s,n)=>s in e?Ks(e,s,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[s]=n;var te=(e,s,n)=>Vs(e,typeof s!="symbol"?s+"":s,n);import{r as a,j as t,a as Js,c as Ys}from"./react-BFCkCmbU.js";import{x as Xs,a as Zs}from"./xterm-D5X2JljJ.js";import{L as Be,u as pe,a as He,b as ms,B as en,R as tn,c as $e}from"./router-BgSDZqI0.js";(function(){const s=document.createElement("link").relList;if(s&&s.supports&&s.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))i(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const l of o.addedNodes)l.tagName==="LINK"&&l.rel==="modulepreload"&&i(l)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function i(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();function he({className:e,...s}){return t.jsx("button",{type:"button",role:"menuitem",className:`block w-full px-3 py-1.5 text-left text-sm text-og-1000 hover:bg-og-50 disabled:opacity-50 disabled:cursor-not-allowed ${e??""}`,...s})}function St({ariaLabel:e,children:s,placement:n="down",autoFocusFirstItem:i=!1,menuClassName:r="min-w-[140px]",className:o,disabled:l=!1,triggerRef:u}){const[m,h]=a.useState(!1),v=a.useRef(null),d=a.useRef(null),f=a.useId(),p=a.useId();return a.useEffect(()=>{if(!m)return;const x=j=>{var R,E;const k=j.target;k&&((R=d.current)!=null&&R.contains(k)||(E=v.current)!=null&&E.contains(k)||h(!1))},N=j=>{var k;j.key==="Escape"&&(h(!1),(k=v.current)==null||k.focus())};return document.addEventListener("mousedown",x),document.addEventListener("keydown",N),()=>{document.removeEventListener("mousedown",x),document.removeEventListener("keydown",N)}},[m]),a.useEffect(()=>{var N;if(!m||!i)return;const x=(N=d.current)==null?void 0:N.querySelector('[role="menuitem"]:not([disabled])');x==null||x.focus()},[m,i]),t.jsxs("div",{className:`relative ${o??""}`,children:[t.jsx("button",{ref:x=>{v.current=x,u&&(u.current=x)},id:p,type:"button",onClick:()=>h(x=>!x),disabled:l,"aria-haspopup":"menu","aria-expanded":m,"aria-controls":m?f:void 0,"aria-label":e,className:"flex h-8 w-8 items-center justify-center rounded text-og-500 transition-colors hover:bg-og-50 hover:text-og-1000 disabled:cursor-not-allowed disabled:opacity-50",children:t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[t.jsx("circle",{cx:"12",cy:"12",r:"1"}),t.jsx("circle",{cx:"12",cy:"5",r:"1"}),t.jsx("circle",{cx:"12",cy:"19",r:"1"})]})}),m&&t.jsx("div",{ref:d,id:f,role:"menu","aria-labelledby":p,className:`absolute right-0 z-10 rounded-md border border-hairline bg-surface py-1 shadow-md ${n==="up"?"bottom-full mb-1":"top-full mt-1"} ${r}`,children:s(()=>{var x;h(!1),(x=v.current)==null||x.focus()})})]})}const sn={"claude-code":"Claude Code",codex:"Codex"};function fs(e){return e?sn[e]:null}function hs(e,s){const n=fs(s);return n?`${e} (${n})`:e}const xs=new Set(["merged","done","failed","cancelled"]),ps=new Set(["in_progress","review","fixing","spec-ready","approved","merge-ready","ready","max_rounds"]),at=20,nt=5*1024*1024,qe=4,gs=600*1e3,nn=1536,rn=1872,bs=192,vs=208,De="/api",kt="baxian.token",Je="baxian:unauthorized";function Et(){try{return typeof localStorage<"u"?localStorage.getItem(kt):null}catch{return null}}function an(e){try{localStorage.setItem(kt,e)}catch(s){console.error("Failed to save auth token to localStorage",s)}}function on(){try{localStorage.removeItem(kt)}catch(e){console.error("Failed to clear auth token from localStorage",e)}}function Ee(e){const s=Et();return{...e??{},...s?{Authorization:`Bearer ${s}`}:{}}}class Pe extends Error{constructor(s,n,i){super(n),this.status=s,this.details=i,this.name="ApiError"}}async function Re(e){const s=await e.text();let n=s||`HTTP ${e.status}`,i;try{const r=JSON.parse(s);typeof r.error=="string"&&(n=r.error),Array.isArray(r.details)&&(i=r.details)}catch{}throw e.status===401&&typeof window<"u"&&window.dispatchEvent(new CustomEvent(Je)),new Pe(e.status,n,i)}async function xe(e){const s=await fetch(`${De}${e}`,{headers:Ee()});return s.ok||await Re(s),s.json()}async function cn(){const e=await fetch("/health");return e.ok||await Re(e),e.json()}async function ne(e,s,n){const i=s!==void 0,r=await fetch(`${De}${e}`,{method:"POST",headers:i?Ee({"Content-Type":"application/json"}):Ee(),body:i?JSON.stringify(s):void 0,signal:n==null?void 0:n.signal});return r.ok||await Re(r),r.json()}async function Ht(e,s,n){const i=await fetch(`${De}${e}`,{method:"PATCH",headers:Ee({"Content-Type":"application/json"}),body:s?JSON.stringify(s):void 0,signal:n==null?void 0:n.signal});if(i.ok||await Re(i),i.status===204)return;const r=await i.text();if(r)return JSON.parse(r)}async function ln(e,s){const n=await fetch(`${De}${e}`,{method:"PUT",headers:Ee({"Content-Type":"application/json"}),body:JSON.stringify(s??null)});if(n.ok||await Re(n),n.status===204)return;const i=await n.text();if(i)return JSON.parse(i)}async function Le(e){const s=await fetch(`${De}${e}`,{method:"DELETE",headers:Ee()});if(s.ok||await Re(s),s.status===204)return;const n=await s.text();if(n)return JSON.parse(n)}const W=encodeURIComponent;function bt(e){return new Promise((s,n)=>{const i=new FileReader;i.onerror=()=>n(i.error??new Error("file read failed")),i.onload=()=>{const r=i.result;if(typeof r!="string"){n(new Error("unexpected FileReader result"));return}const o=r.indexOf(",");s(o>=0?r.slice(o+1):r)},i.readAsDataURL(e)})}const I={agents:{list:()=>xe("/agents"),get:e=>xe(`/agents/${W(e)}`),stop:e=>Le(`/agents/${W(e)}/session`),compact:e=>ne(`/agents/${W(e)}/compact`),clear:e=>ne(`/agents/${W(e)}/clear`),probe:(e,s={},n)=>ne("/agents/probe",{mode:e,host:s.host,hostId:s.hostId},n),installTmux:(e,s={})=>ne("/agents/install-tmux",{mode:e,host:s.host,hostId:s.hostId}),uploadImage:async(e,s)=>ne(`/agents/${W(e)}/images`,{dataBase64:await bt(s)}),setPet:(e,s)=>ln(`/agents/${W(e)}/pet`,{petId:s})},pets:{list:()=>xe("/pets"),create:async(e,s)=>ne("/pets",{petJson:e,spritesheetBase64:await bt(s)}),remove:e=>Le(`/pets/${W(e)}`),fetchSpritesheet:async e=>{const s=await fetch(`${De}/pets/${W(e)}/spritesheet`,{headers:Ee()});return s.ok||await Re(s),s.blob()}},tasks:{list:async e=>{const s=new Map;for(const n of["active","pending"]){let i=0;for(;;){const r=await I.tasks.page(e,{category:n,offset:i});for(const o of r.tasks)s.set(o.id,o);if(!r.hasMore||r.tasks.length===0)break;i=r.nextOffset}}return[...s.values()]},page:(e,s={})=>{const n=[`projectId=${W(e)}`];return s.category&&n.push(`category=${s.category}`),n.push(`offset=${s.offset??0}`),xe(`/tasks?${n.join("&")}`)},get:e=>xe(`/tasks/${W(e)}`),create:e=>ne("/tasks",e),update:(e,s)=>Ht(`/tasks/${W(e)}`,s),retry:e=>ne(`/tasks/${W(e)}/retry`),review:e=>ne(`/tasks/${W(e)}/review`),complete:e=>ne(`/tasks/${W(e)}/complete`),continue:e=>ne(`/tasks/${W(e)}/continue`),spec:(e,s)=>ne(`/tasks/${W(e)}/spec`,s),reviews:e=>xe(`/tasks/${W(e)}/reviews`),githubReview:e=>xe(`/tasks/${W(e)}/github-review`),dispatch:(e,s)=>ne(`/tasks/${W(e)}/dispatch`,s)},projects:{list:()=>xe("/projects"),get:e=>xe(`/projects/${W(e)}`),create:e=>ne("/projects",e),delete:e=>Le(`/projects/${W(e)}`),addAgent:(e,s)=>ne(`/projects/${W(e)}/agents`,s),deleteAgent:(e,s)=>Le(`/projects/${W(e)}/agents/${W(s)}`),resumeAgent:(e,s)=>ne(`/projects/${W(e)}/agents/${W(s)}/resume`),restartRepl:(e,s)=>ne(`/projects/${W(e)}/agents/${W(s)}/restart-repl`),retryAgent:(e,s)=>ne(`/projects/${W(e)}/agents/${W(s)}/retry`),bootstrap:e=>ne(`/projects/${W(e)}/bootstrap`)},hosts:{list:()=>xe("/hosts"),create:e=>ne("/hosts",e),update:(e,s)=>Ht(`/hosts/${W(e)}`,s),delete:e=>Le(`/hosts/${W(e)}`),check:e=>ne("/hosts/check",e)},config:{get:()=>xe("/config")},health:{get:cn},server:{restart:()=>ne("/restart")}};function Rt(e){return{xmlns:"http://www.w3.org/2000/svg",width:16,height:16,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,...e}}function dn(e){return t.jsxs("svg",{...Rt(e),children:[t.jsx("path",{d:"M21.801 10A10 10 0 1 1 17 3.335"}),t.jsx("path",{d:"m9 11 3 3L22 4"})]})}function un(e){return t.jsxs("svg",{...Rt(e),children:[t.jsx("path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"}),t.jsx("path",{d:"M12 9v4"}),t.jsx("path",{d:"M12 17h.01"})]})}function mn(e){return t.jsxs("svg",{...Rt(e),children:[t.jsx("circle",{cx:"12",cy:"12",r:"10"}),t.jsx("path",{d:"m15 9-6 6"}),t.jsx("path",{d:"m9 9 6 6"})]})}const js=a.createContext(null),fn={success:"border-hairline bg-surface text-og-800",warn:"border-accent/25 bg-accent-soft text-accent",error:"border-accent/25 bg-accent-soft text-accent"},hn={success:dn,warn:un,error:mn};let xn=1;function pn({children:e}){const[s,n]=a.useState([]),i=a.useRef(new Map),r=a.useRef(new Map);a.useEffect(()=>{const d=i.current,f=r.current;return()=>{for(const p of d.values())clearTimeout(p);d.clear(),f.clear()}},[]);const o=a.useCallback(d=>{const f=i.current.get(d);f&&clearTimeout(f),i.current.delete(d)},[]),l=a.useCallback(d=>{o(d),r.current.delete(d),n(f=>f.filter(p=>p.id!==d))},[o]),u=a.useCallback((d,f)=>{o(d),i.current.set(d,setTimeout(()=>l(d),f))},[o,l]),m=a.useCallback((d,f)=>{const p=r.current.get(d)??new Set;p.add(f),r.current.set(d,p),o(d)},[o]),h=a.useCallback((d,f,p)=>{const x=r.current.get(d);x==null||x.delete(f),(!x||x.size===0)&&u(d,p)},[u]),v=a.useCallback(d=>{const f=xn++,p=d.durationMs??3e3;n(x=>[...x,{...d,id:f,durationMs:p}]),u(f,p)},[u]);return t.jsxs(js.Provider,{value:{show:v},children:[e,t.jsx("div",{className:"pointer-events-none fixed inset-x-4 top-4 z-[60] flex flex-col items-end gap-2",children:s.map(d=>t.jsx("div",{className:`pointer-events-auto w-full max-w-xs rounded-lg border px-4 py-3 shadow-toast ${fn[d.kind]}`,role:"status",onMouseEnter:()=>m(d.id,"hover"),onMouseLeave:()=>h(d.id,"hover",d.durationMs),onFocus:()=>m(d.id,"focus"),onBlur:f=>{f.currentTarget.contains(f.relatedTarget)||h(d.id,"focus",d.durationMs)},children:t.jsxs("div",{className:"flex items-start gap-2",children:[(()=>{const f=hn[d.kind];return t.jsx(f,{className:"mt-0.5 shrink-0",width:14,height:14})})(),t.jsxs("div",{className:"flex-1",children:[t.jsx("div",{className:"text-sm font-semibold",children:d.title}),d.body&&t.jsx("div",{className:"mt-1 whitespace-pre-line text-xs text-og-700",children:d.body})]}),t.jsx("button",{type:"button",onClick:()=>l(d.id),className:"text-current opacity-50 transition-opacity hover:opacity-100","aria-label":"关闭通知",children:"✕"})]})},d.id))})]})}function ve(){const e=a.useContext(js);if(!e)throw new Error("useToast must be inside <ToastProvider>");return e}const gn={sm:"max-w-md",md:"max-w-lg",lg:"max-w-2xl"},Ut='input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])',ke=[];function Ne({open:e,onClose:s,title:n,titleContent:i,children:r,footer:o,size:l="md",dismissOnBackdrop:u=!0}){const m=a.useRef(null),h=a.useRef();h.current||(h.current=Symbol("modal"));const v=a.useRef(null),d=a.useRef(!1),f=a.useRef(s);return a.useEffect(()=>{f.current=s},[s]),a.useEffect(()=>{if(!e)return;const p=h.current;ke.push(p);const x=()=>ke[ke.length-1]===p;v.current=document.activeElement;const N=R=>{if(!x())return;if(R.key==="Escape"){f.current();return}if(R.key!=="Tab")return;const E=m.current;if(!E)return;const b=Array.from(E.querySelectorAll(Ut)).filter(L=>L.offsetParent!==null||L===document.activeElement);if(b.length===0){R.preventDefault();return}const y=b[0],w=b[b.length-1],_=document.activeElement;R.shiftKey&&(_===y||!E.contains(_))?(R.preventDefault(),w.focus()):!R.shiftKey&&(_===w||!E.contains(_))&&(R.preventDefault(),y.focus())};document.addEventListener("keydown",N);const j=document.body.style.overflow;document.body.style.overflow="hidden";const k=m.current;if(k){const R=k.querySelector(Ut);R==null||R.focus()}return()=>{var E,b;const R=ke.indexOf(p);R>=0&&ke.splice(R,1),document.removeEventListener("keydown",N),document.body.style.overflow=j,(b=(E=v.current)==null?void 0:E.focus)==null||b.call(E)}},[e]),e?t.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-og-1000/45 px-3 sm:px-4",onMouseDown:u?p=>{d.current=p.target===p.currentTarget&&ke[ke.length-1]===h.current}:void 0,onClick:u?p=>{p.target===p.currentTarget&&d.current&&f.current()}:void 0,role:"presentation",children:t.jsxs("div",{ref:m,className:`flex w-full ${gn[l]} max-h-[90dvh] flex-col overflow-hidden rounded-lg border border-og-100 bg-surface shadow-modal`,onClick:p=>p.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":n,children:[t.jsxs("div",{className:"flex shrink-0 items-center justify-between gap-3 border-b border-hairline px-5 py-3",children:[t.jsx("h2",{title:n,className:"min-w-0 truncate font-display text-sm font-semibold tracking-tight text-og-1000",children:i??n}),t.jsx("button",{type:"button",onClick:()=>f.current(),className:"-mr-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-og-400 transition-colors hover:bg-og-50 hover:text-og-800","aria-label":"关闭",children:"✕"})]}),t.jsx("div",{className:"min-h-0 flex-1 overflow-auto px-5 py-4",children:r}),o&&t.jsx("div",{className:"flex shrink-0 flex-wrap items-center justify-end gap-2 border-t border-hairline px-5 py-3",children:o})]})}):null}const ws=a.createContext(null);function bn({children:e}){const[s,n]=a.useState(null),i=a.useRef(null),r=a.useCallback(l=>new Promise(u=>{var h;(h=i.current)==null||h.resolve(!1);const m={...l,resolve:u};i.current=m,n(m)}),[]),o=a.useCallback(l=>{const u=i.current;u&&(i.current=null,n(null),u.resolve(l))},[]);return t.jsxs(ws.Provider,{value:r,children:[e,s&&t.jsx(Ne,{open:!0,title:s.title,onClose:()=>o(!1),size:"sm",footer:t.jsxs("div",{className:"flex justify-end gap-2",children:[t.jsx("button",{type:"button",onClick:()=>o(!1),className:"btn-secondary",children:s.cancelLabel??"取消"}),t.jsx("button",{type:"button",onClick:()=>o(!0),className:"btn-primary",children:s.confirmLabel??"确认"})]}),children:s.body?t.jsx("p",{className:"whitespace-pre-line text-sm text-og-700",children:s.body}):null})]})}function Ct(){const e=a.useContext(ws);if(!e)throw new Error("useConfirm must be inside <ConfirmProvider>");return e}const Ye="baxian.pendingRestart",vn=500,jn=3e4,ys=a.createContext(null);function wn(){try{const e=localStorage.getItem(Ye);if(!e)return{count:0,baselineStartedAt:null};const s=JSON.parse(e);return{count:typeof s.count=="number"?s.count:0,baselineStartedAt:typeof s.baselineStartedAt=="string"?s.baselineStartedAt:null}}catch{return{count:0,baselineStartedAt:null}}}function yn(e){try{e.count<=0?localStorage.removeItem(Ye):localStorage.setItem(Ye,JSON.stringify(e))}catch{}}function Nn({children:e}){const s=wn(),[n,i]=a.useState(s.count),[r,o]=a.useState(s.baselineStartedAt),[l,u]=a.useState(s.count>0?"pending":"idle"),[m,h]=a.useState(),v=a.useRef(s.count),d=a.useRef(s.count>0?"pending":"idle"),f=a.useRef(0),p=a.useCallback(E=>{v.current=E,i(E)},[]),x=a.useCallback(E=>{i(b=>{const y=E(b);return v.current=y,y})},[]),N=a.useCallback(E=>{d.current=E,u(E)},[]);a.useEffect(()=>{yn({count:n,baselineStartedAt:r})},[n,r]),a.useEffect(()=>{let E=!1;(async()=>{try{const y=await I.health.get();if(E)return;o(w=>w!==null&&y.startedAt!==w?(p(0),N("idle"),null):w)}catch{}})();const b=y=>{if(y.key===Ye){if(y.newValue===null){if(d.current==="restarting"&&f.current>0){p(f.current),o(null);return}p(0),o(null),d.current!=="restarting"&&N("idle");return}try{const w=JSON.parse(y.newValue);typeof w.count=="number"&&(d.current==="restarting"&&w.count>v.current&&(f.current+=w.count-v.current),p(w.count),d.current!=="restarting"&&N(w.count>0?"pending":"idle")),typeof w.baselineStartedAt=="string"?o(w.baselineStartedAt):w.baselineStartedAt===null&&o(null)}catch{}}};return window.addEventListener("storage",b),()=>{E=!0,window.removeEventListener("storage",b)}},[p,N]);const j=a.useRef(!1),k=a.useCallback(()=>{x(E=>E+1),d.current==="restarting"?f.current+=1:N("pending"),o(E=>(E!==null||j.current||(j.current=!0,(async()=>{try{const b=await I.health.get();o(y=>y??b.startedAt)}catch{}finally{j.current=!1}})()),E))},[N,x]),R=a.useCallback(async()=>{f.current=0,h(void 0),N("restarting");let E;try{E=(await I.health.get()).startedAt}catch(y){N("failed"),h(`获取重启前 startedAt 失败: ${y instanceof Error?y.message:String(y)}`);return}try{await I.server.restart()}catch(y){if(!(y instanceof Pe&&y.status===409)){N("failed"),h(`触发重启失败: ${y instanceof Error?y.message:String(y)}`);return}}const b=Date.now();for(;Date.now()-b<jn;){await new Promise(y=>setTimeout(y,vn));try{const y=await I.health.get();if(y.startedAt!==E){const w=f.current;f.current=0,o(w>0?y.startedAt:null),p(w),N(w>0?"pending":"idle");return}}catch{}}N("failed"),h("重启超时(30s 未恢复)。请检查日志或手动 baxian start -c <path>")},[p,N]);return t.jsx(ys.Provider,{value:{phase:l,count:n,error:m,flagDirty:k,triggerRestart:R},children:e})}function rt(){const e=a.useContext(ys);if(!e)throw new Error("usePendingRestart must be used inside PendingRestartProvider");return e}const Sn=[500,1e3,2e3,4e3,8e3,15e3,3e4];class Ns{constructor(s){te(this,"attempts",0);te(this,"timer",null);te(this,"delaysMs");this.opts=s,this.delaysMs=s.delaysMs??Sn}schedule(){if(this.timer||!this.shouldReconnect())return;const s=this.delaysMs[Math.min(this.attempts,this.delaysMs.length-1)];this.attempts+=1,this.timer=setTimeout(()=>{this.timer=null,this.shouldReconnect()&&this.opts.reconnect()},s)}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null)}reset(){this.attempts=0}shouldReconnect(){return this.opts.shouldReconnect?this.opts.shouldReconnect():!0}}let qt=0;function kn(){qt++;const e=Math.random().toString(36).slice(2,8);return`sub-${Date.now().toString(36)}-${qt}-${e}`}function En(e){return Array.from(new TextEncoder().encode(e)).map(s=>s.toString(16).padStart(2,"0")).join("")}function Rn(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/stream`}const Cn=(e,s)=>s&&s.length>0?new WebSocket(e,s):new WebSocket(e);class An{constructor(s={}){te(this,"wsUrl");te(this,"wsFactory");te(this,"tokenProvider");te(this,"ws",null);te(this,"subs",new Map);te(this,"snapshotPending",new Set);te(this,"preSubscribeQueue",new Map);te(this,"outbox",[]);te(this,"reconnectScheduler");te(this,"explicitlyClosed",!1);this.wsUrl=s.wsUrl??Rn(),this.wsFactory=s.wsFactory??Cn,this.tokenProvider=s.tokenProvider??Et,this.reconnectScheduler=new Ns({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.subs.size>0})}subscribe(s){const n=kn(),i={subscriberId:n,agentId:s.agentId,mode:s.mode,onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone};return this.subs.set(n,i),this.snapshotPending.add(n),this.preSubscribeQueue.set(n,[]),this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",subscriberId:n,agentId:s.agentId,mode:s.mode}),{subscriberId:n,unsubscribe:()=>this.unsubscribe(n)}}send(s,n){if(this.subs.has(s)){if(this.snapshotPending.has(s)){this.outbox.push({op:"input",subscriberId:s,data:n});return}this.wsSendOrQueue({op:"input",subscriberId:s,data:n})}}resize(s,n,i){const r=this.subs.get(s);r&&(r.lastSize={cols:n,rows:i},!this.snapshotPending.has(s)&&this.wsSendOrQueue({op:"resize",subscriberId:s,cols:n,rows:i}))}ping(){this.wsSendOrQueue({op:"ping"})}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.subs.clear(),this.snapshotPending.clear(),this.preSubscribeQueue.clear(),this.outbox=[]}unsubscribe(s){this.subs.has(s)&&(this.subs.delete(s),this.snapshotPending.delete(s),this.preSubscribeQueue.delete(s),this.wsSendOrQueue({op:"unsubscribe",subscriberId:s}),this.subs.size===0&&this.teardownSocket())}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const s=this.tokenProvider(),n=s?[`baxian.token.${En(s)}`]:void 0;let i;try{i=this.wsFactory(this.wsUrl,n)}catch(r){console.warn("[pane-stream] WebSocket constructor threw:",r),this.scheduleReconnect();return}this.ws=i,i.onopen=()=>{if(i!==this.ws)return;this.reconnectScheduler.reset();for(const o of this.subs.values()){this.snapshotPending.add(o.subscriberId),this.preSubscribeQueue.set(o.subscriberId,[]),o.snapshotSeq=void 0;try{i.send(JSON.stringify({op:"subscribe",subscriberId:o.subscriberId,agentId:o.agentId,mode:o.mode}))}catch(l){console.warn("[pane-stream] resubscribe send failed:",l)}}const r=this.outbox;this.outbox=[];for(const o of r)if(o.op!=="subscribe"){if("subscriberId"in o&&o.subscriberId){if(!this.subs.has(o.subscriberId))continue;if(this.snapshotPending.has(o.subscriberId)&&o.op!=="unsubscribe"){this.outbox.push(o);continue}}try{i.send(JSON.stringify(o))}catch(l){console.warn("[pane-stream] outbox flush failed:",l)}}},i.onmessage=r=>{if(i!==this.ws)return;let o;try{const l=typeof r.data=="string"?r.data:String(r.data);o=JSON.parse(l)}catch{return}this.handleMessage(o)},i.onclose=()=>{i===this.ws&&(this.ws=null,!this.explicitlyClosed&&this.subs.size!==0&&this.scheduleReconnect())},i.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}wsSendOrQueue(s){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(s));return}catch(n){console.warn("[pane-stream] send failed, will queue:",n)}this.outbox.push(s)}handleMessage(s){var n,i;switch(s.type){case"snapshot":this.handleSnapshot(s);break;case"subscribed":this.handleSubscribed(s);break;case"data":this.dispatch(s);break;case"session_gone":for(const r of[...this.subs.values()])r.agentId===s.agentId&&((n=r.onSessionGone)==null||n.call(r));break;case"error":{if(s.subscriberId){const r=this.subs.get(s.subscriberId);(i=r==null?void 0:r.onError)==null||i.call(r,{code:s.code,message:s.message})}else console.warn("[pane-stream] connection-level error:",s.code,s.message);break}}}handleSnapshot(s){const n=this.subs.get(s.subscriberId);n&&n.onSnapshot({cols:s.cols,rows:s.rows,data:s.data})}handleSubscribed(s){const n=this.subs.get(s.subscriberId);if(!n)return;n.snapshotSeq=s.snapshotSeq,n.lastSize||(n.lastSize={cols:s.cols,rows:s.rows}),this.snapshotPending.delete(s.subscriberId);const i=this.preSubscribeQueue.get(s.subscriberId);if(this.preSubscribeQueue.delete(s.subscriberId),i)for(const r of i)r.seq>s.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(s.subscriberId)}flushOutboxForSub(s){if(this.outbox.length===0||!this.ws||this.ws.readyState!==WebSocket.OPEN)return;const n=[];for(const i of this.outbox)if("subscriberId"in i&&i.subscriberId===s&&i.op!=="subscribe")try{this.ws.send(JSON.stringify(i))}catch(r){console.warn("[pane-stream] flushOutboxForSub send failed:",r)}else n.push(i);this.outbox=n}dispatch(s){for(const n of this.subs.values())if(n.agentId===s.agentId)if(this.snapshotPending.has(n.subscriberId)){const i=this.preSubscribeQueue.get(n.subscriberId);i&&i.push({seq:s.seq,data:s.data})}else n.onData(s.data)}}let ot=null;function ct(){return ot||(ot=new An),ot}function $n(e){const{agentId:s,mode:n}=e,i=a.useRef(null),r=a.useRef({onSnapshot:e.onSnapshot,onData:e.onData,onError:e.onError,onSessionGone:e.onSessionGone});r.current={onSnapshot:e.onSnapshot,onData:e.onData,onError:e.onError,onSessionGone:e.onSessionGone},a.useEffect(()=>{const m=ct().subscribe({agentId:s,mode:n,onSnapshot:h=>r.current.onSnapshot(h),onData:h=>r.current.onData(h),onError:h=>{var v,d;return(d=(v=r.current).onError)==null?void 0:d.call(v,h)},onSessionGone:()=>{var h,v;return(v=(h=r.current).onSessionGone)==null?void 0:v.call(h)}});return i.current=m.subscriberId,()=>{i.current=null,m.unsubscribe()}},[s,n]);const o=a.useCallback(u=>{const m=i.current;m&&ct().send(m,u)},[]),l=a.useCallback((u,m)=>{const h=i.current;h&&ct().resize(h,u,m)},[]);return{send:o,resize:l}}const Tn=[{key:"up",label:"上",path:"M12 5l-6 6m6-6l6 6m-6-6v14"},{key:"down",label:"下",path:"M12 19l6-6m-6 6l-6-6m6 6V5"},{key:"left",label:"左",path:"M5 12l6-6m-6 6l6 6m-6-6h14"},{key:"right",label:"右",path:"M19 12l-6-6m6 6l-6 6m6-6H5"}],We=Object.fromEntries(Tn.map(e=>[e.key,e]));function ze({arrow:e,onPress:s}){return t.jsx("button",{type:"button","aria-label":`方向键 ${e.label}`,"data-arrow":e.key,onMouseDown:n=>n.preventDefault(),onClick:()=>s(e.key),className:"flex h-8 w-8 items-center justify-center rounded border border-hairline bg-surface text-og-700 transition-colors hover:bg-og-50 hover:text-og-1000 active:bg-og-200",children:t.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:t.jsx("path",{d:e.path})})})}function In({onKey:e,onEscape:s,className:n}){return t.jsxs("div",{role:"group","aria-label":"终端按键",className:n??"flex flex-none items-center justify-center gap-1 border-t border-hairline bg-page px-3 py-2",children:[s&&t.jsx("button",{type:"button","aria-label":"Esc 键","data-key":"escape",onMouseDown:i=>i.preventDefault(),onClick:s,className:"mr-2 flex h-8 items-center justify-center rounded border border-hairline bg-surface px-2.5 font-mono text-xs text-og-700 transition-colors hover:bg-og-50 hover:text-og-1000 active:bg-og-200",children:"ESC"}),t.jsx(ze,{arrow:We.left,onPress:e}),t.jsx(ze,{arrow:We.up,onPress:e}),t.jsx(ze,{arrow:We.down,onPress:e}),t.jsx(ze,{arrow:We.right,onPress:e})]})}const Pn=Math.floor(nt/1024/1024);function Dn({agentId:e,className:s}){const n=a.useRef(null),[i,r]=a.useState(!1),{show:o}=ve(),l=async u=>{var h;const m=(h=u.target.files)==null?void 0:h[0];if(u.target.value="",!!m){if(m.size>nt){o({kind:"error",title:"图片过大",body:`单张图片不能超过 ${Pn} MiB`});return}r(!0);try{await I.agents.uploadImage(e,m),o({kind:"success",title:"图片已插入",body:"路径已粘贴到终端输入,补充说明后回车"})}catch(v){const d=v instanceof Pe||v instanceof Error?v.message:String(v);o({kind:"error",title:"图片上传失败",body:d})}finally{r(!1)}}};return t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button","aria-label":"上传图片",disabled:i,onMouseDown:u=>u.preventDefault(),onClick:()=>{var u;return(u=n.current)==null?void 0:u.click()},className:s??"flex h-8 w-8 items-center justify-center rounded border border-hairline bg-surface text-og-700 transition-colors hover:bg-og-50 hover:text-og-1000 active:bg-og-200 disabled:cursor-not-allowed disabled:opacity-50",children:t.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[t.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",ry:"2"}),t.jsx("circle",{cx:"9",cy:"9",r:"2"}),t.jsx("path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"})]})}),t.jsx("input",{ref:n,type:"file",accept:"image/*",className:"hidden",onChange:l})]})}const Ln={up:"A",down:"B",right:"C",left:"D"};function Mn(e,s){return(s?"\x1BO":"\x1B[")+Ln[e]}const Wt=18,_n=250,On=256*1024,zt="#fdfdfd",Fn='ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',Bn={background:zt,foreground:"#474c55",cursor:"#1348dc",cursorAccent:zt,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"},Hn=/\x1b\[(?:\?[\d;]*c|>[\d;]*c|\??\d+;\d+R|\d+n)/g;function Un(e){return e.replace(Hn,"")}const qn=1024*1024;function Wn(e){const s=e.indexOf(";");if(s===-1)return null;const n=e.slice(s+1);if(n.length===0||n==="?"||n.length>qn)return null;try{const i=atob(n),r=new Uint8Array(i.length);for(let o=0;o<i.length;o++)r[o]=i.charCodeAt(o);return new TextDecoder().decode(r)}catch{return null}}function _e({agentId:e,mode:s,interactive:n=!1,maxLines:i,className:r,autoFocus:o=!0,deferFullUntilFocus:l=!1,arrowKeys:u=!1}){const m=a.useRef(null),h=a.useRef(null),v=a.useRef(null),d=a.useRef(null),f=a.useRef(!1),p=a.useRef(""),x=a.useRef([]),N=a.useRef(0),j=a.useRef(null),k=a.useRef(null),R=a.useRef(null),E=a.useRef(Promise.resolve()),b=a.useRef(0),[y,w]=a.useState(null),[_,L]=a.useState(!1),T=`${e}\0${s}\0${l?"1":"0"}`,[F,O]=a.useState({key:T,active:!1}),M=F.key===T&&F.active,z=s==="full"&&l,X=z&&!M?"preview":s,$=n&&X==="full",Z=(c,g)=>g.length===0?Promise.resolve():new Promise(S=>{try{c.write(g,()=>S())}catch(P){console.warn("[pane-terminal] write failed:",P),S()}}),q=X==="preview",V=()=>{if(!q)return;const c=m.current,g=h.current;if(!c||!g||c.clientHeight<=0)return;const P=(g.buffer.active.cursorY+1)*Wt;c.scrollTop=Math.max(0,P-c.clientHeight)},U=()=>{if(!q||R.current!==null)return;let c=!1;const g=requestAnimationFrame(()=>{c=!0,R.current=null,V()});c||(R.current=g)},Q=(c,g)=>{E.current=E.current.then(async()=>{const S=h.current;if(!(!S||g!==b.current))try{await c(S),$&&S.scrollToBottom(),U()}catch(P){console.warn("[pane-terminal] terminal task failed:",P)}}).catch(S=>{console.warn("[pane-terminal] write chain failed:",S)})},se=(c,g)=>{Q(S=>Z(S,c),g)},de=()=>{j.current!==null&&(cancelAnimationFrame(j.current),j.current=null),k.current!==null&&(clearTimeout(k.current),k.current=null)},B=()=>{de(),x.current=[],N.current=0},ie=()=>{de();const c=x.current;c.length!==0&&(x.current=[],N.current=0,se(c.join(""),b.current))},re=c=>{if(c.length!==0){if(x.current.push(c),N.current+=c.length,N.current>=On){ie();return}j.current===null&&(j.current=requestAnimationFrame(ie)),k.current===null&&(k.current=setTimeout(ie,_n))}},{send:le,resize:oe}=$n({agentId:e,mode:X,onSnapshot:({cols:c,rows:g,data:S})=>{if(h.current)try{const K=b.current+1;b.current=K,B(),Q(async J=>{var C;J.reset(),$?((C=d.current)==null||C.call(d),await Z(J,S)):(c>0&&g>0&&J.resize(c,g),await Z(J,S))},K)}catch(K){console.warn("[pane-terminal] snapshot write failed:",K)}},onData:c=>{re(c)},onError:c=>w(`${c.code}: ${c.message}`),onSessionGone:()=>L(!0)});a.useEffect(()=>{w(null),L(!1)},[e,X]),a.useEffect(()=>{p.current=""},[T]),a.useEffect(()=>{if(X!=="full")return;const c=p.current;c.length!==0&&(p.current="",le(c))},[le,X]);const me=a.useCallback(()=>{!n||!z||M||(f.current=!0,O({key:T,active:!0}))},[T,M,n,z]),ce=a.useCallback(c=>{const g=Un(c);if(g.length!==0){if(z&&(!M||p.current.length>0)){p.current+=g,me();return}le(g)}},[me,M,le,z]);a.useEffect(()=>{const c=m.current;if(!c)return;let g=!1;const S=new Xs.Terminal({cursorBlink:n,disableStdin:!n,theme:Bn,fontFamily:Fn,fontSize:13,lineHeight:1.4,scrollback:X==="full"?5e3:1e3}),P=new Zs.FitAddon;S.loadAddon(P),S.open(c),h.current=S,v.current=P;const K=q?S.onRender(()=>U()):null;if(n&&(o||f.current)){f.current=!1;try{S.focus()}catch{}}n&&(S.onData(ce),X==="full"&&S.parser.registerOscHandler(52,be=>{var Se;const we=Wn(be);return we!==null&&((Se=navigator.clipboard)==null||Se.writeText(we).catch(()=>{})),!0}));const J=()=>c.clientWidth>0&&c.clientHeight>0,C=(be=!1)=>{if(!J())return!1;const we=S.cols,Se=S.rows;try{P.fit()}catch{return!1}return $&&S.scrollToBottom(),S.cols>0&&S.rows>0&&(be||S.cols!==we||S.rows!==Se)&&oe(S.cols,S.rows),!0};d.current=$?()=>C(!0):null;let D=null,Y=null,G=null,je=0;const ge=()=>{D||(D=new ResizeObserver(()=>{Y&&clearTimeout(Y),Y=setTimeout(()=>{Y=null,$?C():q&&U()},100)}),D.observe(c))},Ae=()=>{G=requestAnimationFrame(()=>{if(G=null,!g){if(!$){q&&(ge(),U());return}if(C(!0)){ge();return}if(je++<5){Ae();return}ge()}})};return Ae(),()=>{g=!0,G!==null&&cancelAnimationFrame(G),j.current!==null&&(cancelAnimationFrame(j.current),j.current=null),k.current!==null&&(clearTimeout(k.current),k.current=null),R.current!==null&&(cancelAnimationFrame(R.current),R.current=null),b.current++,x.current=[],N.current=0,E.current=Promise.resolve(),Y&&clearTimeout(Y),D==null||D.disconnect(),K==null||K.dispose(),h.current=null,v.current=null,d.current=null;try{S.dispose()}catch(be){console.warn("[pane-terminal] dispose failed:",be)}}},[e,o,$,ce,n,X,oe]);const ue=()=>{var c;if(n){me();try{(c=h.current)==null||c.focus()}catch{}}};a.useEffect(()=>{if(n)return;const c=m.current;if(!c)return;const g=S=>{S.stopPropagation()};return c.addEventListener("wheel",g,{capture:!0,passive:!0}),()=>c.removeEventListener("wheel",g,{capture:!0})},[n]);const A=i&&i>0?{maxHeight:`${i*Wt}px`}:void 0;return t.jsxs("div",{className:r??"flex flex-col h-full w-full min-h-0 bg-term",children:[(y||_)&&t.jsx("div",{className:"border-b border-accent/25 bg-accent-soft px-3 py-1 font-mono text-xs text-accent",children:_?"会话已结束":y}),t.jsx("div",{className:"flex flex-1 min-h-0 px-2 py-1.5",style:A,children:t.jsx("div",{ref:m,className:"flex-1 min-h-0 overflow-hidden",onMouseDown:ue})}),n&&u&&t.jsxs("div",{className:"grid grid-cols-[1fr_auto_1fr] gap-2 flex-none items-center border-t border-hairline bg-page px-3 py-2",children:[t.jsx("div",{className:"flex items-center",children:t.jsx(Dn,{agentId:e})}),t.jsx(In,{className:"flex items-center justify-center gap-1",onKey:c=>{var S,P;const g=!!((P=(S=h.current)==null?void 0:S.modes)!=null&&P.applicationCursorKeysMode);ce(Mn(c,g))},onEscape:()=>ce("\x1B")})]})]})}function zn(){const[e,s]=a.useState([]),[n,i]=a.useState(!0),[r,o]=a.useState(null),l=a.useCallback(async()=>{i(!0);try{s(await I.pets.list()),o(null)}catch(u){o(u instanceof Error?u.message:String(u))}finally{i(!1)}},[]);return a.useEffect(()=>{l()},[l]),{pets:e,loading:n,error:r,refresh:l}}const lt=new Map,dt=new Map;function Gn(e){const[s,n]=a.useState(()=>e?dt.get(e)??null:null);return a.useEffect(()=>{if(!e){n(null);return}const i=dt.get(e);if(n(i??null),i)return;let r=!1,o=lt.get(e);return o||(o=I.pets.fetchSpritesheet(e).then(l=>{const u=URL.createObjectURL(l);return dt.set(e,u),u}),lt.set(e,o)),o.then(l=>{r||n(l)},()=>{r||n(null),lt.delete(e)}),()=>{r=!0}},[e]),s}const Qn=[{state:"idle",row:0,durations:[280,110,110,140,140,320]},{state:"running-right",row:1,durations:[120,120,120,120,120,120,120,220]},{state:"running-left",row:2,durations:[120,120,120,120,120,120,120,220]},{state:"waving",row:3,durations:[140,140,140,280]},{state:"jumping",row:4,durations:[140,140,140,140,280]},{state:"failed",row:5,durations:[140,140,140,140,140,140,140,240]},{state:"waiting",row:6,durations:[150,150,150,150,150,260]},{state:"running",row:7,durations:[120,120,120,120,120,220]},{state:"review",row:8,durations:[150,150,150,150,150,280]}];function Kn(e,s){if(s)return 3;switch(e){case"working":return 7;case"waiting":return 6;case"pending":return 6;case"error":return 5;case"idle":return 0;case"unknown":return 0;default:return 0}}const At=36,Vn=At/vs,Jn=bs*Vn;function Yn(){return typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}function Ss({petId:e,status:s,bootstrapping:n=!1,label:i,displayHeight:r=At,className:o}){const l=Gn(e),u=Kn(s,n),m=Qn[u],h=m.durations.length,[v,d]=a.useState(0),f=r/vs,p=bs*f;return a.useEffect(()=>{if(d(0),!l||h<=1||Yn())return;let x,N=0;const j=()=>{N=(N+1)%h,d(N),x=setTimeout(j,m.durations[N])};return x=setTimeout(j,m.durations[0]),()=>clearTimeout(x)},[l,u,h,m]),l?t.jsx("span",{role:"img","aria-label":i,title:i,"data-pet-row":u,"data-pet-col":v,className:["inline-block shrink-0",o].filter(Boolean).join(" "),style:{width:`${p}px`,height:`${r}px`,backgroundImage:`url(${l})`,backgroundRepeat:"no-repeat",backgroundSize:`${nn*f}px ${rn*f}px`,backgroundPositionX:`${-(v*p)}px`,backgroundPositionY:`${-(u*r)}px`,imageRendering:"pixelated"}}):t.jsx("span",{className:"pill pill-idle",title:i,children:i})}class Ve extends Error{constructor(s){super(s),this.name="PetPackageError"}}const Ge=e=>e.split("/").pop()??e;function Xn(e){return typeof e.text=="function"?e.text():new Promise((s,n)=>{const i=new FileReader;i.onerror=()=>n(i.error??new Error("file read failed")),i.onload=()=>s(typeof i.result=="string"?i.result:""),i.readAsText(e)})}async function Zn(e){const s=e.find(l=>Ge(l.name)==="pet.json"||Ge(l.webkitRelativePath||"")==="pet.json");if(!s)throw new Ve("文件包中未找到 pet.json");let n;try{n=JSON.parse(await Xn(s))}catch{throw new Ve("pet.json 解析失败")}const i=n&&typeof n=="object"&&typeof n.spritesheetPath=="string"?n.spritesheetPath:"",r=i?Ge(i):"",o=(r?e.find(l=>Ge(l.name)===r):void 0)??e.find(l=>/\.(png|webp)$/i.test(l.name));if(!o)throw new Ve("文件包中未找到精灵图(png/webp)");return{manifest:n,spritesheet:o}}function er({children:e,style:s}){const n=a.useRef(null),[i,r]=a.useState(typeof IntersectionObserver>"u");return a.useEffect(()=>{if(i||typeof IntersectionObserver>"u")return;const o=n.current;if(!o)return;const l=new IntersectionObserver(u=>{u.some(m=>m.isIntersecting)&&(r(!0),l.disconnect())});return l.observe(o),()=>l.disconnect()},[i]),t.jsx("span",{ref:n,className:"inline-block shrink-0",style:s,children:i?e:null})}function tr({agentId:e,currentPetId:s,onClose:n}){const{show:i}=ve(),r=Ct(),{pets:o,loading:l,refresh:u}=zn(),[m,h]=a.useState(!!s),[v,d]=a.useState(s),[f,p]=a.useState(!1),x=a.useRef(null);a.useEffect(()=>{d(s)},[s]),a.useEffect(()=>{const b=x.current;b&&(b.setAttribute("webkitdirectory",""),b.setAttribute("directory",""))},[m]);const N=b=>b instanceof Pe||b instanceof Error?b.message:String(b),j=async b=>{if(h(b),!b&&v){p(!0);try{await I.agents.setPet(e,null),d(null),i({kind:"success",title:"已关闭 Agent Pet"})}catch(y){i({kind:"error",title:"关闭失败",body:N(y)}),h(!0)}finally{p(!1)}}},k=async b=>{p(!0);try{await I.agents.setPet(e,b),d(b),i({kind:"success",title:"已选择 Pet"})}catch(y){i({kind:"error",title:"选择失败",body:N(y)})}finally{p(!1)}},R=async(b,y)=>{if(await r({title:`删除 Pet「${y}」?`,body:"使用它的 Agent 会回到默认状态显示。",confirmLabel:"删除"})){p(!0);try{await I.pets.remove(b),await u(),i({kind:"success",title:`Pet「${y}」已删除`})}catch(w){i({kind:"error",title:"删除失败",body:N(w)})}finally{p(!1)}}},E=async b=>{const y=b.target.files?Array.from(b.target.files):[];if(b.target.value="",!!y.length){p(!0);try{const{manifest:w,spritesheet:_}=await Zn(y);await I.pets.create(w,_),await u(),i({kind:"success",title:"Pet 上传成功"})}catch(w){const _=w instanceof Ve?w.message:N(w);i({kind:"error",title:"Pet 上传失败",body:_})}finally{p(!1)}}};return t.jsx(Ne,{open:!0,onClose:n,title:"Agent Pet",size:"md",children:t.jsxs("div",{className:"space-y-4",children:[t.jsxs("label",{className:"flex items-center gap-2 text-sm text-og-1000",children:[t.jsx("input",{type:"checkbox",checked:m,disabled:f,onChange:b=>void j(b.target.checked)}),"启用 Agent Pet"]}),m?t.jsxs(t.Fragment,{children:[t.jsxs("div",{children:[t.jsx("button",{type:"button",onClick:()=>{var b;return(b=x.current)==null?void 0:b.click()},disabled:f,className:"btn-secondary",children:"上传 Pet 文件包"}),t.jsx("input",{ref:x,type:"file","aria-label":"上传 Codex Pet 文件包",className:"hidden",onChange:b=>void E(b)}),t.jsx("p",{className:"mt-1 text-xs text-og-400",children:"选择 Codex Pet 目录(含 pet.json 与精灵图)。"})]}),l?t.jsx("p",{className:"text-sm text-og-500",children:"加载中…"}):o.length===0?t.jsx("p",{className:"text-sm text-og-500",children:"还没有上传过 Pet,点击上方按钮上传。"}):t.jsx("ul",{className:"grid grid-cols-2 gap-2",children:o.map(b=>{const y=b.id===v;return t.jsxs("li",{className:`flex items-center gap-2 rounded-md border p-2 ${y?"border-accent bg-accent-soft/40":"border-hairline"}`,children:[t.jsx(er,{style:{width:`${Jn}px`,height:`${At}px`},children:t.jsx(Ss,{petId:b.id,status:"idle",label:b.displayName})}),t.jsxs("button",{type:"button",onClick:()=>void k(b.id),disabled:f||y,title:b.description||b.displayName,className:"min-w-0 flex-1 truncate text-left text-sm text-og-1000 hover:text-accent-hover disabled:cursor-default",children:[b.displayName,y&&t.jsx("span",{className:"ml-1 text-xs text-accent",children:"(当前)"})]}),t.jsx("button",{type:"button","aria-label":`删除 ${b.displayName}`,onClick:()=>void R(b.id,b.displayName),disabled:f,className:"shrink-0 text-xs text-accent hover:underline disabled:opacity-50",children:"删除"})]},b.id)})})]}):t.jsx("p",{className:"text-xs text-og-500",children:"开启后可上传 Codex Pet 文件包,或选择已上传过的 Pet 替换 Agent 卡片上的状态显示。"})]})})}const sr={unknown:{label:"未知",cls:"pill pill-idle"},idle:{label:"空闲",cls:"pill pill-idle"},pending:{label:"待人工",cls:"pill pill-warn"},working:{label:"工作中",cls:"pill pill-live"},waiting:{label:"等待中",cls:"pill pill-review"},error:{label:"异常",cls:"pill pill-warn"}},nr=72,rr={absent:{label:"无会话",modifier:"status-dot--warn"},unreachable:{label:"主机不可达",modifier:"status-dot--danger"},unknown:{label:"会话状态未知",modifier:"status-dot--warn"},starting:{label:"会话启动中",modifier:"status-dot--info"}};function ir({state:e}){if(e==="present")return null;const{label:s,modifier:n}=rr[e];return t.jsx("span",{role:"img","aria-label":s,title:s,className:`status-dot ml-2 ${n}`})}function ks({agent:e,projectId:s,role:n,runtime:i,onDeleted:r,pendingRestart:o=!1,terminalLoading:l=!1,showTaskBinding:u=!0,terminalMode:m="activity-preview",active:h,onActivate:v}){var be,we,Se,Mt,_t,Ot,Ft,Bt;const[d,f]=a.useState(!1),[p,x]=a.useState(null),{show:N}=ve(),j=Ct(),{flagDirty:k}=rt(),[R,E]=a.useState(!1),[b,y]=a.useState(null),[w,_]=a.useState(!1),[L,T]=a.useState(!1),[F,O]=a.useState(!1),[M,z]=a.useState(!1),[X,$]=a.useState(!1),[Z,q]=a.useState(!1),V=(be=e.binding)==null?void 0:be.taskId,U=((we=e.binding)==null?void 0:we.status)==="awaiting_human",Q=U&&((Se=e.binding)==null?void 0:Se.awaitingPhase)==="greeting_failed",se=!!((Mt=e.binding)!=null&&Mt.creationToken)&&!((_t=e.binding)!=null&&_t.paneId)&&!U&&e.reason!=="PENDING_HUMAN",de=se&&e.tmuxSessionStatus!=="present",B=se?{label:"启动中",cls:"pill pill-review"}:sr[e.runtimeStatus],ie=se?"starting":e.tmuxSessionStatus,re=m==="activity-preview"&&!de&&(e.runtimeStatus==="working"||e.runtimeStatus==="pending"),le=m==="embedded-full",oe=le&&typeof v=="function",me=oe&&h===!0,ce=l||o||de,ue=l?"Agent 状态加载中":o?"重启 baxian server 后可用":"Agent 正在启动",A=fs(i),c=async()=>{f(!0),x(null);try{await I.agents.stop(e.id)}catch(H){x(H instanceof Error?H.message:String(H))}finally{f(!1)}},g=async()=>{if(!(!V||!await j({title:"发起 QA 重审?",body:`QA agent 将对任务 ${V} 立即开始新一轮 review(reviewRound +1)。`,confirmLabel:"发起重审"}))){O(!0);try{const fe=await I.tasks.review(V);N({kind:"success",title:`已发起 QA 重审(第 ${fe.reviewRound} 轮)`})}catch(fe){N({kind:"error",title:"发起评审失败",body:fe instanceof Error?fe.message:String(fe)})}finally{O(!1)}}},S=async()=>{$(!0);try{(await I.projects.bootstrap(s)).ok?N({kind:"success",title:"重试 bootstrap 完成",body:"agent 状态将在下一次刷新生效。"}):N({kind:"warn",title:"重试 bootstrap 仍失败",body:"看一下红色错误卡的最新原因,按提示修复后再试。"})}catch(H){N({kind:"error",title:"重试 bootstrap 失败",body:H instanceof Error?H.message:String(H)})}finally{$(!1)}},P=async()=>{if(await j({title:`恢复 Agent ${e.id}?`,body:Q?"greeting 能力未通过,baxian 会重跑能力握手(会话存活则重启 REPL,已丢失则重建);握手通过才解除挂起。":"baxian 会清除 awaiting_human 状态,agent 恢复可用。",confirmLabel:"恢复"})){z(!0);try{if(Q){e.tmuxSessionStatus==="present"?await I.projects.restartRepl(s,e.id):await I.projects.retryAgent(s,e.id),N({kind:"success",title:`Agent ${e.id} 正在重跑能力握手`,body:"握手通过后 Held 会在下一次刷新自动解除,仍失败则按提示修复 runtime 后再试。"});return}const fe=await I.projects.resumeAgent(s,e.id);N({kind:"success",title:`Agent ${e.id} 已 Resume`,body:fe.releasedBinding?"原任务已释放,agent 可接新任务。":"保留绑定(原任务仍 active)。"})}catch(fe){N({kind:"error",title:"Resume 失败",body:fe instanceof Error?fe.message:String(fe)})}finally{z(!1)}}},K=async()=>{_(!0);try{await I.agents.compact(e.id),N({kind:"success",title:`已向 Agent ${e.id} 发送 /compact`})}catch(H){N({kind:"error",title:"压缩上下文失败",body:H instanceof Error?H.message:String(H)})}finally{_(!1)}},J=async()=>{if(await j({title:`清空 Agent ${e.id} 的上下文?`,body:"将发送 /clear,整个会话上下文不可恢复。",confirmLabel:"清空"})){T(!0);try{await I.agents.clear(e.id),N({kind:"success",title:`已向 Agent ${e.id} 发送 /clear`})}catch(H){N({kind:"error",title:"清空上下文失败",body:H instanceof Error?H.message:String(H)})}finally{T(!1)}}},C=async()=>{if(await j({title:`删除 Agent ${e.id}?`,body:"此操作不可撤销。",confirmLabel:"删除"})){E(!0),y(null);try{const H=await I.projects.deleteAgent(s,e.id);H!=null&&H.restartRequired&&k();const fe=(H==null?void 0:H.removed)??[e.id];if(fe.length>1){const Gs=fe.filter(Qs=>Qs!==e.id).join(", ");N({kind:"warn",title:`已删除 Agent ${e.id}`,body:`配对的 QA agent ${Gs} 也被一并移除。`})}else N({kind:"success",title:`Agent ${e.id} 已删除`});r==null||r()}catch(H){y(H instanceof Error?H.message:String(H))}finally{E(!1)}}},D=oe&&!ce&&!me,Y=["card relative flex h-full min-w-0 flex-col overflow-visible p-4",me?"ring-2 ring-accent":""].filter(Boolean).join(" "),G=["mb-3 flex items-start justify-between gap-2",e.petId?"pr-28":""].filter(Boolean).join(" "),je=["mb-2 mt-3 h-80 min-h-0 overflow-hidden border border-hairline bg-surface",D?"cursor-pointer":""].filter(Boolean).join(" "),ge=D?()=>v==null?void 0:v():void 0,Ae=D?H=>{(H.key==="Enter"||H.key===" ")&&(H.preventDefault(),v==null||v())}:void 0;return t.jsxs("div",{className:Y,"data-agent-card":oe?e.id:void 0,children:[e.petId&&t.jsx("div",{className:"absolute -top-4 right-7 z-10",children:t.jsx(Ss,{petId:e.petId,status:e.runtimeStatus,bootstrapping:se,label:B.label,displayHeight:nr})}),t.jsxs("div",{className:G,children:[t.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[t.jsx("span",{className:"shrink-0 font-mono text-xs font-medium tracking-[0.05em] text-og-500",children:n==="qa"?"QA":"Dev"}),t.jsx("span",{className:"min-w-0 truncate whitespace-nowrap font-display text-sm font-semibold text-og-1000",title:hs(e.id,i),children:e.id}),A&&t.jsxs("span",{className:"hidden shrink-0 whitespace-nowrap text-xs text-og-400 sm:inline",title:A,children:["(",A,")"]})]}),t.jsxs("div",{className:"flex flex-wrap items-center justify-end gap-1",children:[U&&t.jsx("span",{className:"pill pill-warn",title:((Ot=e.binding)==null?void 0:Ot.awaitingReason)??"需人工处理",children:"挂起"}),!e.petId&&t.jsx("span",{className:B.cls,children:B.label}),e.stale&&t.jsx("span",{className:"pill pill-warn",title:e.observedAt?`Last observed at ${e.observedAt}`:void 0,children:"失联"}),t.jsx(ir,{state:ie})]})]}),de&&t.jsx("div",{className:"mb-2 rounded-md border border-accent-soft bg-accent-soft/40 px-2.5 py-2 text-xs text-accent",children:"Agent 正在启动,终端可用后会自动刷新。"}),U&&t.jsxs("div",{className:"mb-2 rounded-md border border-accent/25 bg-accent-soft/60 px-2.5 py-2 text-xs text-accent",children:[t.jsx("span",{className:"font-mono",children:(Ft=e.binding)==null?void 0:Ft.awaitingPhase}),((Bt=e.binding)==null?void 0:Bt.awaitingReason)&&t.jsxs("span",{children:[" · ",e.binding.awaitingReason]})]}),!se&&e.runtimeStatus==="pending"&&t.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-accent/25 bg-accent-soft/60 px-2.5 py-2 text-xs text-accent",children:[t.jsx("div",{className:"font-medium",children:"等待人工介入"}),t.jsxs("div",{children:["请打开 ",t.jsx(Be,{to:`/terminal/${e.id}`,className:"text-accent hover:text-accent-hover underline",children:"终端"})," 处理。"]})]}),e.latestError&&t.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-accent/25 bg-accent-soft px-2.5 py-2 text-xs text-accent",children:[t.jsx("div",{className:"break-words font-medium",children:e.latestError.message}),t.jsxs("div",{className:"font-mono text-xs opacity-80",children:[e.latestError.reason," · ",e.latestError.occurredAt]})]}),e.latestBootstrapError&&t.jsxs("div",{className:"mb-2 space-y-1 rounded-md border border-accent/25 bg-accent-soft px-2.5 py-2 text-xs text-accent",children:[t.jsx("div",{className:"break-words font-medium",children:e.latestBootstrapError.message}),e.latestBootstrapError.recommendation&&t.jsx("div",{className:"break-words",children:e.latestBootstrapError.recommendation}),t.jsxs("div",{className:"flex items-center justify-between gap-2",children:[t.jsxs("div",{className:"truncate font-mono text-xs opacity-80",children:[e.latestBootstrapError.reason," · ",e.latestBootstrapError.occurredAt]}),t.jsx("button",{type:"button",onClick:S,disabled:X,className:"btn-primary shrink-0",children:X?"重试中…":"重试 bootstrap"})]})]}),u&&V&&t.jsxs("div",{className:"mb-2 text-xs text-og-500",children:["任务:",t.jsx("span",{className:"font-mono text-og-700",children:V})]}),re&&t.jsx("div",{className:"mb-2 overflow-hidden border border-hairline bg-surface",children:t.jsx(_e,{agentId:e.id,mode:"preview",maxLines:6,interactive:!1})}),le&&t.jsx("div",{className:je,role:D?"button":void 0,tabIndex:D?0:void 0,"aria-label":D?`激活 ${e.id} 终端`:void 0,onClick:ge,onKeyDown:Ae,children:ce?t.jsx("div",{className:"flex h-full items-center justify-center px-3 text-sm text-og-500",children:ue}):oe?me?t.jsx(_e,{agentId:e.id,mode:"full",interactive:!0,autoFocus:!0}):t.jsx(_e,{agentId:e.id,mode:"preview",interactive:!1}):t.jsx(_e,{agentId:e.id,mode:"full",interactive:!0,autoFocus:!1,deferFullUntilFocus:!0})}),o&&t.jsx("div",{className:"mb-2 rounded-md border border-accent/25 bg-accent-soft/60 px-2.5 py-1.5 text-xs text-accent",children:"重启 baxian server 后生效"}),t.jsxs("div",{className:"mt-3 flex items-center gap-2",children:[t.jsxs("div",{className:"flex min-w-0 flex-1 items-center gap-2 overflow-x-auto scrollbar-none",children:[ce?t.jsx("span",{className:"shrink-0 cursor-not-allowed text-sm text-og-400",title:ue,children:"终端"}):t.jsx(Be,{to:`/terminal/${e.id}`,className:"btn-secondary shrink-0",children:"终端"}),!o&&e.runtimeStatus==="working"&&t.jsx("button",{onClick:c,disabled:d,className:"btn-ghost shrink-0",children:d?"停止中…":"停止"}),U&&t.jsx("button",{type:"button",onClick:P,disabled:M,title:Q?"重跑 greeting 能力握手以恢复(会话存活则重启 REPL,已丢失则重建;greeting_failed 无法靠清状态解除)":"清除 awaiting_human 状态,让 agent 恢复可用",className:"btn-primary shrink-0",children:M?"恢复中…":"恢复"})]}),t.jsx(St,{ariaLabel:`Agent ${e.id} 操作菜单`,className:"shrink-0",placement:"up",autoFocusFirstItem:!0,disabled:R,children:H=>t.jsxs(t.Fragment,{children:[t.jsx(he,{onClick:()=>{H(),q(!0)},disabled:w||L||R,title:"配置 Agent Pet(在状态位置显示动画宠物)",children:"Agent Pet"}),t.jsx(he,{onClick:()=>{H(),K()},disabled:w||L||R,title:"向 agent runtime 发送 /compact 压缩上下文",children:w?"压缩中…":"压缩上下文"}),t.jsx(he,{onClick:()=>{H(),J()},disabled:L||w||R,title:"向 agent runtime 发送 /clear 清空上下文",children:L?"清空中…":"清空上下文"}),!o&&V&&n==="dev"&&t.jsx(he,{onClick:()=>{H(),g()},disabled:F||R,title:`让 QA agent 立即对任务 ${V} 跑一轮 review(需要该任务已有 PR)`,children:F?"发起中…":"发起评审"}),t.jsx(he,{onClick:()=>{H(),C()},disabled:R||w||L,children:R?"删除中…":"删除"})]})})]}),p&&t.jsx("div",{className:"mt-1.5 break-words text-xs text-accent",children:p}),b&&t.jsx("div",{className:"mt-1.5 break-words text-xs text-accent",children:b}),Z&&t.jsx(tr,{agentId:e.id,currentPetId:e.petId??null,onClose:()=>q(!1)})]})}const ut="baxian:terminal-activated";function Es({coordinateAcrossInstances:e=!0}={}){const s=a.useId(),[n,i]=a.useState(null);a.useEffect(()=>{if(n===null)return;const o=m=>{m.composedPath().some(d=>d instanceof Element&&d.hasAttribute("data-agent-card"))||i(null)},l=m=>{if(m.key!=="Escape")return;const h=document.activeElement;h instanceof Element&&h.closest("[data-agent-card]")||i(null)},u=m=>{const h=m.detail;(h==null?void 0:h.ownerId)!==s&&i(null)};return document.addEventListener("click",o),document.addEventListener("keydown",l),e&&document.addEventListener(ut,u),()=>{document.removeEventListener("click",o),document.removeEventListener("keydown",l),e&&document.removeEventListener(ut,u)}},[n,e,s]);const r=a.useCallback(o=>{i(o),e&&document.dispatchEvent(new CustomEvent(ut,{detail:{ownerId:s}}))},[e,s]);return{activeAgentId:n,activateAgentCard:r}}const ar={pending:"待处理",in_progress:"进行中",review:"评审中",fixing:"修订中","spec-ready":"Spec 待批",approved:"已通过","merge-ready":"待确认",ready:"待确认",merged:"已合并",done:"已完成",failed:"失败",max_rounds:"轮次达上限",cancelled:"已取消"};function Ie(e){return ar[e]??e}const Rs={pending:"pill",in_progress:"pill pill-live",review:"pill pill-review",fixing:"pill pill-warn","spec-ready":"pill pill-warn",approved:"pill pill-live","merge-ready":"pill pill-warn",ready:"pill pill-warn",merged:"pill pill-live",done:"pill pill-live",failed:"pill pill-danger",max_rounds:"pill pill-warn",cancelled:"pill"},or={pending:"bg-og-300",in_progress:"bg-success",review:"bg-accent",fixing:"bg-warn","spec-ready":"bg-warn",approved:"bg-success","merge-ready":"bg-warn",ready:"bg-warn",merged:"bg-success",done:"bg-success",failed:"bg-danger",max_rounds:"bg-warn",cancelled:"bg-og-300"};function cr({status:e}){return t.jsx("span",{role:"img","aria-label":e,title:e,className:`inline-block h-2 w-2 shrink-0 rounded-full ${or[e]??"bg-og-300"}`})}function $t(e){if(!e)return"";const s=e.match(/^task-(\d+)$/);return s?s[1]:e}function mt(e,s=!0){if(e==null)return"";const n=String(e).trim();if(!n)return"";const i=new Date(n.replace(/^(\d{4}-\d{2}-\d{2}) /,"$1T"));if(Number.isNaN(i.getTime()))return n;const r=u=>String(u).padStart(2,"0"),o=`${i.getFullYear()}-${r(i.getMonth()+1)}-${r(i.getDate())}`,l=`${r(i.getHours())}:${r(i.getMinutes())}`;return s?`${o} ${l}:${r(i.getSeconds())}`:`${o} ${l}`}function Ce(e,s){return`/project/${encodeURIComponent(e)}/task/${encodeURIComponent(s)}`}function Cs({group:e,projectId:s,agentsById:n,agentsLoaded:i,agentsError:r=!1,tasks:o,onDeleted:l,terminalMode:u="activity-preview"}){var w,_,L;const m=e.find(T=>T.role==="dev")??e[0],h=e.find(T=>T.role==="qa"),v=o.filter(T=>dr(T,m==null?void 0:m.id,h==null?void 0:h.id)),d=m?o.filter(T=>ur(T,s,m.id)).sort((T,F)=>T.createdAt.localeCompare(F.createdAt)):[],f=m?n.get(m.id):void 0,p=!!f&&f.runtimeStatus==="idle"&&((w=f.binding)==null?void 0:w.status)!=="awaiting_human"&&!((_=f.binding)!=null&&_.creationToken)&&!((L=f.binding)!=null&&L.taskId),x=`Agent group ${e.map(T=>T.id).join(" / ")}`,N=pe(),j=u==="embedded-full",{activeAgentId:k,activateAgentCard:R}=Es({coordinateAcrossInstances:j}),E=u==="embedded-full"?e.length<=1?"lg:grid-cols-1":e.length===2?"lg:grid-cols-2":e.length===3?"lg:grid-cols-3":"lg:grid-cols-4":"sm:grid-cols-2",b=!!m&&d.length>0,y=v.length===0&&!b;return t.jsxs("div",{role:"group","aria-label":x,className:"min-w-0",children:[b&&m&&t.jsx(lr,{tasks:d,devId:m.id,dispatchReady:p,label:x}),v.length>0&&t.jsx("div",{className:"card mb-2 max-h-28 overflow-y-auto divide-y divide-hairline",children:v.map(T=>{const F=T.phase==="spec"?T.specReviewRound??0:T.reviewRound;return t.jsxs("button",{type:"button",onClick:()=>N(Ce(T.projectId,T.id)),className:"flex w-full items-center gap-3 px-3 py-2 text-left text-sm transition-colors hover:bg-og-50/60",children:[t.jsxs("div",{className:"min-w-0 flex-1 flex items-center gap-2",children:[t.jsx("span",{className:"shrink-0 font-mono text-xs text-og-500",title:T.id,children:$t(T.id)}),t.jsx("span",{className:"truncate text-og-1000",children:T.title})]}),t.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[t.jsxs("span",{className:"shrink-0 text-xs text-og-500",children:["第 ",F," 轮"]}),t.jsx("span",{className:`${Rs[T.status]} shrink-0`,title:T.status,children:Ie(T.status)})]})]},T.id)})}),y&&t.jsx("div",{className:"mb-2 rounded-lg border border-hairline bg-surface px-3 py-2 text-sm text-og-400","aria-label":`${x} no active task`,children:"暂无任务"}),t.jsx("div",{className:`grid grid-cols-1 ${E} gap-4`,children:e.map(T=>{const F=n.get(T.id),O=F??{id:T.id,projectId:s,runtimeStatus:"unknown",tmuxSessionStatus:"unknown",stale:!0};return t.jsx(ks,{agent:O,projectId:s,role:T.role,runtime:T.runtime,pendingRestart:i&&!F,terminalLoading:!i&&!F&&!r,onDeleted:l,showTaskBinding:!1,terminalMode:u,...j?{active:k===T.id,onActivate:()=>R(T.id)}:{}},T.id)})})]})}function lr({tasks:e,devId:s,dispatchReady:n,label:i}){const{show:r}=ve(),o=pe(),[l,u]=a.useState(null),m=async h=>{u(h);try{await I.tasks.dispatch(h,{agentId:s}),r({kind:"success",title:`任务 ${h} 已交给 ${s}`})}catch(v){r({kind:"error",title:"发起失败",body:v instanceof Error?v.message:String(v)})}finally{u(null)}};return t.jsx("div",{role:"group",className:"card mb-2 max-h-28 overflow-y-auto divide-y divide-hairline","aria-label":`${i} claimable tasks for ${s}`,children:e.map(h=>{const v=h.preferredAgentId==="",d=l!==null;return t.jsxs("div",{className:"flex items-center gap-3 px-3 py-2 text-sm",children:[t.jsxs("button",{type:"button",onClick:()=>o(Ce(h.projectId,h.id)),className:"min-w-0 flex-1 flex items-center gap-2 text-left transition-colors hover:text-accent-hover",children:[t.jsx("span",{className:"shrink-0 font-mono text-xs text-og-500",title:h.id,children:$t(h.id)}),t.jsx("span",{className:"truncate text-og-1000",title:h.title,children:h.title}),v&&t.jsx("span",{className:"pill shrink-0",children:"未分配"})]}),t.jsx("button",{type:"button",onClick:()=>void m(h.id),disabled:!n||d,title:n?`交给 ${s} 并立即开始`:"Dev agent 当前不可用",className:"shrink-0 text-sm font-medium text-accent transition-colors hover:text-accent-hover disabled:opacity-50 disabled:cursor-not-allowed",children:l===h.id?"发起中…":"发起"})]},h.id)})})}function dr(e,s,n){return!(!s||!ps.has(e.status)||!(e.agentId===s||e.preferredAgentId===s)||n&&e.qaAgentId&&e.qaAgentId!==n)}function ur(e,s,n){return e.projectId!==s||e.status!=="pending"?!1:e.preferredAgentId===n||e.preferredAgentId===""}const ae="w-full rounded-md border border-og-100 bg-surface px-2.5 py-1.5 text-sm 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",ee="mb-1.5 block text-xs font-medium text-og-700",Xe="mt-1 text-xs text-accent",ft="mt-1 text-xs text-og-500",Te="h-3.5 w-3.5 accent-accent",mr=/^[a-z][a-z0-9-]{1,31}$/,fr=[/^https?:\/\/[^/\s]+\/[^\s]+$/,/^ssh:\/\/[^/\s]+\/[^\s]+$/,/^[^@/\s]+@[^:/\s]+:[^\s]+$/,/^[^/\s:@]+\/[^/\s]+$/];function hr({open:e,onClose:s,onCreated:n}){const[i,r]=a.useState(""),[o,l]=a.useState(""),[u,m]=a.useState(null),[h,v]=a.useState(null),[d,f]=a.useState(""),[p,x]=a.useState(!1),[N,j]=a.useState(null),[k,R]=a.useState({}),[E,b]=a.useState(new Set),y=a.useRef(0),{show:w}=ve(),{flagDirty:_}=rt();a.useEffect(()=>{if(!e)return;y.current+=1;const O=y.current;r(""),l(""),m(null),v(null),f(""),j(null),R({}),b(new Set),I.config.get().then(M=>{O===y.current&&b(new Set(M.project.map(z=>z.id)))}).catch(()=>{})},[e]);const L=()=>{p||s()},T=()=>{const O={};return i?mr.test(i)?E.has(i)&&(O.id="该 id 已被占用"):O.id="小写字母开头,只含 a-z 0-9 -,长度 2-32":O.id="必填",o?fr.some(M=>M.test(o.trim()))||(O.repo="需为 git URL(https / ssh / scp,如 https://gitlab.example.com/group/proj.git)或 owner/repo"):O.repo="必填",R(O),Object.keys(O).length===0},F=async O=>{if(O.preventDefault(),!!T()){x(!0),j(null);try{const M=await I.projects.create({id:i,repo:o.trim(),merge:u,...h?{specApproval:h}:{},...d?{review:{mode:d}}:{}});M.restartRequired&&_(),w({kind:"success",title:`项目 ${M.project.id} 已创建`}),n(M.project.id)}catch(M){j(M instanceof Error?M.message:String(M))}finally{x(!1)}}};return t.jsx(Ne,{open:e,onClose:L,title:"新建项目",size:"md",footer:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:L,disabled:p,className:"btn-secondary",children:"取消"}),t.jsx("button",{type:"submit",form:"create-project-form",disabled:p,className:"btn-primary",children:p?"创建中…":"创建"})]}),children:t.jsxs("form",{id:"create-project-form",onSubmit:F,className:"space-y-3",children:[N&&t.jsx("div",{className:"rounded-md border border-accent/25 bg-accent-soft px-3 py-2 text-sm text-accent",children:N}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"proj-id",children:"项目 ID"}),t.jsx("input",{id:"proj-id",type:"text",value:i,onChange:O=>r(O.target.value),className:ae,placeholder:"kongkong",disabled:p}),k.id&&t.jsx("div",{className:Xe,children:k.id})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"proj-repo",children:"Git 仓库地址"}),t.jsx("input",{id:"proj-repo",type:"text",value:o,onChange:O=>l(O.target.value),className:ae,placeholder:"https://github.com/baxian-ai/baxian.git",disabled:p}),k.repo&&t.jsx("div",{className:Xe,children:k.repo})]}),t.jsxs("div",{children:[t.jsx("span",{className:ee,children:"合并策略"}),t.jsxs("label",{className:"mb-1 flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"merge",checked:u===null,onChange:()=>m(null),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"人类合并(默认)"})]}),t.jsxs("label",{className:"flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"merge",checked:u==="auto",onChange:()=>m("auto"),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"QA Approve 后自动合并"})]})]}),t.jsxs("div",{children:[t.jsx("span",{className:ee,children:"Spec 审核"}),t.jsxs("label",{className:"flex items-center gap-2",children:[t.jsx("input",{type:"checkbox",checked:h==="human",onChange:O=>v(O.target.checked?"human":null),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"Spec 需由人类审核"})]}),t.jsx("div",{className:"mt-1 text-xs text-og-500",children:"勾选后,走 SDD 的任务在 QA agent 通过 Spec 后停驻,等你在任务页通过或打回;是否走 SDD 仍由 Dev agent 按任务复杂度判定。"})]}),t.jsxs("div",{children:[t.jsx("span",{className:ee,children:"Review 模式"}),t.jsxs("label",{className:"mb-1 flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"review-mode",checked:d==="",onChange:()=>f(""),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"跟随全局"})]}),t.jsxs("label",{className:"mb-1 flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"review-mode",checked:d==="github",onChange:()=>f("github"),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"GitHub PR"})]}),t.jsxs("label",{className:"flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"review-mode",checked:d==="server",onChange:()=>f("server"),disabled:p,className:"h-3.5 w-3.5 accent-accent"}),t.jsx("span",{className:"text-sm text-og-800",children:"Server"})]})]})]})})}const Gt=/^[a-z][a-z0-9-]{1,31}$/,xr=500,Qt={id:"",role:"dev",pairWith:"",mode:"local",host:"",runtime:"",workdir:"",yolo:!0,model:"",addDirs:""};function pr(e){return e.alias?e.alias:`${e.user?`${e.user}@`:""}${e.hostname}${e.port!=null?`:${e.port}`:""}`}function As({open:e,onClose:s,projectId:n,onCreated:i}){var c;const[r,o]=a.useState(Qt),[l,u]=a.useState(null),[m,h]=a.useState([]),[v,d]=a.useState(new Set),[f,p]=a.useState(null),[x,N]=a.useState(!1),[j,k]=a.useState(!1),[R,E]=a.useState(null),[b,y]=a.useState(!1),[w,_]=a.useState(null),[L,T]=a.useState(!1),F=a.useRef(null),O=a.useRef(null),M=a.useRef(0),z=a.useRef(0),{show:X}=ve(),{flagDirty:$}=rt();a.useEffect(()=>{if(!e)return;z.current+=1;const g=z.current;o(Qt),u(null),h([]),d(new Set),p(null),N(!1),k(!1),E(null),M.current+=1,_(null),T(!1),I.config.get().then(S=>{if(g!==z.current)return;const P=S.project.find(J=>J.id===n)??null;u(P),h(S.host??[]);const K=new Set;S.project.forEach(J=>J.agent.forEach(C=>C.forEach(D=>K.add(D.id)))),d(K)}).catch(()=>{})},[e,n]);const Z=()=>{b||s()},q=a.useCallback(()=>{F.current&&F.current.abort();const g=new AbortController;F.current=g,N(!0),_(null);const S=r.mode==="remote"?{hostId:r.host}:{};I.agents.probe(r.mode,S,{signal:g.signal}).then(P=>{g.signal.aborted||(p(P),_(null))}).catch(P=>{g.signal.aborted||(p(null),_(P instanceof Error?P.message:String(P)))}).finally(()=>{F.current===g&&N(!1)})},[r.mode,r.host]);a.useEffect(()=>{if(e&&(p(null),E(null),k(!1),M.current+=1,F.current&&F.current.abort(),!(r.mode==="remote"&&!r.host)))return O.current&&clearTimeout(O.current),O.current=setTimeout(q,xr),()=>{O.current&&clearTimeout(O.current)}},[e,r.mode,r.host,q]),a.useEffect(()=>{e||F.current&&F.current.abort()},[e]),a.useEffect(()=>()=>{F.current&&F.current.abort(),O.current&&clearTimeout(O.current)},[]);const V=()=>{if(j)return;const g=M.current;k(!0),E(null);const S=r.mode==="remote"?{hostId:r.host}:{};I.agents.installTmux(r.mode,S).then(P=>{M.current===g&&(E({ok:P.ok,message:P.message}),k(!1),P.ok&&q())}).catch(P=>{M.current===g&&(E({ok:!1,message:P instanceof Error?P.message:String(P)}),k(!1))})},U=(l==null?void 0:l.agent.filter(g=>g.length===1&&g[0].role==="dev").map(g=>g[0]))??[],Q=U.length>0,se=Gt.test(r.id)&&!v.has(r.id),de=r.mode==="local"||r.mode==="remote"&&r.host!=="",B=r.runtime!==""&&(r.runtime==="claude-code"?!!(f!=null&&f.runtimes["claude-code"].ok):!!(f!=null&&f.runtimes.codex.ok)),ie=!!(f!=null&&f.tmux.ok),re=r.mode==="local"||!!((c=f==null?void 0:f.ssh)!=null&&c.ok),le=r.role==="dev"||r.role==="qa"&&r.pairWith!=="",oe=!b&&se&&de&&le&&B&&ie&&re,me=async g=>{if(g.preventDefault(),!!oe){y(!0),_(null);try{const S=r.addDirs.split(`
2
+ `).map(J=>J.trim()).filter(J=>J.length>0),P={id:r.id,role:r.role,runtime:r.runtime,mode:r.mode,...r.mode==="remote"?{host:r.host}:{},...r.workdir?{workdir:r.workdir}:{},yolo:r.yolo,...r.model.trim()?{model:r.model.trim()}:{},...S.length>0?{addDirs:S}:{},...r.role==="qa"?{pairWith:r.pairWith}:{}},K=await I.projects.addAgent(n,P);K.restartRequired&&$(),X({kind:"success",title:`Agent ${K.agent.id} 已添加到 ${n}`}),i(),s()}catch(S){_(S instanceof Error?S.message:String(S))}finally{y(!1)}}},ce=({rt:g})=>{if(r.mode==="remote"&&!r.host)return t.jsx("span",{className:"ml-2 text-xs text-og-400",children:"(请先选择 Host)"});if(x)return t.jsx("span",{className:"ml-2 text-xs text-og-400",children:"…探测中"});if(!f)return t.jsx("span",{className:"ml-2 text-xs text-og-400",children:"?"});const P=f.runtimes[g];return P.ok?t.jsxs("span",{className:"ml-2 text-xs text-probe-ok",children:["✓ ",P.path??""]}):t.jsxs("span",{className:"ml-2 text-xs text-accent",title:P.message,children:["⨯ ",P.message]})},ue=()=>{var S;if(r.mode==="remote"&&!r.host)return null;if(x&&!j)return t.jsx("div",{className:"text-xs text-og-400",children:"tmux: …探测中"});if(!f)return null;if(f.tmux.ok)return t.jsxs("div",{className:"text-xs text-probe-ok",children:["tmux: ✓ ",f.tmux.path??""]});const g=r.mode==="local"||!!((S=f.ssh)!=null&&S.ok);return t.jsxs("div",{className:"space-y-1",children:[t.jsxs("div",{className:"text-xs text-accent",children:["tmux: ⨯ ",f.tmux.message,g&&t.jsx("button",{type:"button",onClick:V,className:"ml-2 text-accent underline transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",disabled:j||b,children:j?"安装中…":"一键安装"})]}),j&&t.jsx("div",{className:"text-xs text-og-500",children:"正在安装 tmux,可能需要几分钟,请勿关闭窗口…"}),!j&&R&&t.jsxs("div",{className:`break-all text-xs ${R.ok?"text-probe-ok":"text-accent"}`,children:[R.ok?"✓ ":"⨯ ",R.message]})]})},A=()=>r.mode!=="remote"||!r.host||!(f!=null&&f.ssh)?null:f.ssh.ok?t.jsxs("div",{className:"text-xs text-probe-ok",children:["SSH: ✓ ",f.ssh.message]}):t.jsxs("div",{className:"text-xs text-accent",children:["SSH: ⨯ ",f.ssh.message]});return t.jsx(Ne,{open:e,onClose:Z,title:`添加 Agent 到 ${n}`,size:"lg",footer:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:Z,disabled:b,className:"btn-secondary",children:"取消"}),t.jsx("button",{type:"submit",form:"create-agent-form",disabled:!oe,className:"btn-primary",children:b?"添加中…":"添加 Agent"})]}),children:t.jsxs("form",{id:"create-agent-form",onSubmit:me,className:"space-y-3",children:[w&&t.jsx("div",{className:"rounded-md border border-accent/25 bg-accent-soft px-3 py-2 text-sm text-accent",children:w}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"agent-id",children:"Agent ID"}),t.jsx("input",{id:"agent-id",type:"text",value:r.id,onChange:g=>o({...r,id:g.target.value}),className:ae,placeholder:`${n}-${r.role}`,disabled:b}),r.id&&!Gt.test(r.id)&&t.jsx("div",{className:Xe,children:"小写字母开头,只含 a-z 0-9 -,长度 2-32"}),r.id&&v.has(r.id)&&t.jsx("div",{className:Xe,children:"该 id 已被占用(全局唯一)"})]}),t.jsxs("div",{children:[t.jsx("span",{className:ee,children:"角色"}),t.jsxs("label",{className:"mr-4 inline-flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"role",checked:r.role==="dev",className:Te,onChange:()=>o({...r,role:"dev",pairWith:""}),disabled:b}),t.jsx("span",{className:"text-sm text-og-800",children:"Dev agent"})]}),t.jsxs("label",{className:"inline-flex items-center gap-2",title:Q?"":"请先创建一个 Dev agent",children:[t.jsx("input",{type:"radio",name:"role",checked:r.role==="qa",className:Te,onChange:()=>o({...r,role:"qa"}),disabled:b||!Q}),t.jsx("span",{className:`text-sm ${Q?"text-og-800":"text-og-400"}`,children:"QA agent"})]})]}),r.role==="qa"&&t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"pair-with",children:"配对 Dev agent"}),t.jsxs("select",{id:"pair-with",value:r.pairWith,onChange:g=>o({...r,pairWith:g.target.value}),className:ae,disabled:b,children:[t.jsx("option",{value:"",children:"请选择"}),U.map(g=>t.jsxs("option",{value:g.id,children:[g.id,"(",g.mode,")"]},g.id))]})]}),t.jsxs("div",{children:[t.jsx("span",{className:ee,children:"运行模式"}),t.jsxs("label",{className:"mr-4 inline-flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"mode",checked:r.mode==="local",className:Te,onChange:()=>o({...r,mode:"local",host:""}),disabled:b}),t.jsx("span",{className:"text-sm text-og-800",children:"本机"})]}),t.jsxs("label",{className:"inline-flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"mode",checked:r.mode==="remote",className:Te,onChange:()=>o({...r,mode:"remote"}),disabled:b}),t.jsx("span",{className:"text-sm text-og-800",children:"远程 (SSH)"})]})]}),r.mode==="remote"&&t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host",children:"Host"}),m.length===0?t.jsx("div",{className:"rounded-md border border-og-100 bg-og-50/40 px-3 py-2 text-xs text-og-600",children:"还没有配置 Host。请先在右上角菜单的「Host 管理」中添加。"}):t.jsxs("select",{id:"host",value:r.host,onChange:g=>o({...r,host:g.target.value}),className:ae,disabled:b,children:[t.jsx("option",{value:"",children:"请选择 Host"}),m.map(g=>t.jsx("option",{value:g.id,children:pr(g)},g.id))]}),t.jsx("div",{className:ft,children:"私钥/跳板机仍可在 ~/.ssh/config 配置;端口/密码在「Host 管理」里设置。"})]}),t.jsxs("div",{children:[t.jsxs("div",{className:"mb-1.5 flex items-center justify-between",children:[t.jsx("span",{className:"text-xs font-medium text-og-700",children:"运行时"}),t.jsx("button",{type:"button",onClick:q,className:"text-xs text-accent transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",disabled:b||x||r.mode==="remote"&&!r.host,children:"↻ 重新探测"})]}),t.jsxs("label",{className:"flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"runtime",checked:r.runtime==="claude-code",className:Te,onChange:()=>o({...r,runtime:"claude-code"}),disabled:b||(f?!f.runtimes["claude-code"].ok:!1)}),t.jsx("span",{className:"text-sm text-og-800",children:"Claude Code"}),t.jsx(ce,{rt:"claude-code"})]}),t.jsxs("label",{className:"mt-1 flex items-center gap-2",children:[t.jsx("input",{type:"radio",name:"runtime",checked:r.runtime==="codex",className:Te,onChange:()=>o({...r,runtime:"codex"}),disabled:b||(f?!f.runtimes.codex.ok:!1)}),t.jsx("span",{className:"text-sm text-og-800",children:"Codex"}),t.jsx(ce,{rt:"codex"})]}),t.jsx("div",{className:"mt-2",children:t.jsx(ue,{})}),t.jsx("div",{children:t.jsx(A,{})})]}),t.jsxs("div",{children:[t.jsxs("button",{type:"button",onClick:()=>T(g=>!g),"aria-expanded":L,"aria-controls":L?"advanced-options":void 0,className:"flex w-full items-center justify-between rounded-md px-1 py-1.5 text-left text-xs font-medium text-og-700 transition-colors hover:bg-og-50",children:[t.jsx("span",{children:"高级选项"}),t.jsx("span",{className:"text-og-400",children:L?"收起":"展开"})]}),L&&t.jsxs("div",{id:"advanced-options",className:"mt-3 space-y-3",children:[t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"workdir",children:"Workdir(可选)"}),t.jsx("input",{id:"workdir",type:"text",value:r.workdir,onChange:g=>o({...r,workdir:g.target.value}),className:ae,placeholder:"留空时自动 clone 到 ~/.baxian/repos/<owner>/<repo>",disabled:b})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"model",children:"Model(可选)"}),t.jsx("input",{id:"model",type:"text",value:r.model,onChange:g=>o({...r,model:g.target.value}),className:ae,placeholder:r.runtime==="codex"?"例: o3 / gpt-4o(留空走 default)":"例: sonnet / opus / claude-sonnet-4-6(留空走 default)",disabled:b}),t.jsx("div",{className:ft,children:"透传到 launch 命令的 --model 参数;留空跟随 CLI 默认。"})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"addDirs",children:"Additional Dirs(可选)"}),t.jsx("textarea",{id:"addDirs",value:r.addDirs,onChange:g=>o({...r,addDirs:g.target.value}),className:`${ae} font-mono text-xs`,rows:3,placeholder:`每行一个绝对路径,例:
3
3
  /Users/me/shared-libs
4
- /Users/me/extra-repo`,disabled:b}),t.jsx("div",{className:ft,children:"透传到 --add-dir。当前 YOLO 模式下不影响权限拦截,主要用于让 CLI 把额外目录纳入工作根。"})]})]})]}),t.jsx("div",{className:"rounded-md border border-accent/25 bg-accent-soft/60 px-3 py-2.5",children:t.jsxs("label",{className:"flex cursor-pointer items-start gap-2",children:[t.jsx("input",{type:"checkbox",className:"mt-1 h-3.5 w-3.5 accent-accent",checked:r.yolo,onChange:g=>o({...r,yolo:g.target.checked}),disabled:b}),t.jsxs("div",{className:"text-sm text-og-800",children:[t.jsx("div",{className:"font-medium",children:"YOLO 模式(推荐开启)"}),t.jsxs("div",{className:"mt-1 text-xs text-accent",children:["Agent 自主执行所有命令、文件改动,无需逐条确认。开启后体验更顺滑, 但",t.jsx("strong",{className:"font-semibold",children:"请确认在受控环境(容器、隔离 worktree)中运行"}),"。"]})]})]})})]})})}const Kt=200,Vt=16e3,gr="baxian.draft.createTask:";function vt(e){return`${gr}${e??"*"}`}function Jt(e){try{const s=localStorage.getItem(e);if(!s)return null;const n=JSON.parse(s);if(!n||typeof n!="object")return null;const i=n,r=typeof i.title=="string"?i.title:"",o=typeof i.description=="string"?i.description:"",l=typeof i.projectId=="string"?i.projectId:"",u=typeof i.preferredAgentId=="string"?i.preferredAgentId:"",m=typeof i.updatedAt=="number"?i.updatedAt:void 0;return!r.trim()&&!o.trim()?null:{title:r,description:o,projectId:l,preferredAgentId:u,updatedAt:m}}catch{return null}}function br(e,s){const n=!s.title.trim()&&!s.description.trim();try{n?localStorage.removeItem(e):localStorage.setItem(e,JSON.stringify({...s,updatedAt:Date.now()}))}catch{}}function Yt(e){try{localStorage.removeItem(e)}catch{}}function vr(e){const s=vt(e),n=Jt(s);if(!e)return n;const i=vt(void 0),r=Jt(i);if(!r||r.projectId!==e)return n;const o=!n||(r.updatedAt??0)>(n.updatedAt??0);if(o)try{localStorage.setItem(s,JSON.stringify(r))}catch{return r}try{localStorage.removeItem(i)}catch{}return o?r:n}const Xt="mt-1 text-right text-xs text-og-400",jr=Math.floor(nt/1024/1024);function Tt(e){const s=e.mode==="edit",{show:n}=ve(),i=s?e.task.projectId:e.projectId,r=s?e.task.title:"",o=s?e.task.description:"",l=s?e.task.preferredAgentId:"",[u,m]=a.useState([]),[h,v]=a.useState([]),[d,f]=a.useState(i??""),[p,x]=a.useState(l),[N,j]=a.useState(r),[k,R]=a.useState(o),[E,b]=a.useState([]),y=a.useRef(null),[w,_]=a.useState(!1),[L,T]=a.useState(null),[F,O]=a.useState(!1),M=a.useRef(0),z=a.useRef(0),X=a.useRef(0),$=a.useRef(new Set),Z=s?null:vt(i);a.useEffect(()=>{if(!e.open)return;M.current+=1,z.current+=1;const C=M.current;m([]),v([]),$.current=new Set;const D=Z?vr(i):null;D&&$.current.add(D.projectId),f(i??(D==null?void 0:D.projectId)??""),x((D==null?void 0:D.preferredAgentId)||l),j((D==null?void 0:D.title)||r),R((D==null?void 0:D.description)||o),O(D!==null),T(null),_(!1),b([]),Promise.all([I.projects.list(),I.agents.list()]).then(([Y,G])=>{C===M.current&&(m(Y),v(G))}).catch(Y=>{C===M.current&&T(Y instanceof Error?Y.message:String(Y))})},[e.open,i,r,o,l,Z]),a.useEffect(()=>{if(!(!e.open||!Z)){if(X.current!==z.current){X.current=z.current;return}br(Z,{title:N,description:k,projectId:d,preferredAgentId:p})}},[e.open,Z,N,k,d,p]);const q=a.useMemo(()=>u.find(C=>C.id===d)??null,[u,d]),V=a.useMemo(()=>q?q.agent.flat().filter(C=>C.role==="dev"):[],[q]),U=a.useMemo(()=>new Set(h.map(C=>C.id)),[h]),Q=a.useMemo(()=>V.filter(C=>U.has(C.id)),[V,U]),se=a.useMemo(()=>V.filter(C=>!U.has(C.id)),[V,U]);a.useEffect(()=>{s||q!==null&&p!==""&&!Q.find(C=>C.id===p)&&x("")},[q,Q,p,s]),a.useEffect(()=>{s||q&&Q.length!==0&&($.current.has(q.id)||($.current.add(q.id),x(C=>C===""?Q[0].id:C)))},[s,q,Q]);const de=!s||Q.find(C=>C.id===p),B=s&&!de&&!!p,ie=B&&se.some(C=>C.id===p),re=ie?`当前 Dev agent "${p}" 在 baxian.json 中存在但 runtime 未加载,可能是手动编辑过配置文件;重启 server 可拉起`:B?`当前 Dev agent "${p}" 不在 runtime(可能已从 project 配置移除);保存可能失败,请确认或选择新 Dev agent`:!d||Q.length>0?null:se.length>0?"baxian.json 里有 Dev agent 但 runtime 未加载(可能是手动编辑过配置);重启 server 后生效":null,le=N.trim(),oe=k.trim(),ce=!!d&&le.length>0&&!w,ue=()=>{w||e.onClose()},A=()=>{Z&&(Yt(Z),f(i??""),x(l),j(r),R(o),T(null),O(!1))},c=async C=>{var D,Y;if(C.preventDefault(),!!ce){_(!0),T(null);try{if(e.mode==="edit"){const G=await I.tasks.update(e.task.id,{title:le,description:oe,preferredAgentId:p});n({kind:"success",title:"任务已更新"}),(D=e.onUpdated)==null||D.call(e,G),e.onClose()}else{const G=E.length?await Promise.all(E.map(async ge=>({dataBase64:await bt(ge),filename:ge.name}))):void 0,je=await I.tasks.create({projectId:d,title:le,description:oe,preferredAgentId:p,...G?{images:G}:{}});Z&&Yt(Z),n({kind:"success",title:"任务已创建"}),(Y=e.onCreated)==null||Y.call(e,je),e.onClose()}}catch(G){T(G instanceof Error?G.message:String(G))}finally{_(!1)}}},g=C=>{const D=Array.from(C.target.files??[]);if(C.target.value="",D.length===0)return;const Y=D.filter(G=>G.size>nt?(n({kind:"error",title:"图片过大",body:`${G.name} 超过 ${jr} MiB`}),!1):!0);b(G=>(G.length+Y.length>qe&&n({kind:"warn",title:`最多 ${qe} 张图片`}),[...G,...Y].slice(0,qe)))},S=C=>b(D=>D.filter((Y,G)=>G!==C)),P=s?"编辑任务":"新建任务",K=s?w?"保存中…":"保存":w?"创建中…":"创建",J=!s&&!i;return t.jsx(Ne,{open:e.open,onClose:ue,title:P,size:"md",dismissOnBackdrop:!1,footer:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:ue,disabled:w,className:"btn-secondary",children:"取消"}),t.jsx("button",{type:"submit",form:"create-task-form",disabled:!ce,className:"btn-primary",children:K})]}),children:t.jsxs("form",{id:"create-task-form",onSubmit:c,className:"space-y-3",children:[!s&&F&&t.jsxs("div",{className:"flex items-center justify-between gap-3 rounded-md border border-accent-soft bg-accent-soft/30 px-3 py-2 text-xs text-accent",children:[t.jsx("span",{children:"已恢复上次未提交的草稿"}),t.jsx("button",{type:"button",onClick:A,className:"shrink-0 underline hover:text-accent-hover",children:"丢弃"})]}),L&&t.jsx("div",{className:"rounded-md border border-accent/25 bg-accent-soft px-3 py-2 text-sm text-accent",children:L}),J&&t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"task-project",children:"Project"}),t.jsxs("select",{id:"task-project",value:d,onChange:C=>f(C.target.value),className:ae,disabled:w,required:!0,children:[t.jsx("option",{value:"",disabled:!0,children:"选择项目"}),u.map(C=>t.jsx("option",{value:C.id,children:C.id},C.id))]})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"task-dev",children:"Dev agent"}),t.jsxs("select",{id:"task-dev",value:p,onChange:C=>x(C.target.value),className:ae,disabled:w,children:[t.jsx("option",{value:"",children:"暂不指定"}),B&&t.jsxs("option",{value:p,children:[p," ",ie?"(待重启)":"(不在 runtime)"]}),Q.map(C=>t.jsx("option",{value:C.id,children:C.id},C.id))]}),re&&t.jsx("div",{className:"mt-1 text-xs text-accent",children:re})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"task-title",children:"Title"}),t.jsx("input",{id:"task-title",type:"text",value:N,onChange:C=>j(C.target.value),maxLength:Kt,className:ae,placeholder:"一句话描述要做什么",disabled:w,required:!0}),t.jsxs("div",{className:Xt,children:[N.length," / ",Kt]})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"task-description",children:"Description(可选)"}),t.jsx("textarea",{id:"task-description",value:k,onChange:C=>R(C.target.value),maxLength:Vt,rows:8,className:`${ae} font-mono text-xs`,placeholder:"详细描述任务,支持 markdown;简单任务可不填",disabled:w}),t.jsxs("div",{className:Xt,children:[k.length," / ",Vt]})]}),!s&&t.jsxs("div",{children:[t.jsx("label",{className:ee,children:"图片(可选)"}),t.jsx("button",{type:"button",onClick:()=>{var C;return(C=y.current)==null?void 0:C.click()},disabled:w||E.length>=qe,className:"btn-secondary",children:"添加图片"}),t.jsx("input",{ref:y,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:g}),E.length>0&&t.jsx("ul",{className:"mt-2 space-y-1",children:E.map((C,D)=>t.jsxs("li",{className:"flex items-center justify-between rounded-md border border-og-100 bg-surface px-2.5 py-1.5",children:[t.jsx("span",{title:C.name,className:"truncate text-xs text-og-700",children:C.name}),t.jsx("button",{type:"button","aria-label":`移除图片 ${C.name}`,onClick:()=>S(D),disabled:w,className:"ml-2 shrink-0 text-og-400 transition-colors",children:"✕"})]},`${C.name}-${D}`))})]})]})})}const Zt="***",ht={hostname:"",port:"",alias:"",user:"",password:""};function wr(e){return e.alias?e.alias:`${e.user?`${e.user}@`:""}${e.hostname}${e.port!=null?`:${e.port}`:""}`}function yr({open:e,onClose:s}){var ue;const[n,i]=a.useState([]),[r,o]=a.useState("list"),[l,u]=a.useState(null),[m,h]=a.useState(null),[v,d]=a.useState(!1),[f,p]=a.useState(!1),[x,N]=a.useState(ht),[j,k]=a.useState(null),[R,E]=a.useState(!1),[b,y]=a.useState(!1),[w,_]=a.useState(null),[L,T]=a.useState(!1),[F,O]=a.useState(null),M=a.useRef(0),z=a.useRef(null),{show:X}=ve(),$=a.useCallback(()=>{I.hosts.list().then(i).catch(A=>k(A instanceof Error?A.message:String(A)))},[]);a.useEffect(()=>{if(!e){z.current&&z.current.abort();return}o("list"),u(null),h(null),N(ht),k(null),$()},[e,$]),a.useEffect(()=>{M.current+=1,z.current&&z.current.abort(),y(!1),_(null),T(!1),O(null)},[x.hostname,x.user,x.port,x.password,f,r]),a.useEffect(()=>()=>{z.current&&z.current.abort()},[]);const Z=()=>{u(null),h(null),d(!1),p(!1),N(ht),k(null),o("form")},q=A=>{u(A.id??null),h(A),d(A.password===Zt),p(!1),N({hostname:A.hostname,port:A.port!=null?String(A.port):"",alias:A.alias??"",user:A.user??"",password:""}),k(null),o("form")},V=()=>{const A={hostname:x.hostname.trim()};return l?(A.port=x.port.trim()?Number(x.port):null,A.alias=x.alias.trim(),A.user=x.user.trim()):(x.port.trim()&&(A.port=Number(x.port)),x.alias.trim()&&(A.alias=x.alias.trim()),x.user.trim()&&(A.user=x.user.trim())),l&&f?A.password="":x.password&&(A.password=x.password),A},U=x.port.trim(),Q=U===""||/^\d+$/.test(U)&&Number(U)>0&&Number(U)<=65535,se=x.hostname.trim().length>0&&Q,de=!!m&&x.hostname.trim()===m.hostname&&x.user.trim()===(m.user??"")&&x.port.trim()===(m.port!=null?String(m.port):""),B=()=>l&&de&&!x.password&&!f?{hostId:l}:{host:{hostname:x.hostname.trim(),...x.user.trim()?{user:x.user.trim()}:{},...U?{port:Number(U)}:{},...!f&&x.password?{password:x.password}:{}}},ie=async()=>{if(!se||b)return;z.current&&z.current.abort();const A=new AbortController;z.current=A;const c=M.current;y(!0),_(null),O(null),k(null);try{const g=await I.agents.probe("remote",B(),{signal:A.signal});if(A.signal.aborted||M.current!==c)return;_(g)}catch(g){if(A.signal.aborted||M.current!==c)return;k(g instanceof Error?g.message:String(g))}finally{M.current===c&&y(!1)}},re=async()=>{if(L)return;const A=M.current;T(!0),O(null),k(null);try{const c=await I.agents.installTmux("remote",B());if(M.current!==A)return;O({ok:c.ok,message:c.message}),_(g=>g&&{...g,tmux:c.tmux})}catch(c){if(M.current!==A)return;k(c instanceof Error?c.message:String(c))}finally{M.current===A&&T(!1)}},le=async A=>{if(A.preventDefault(),!(!se||R)){E(!0),k(null);try{if(l)await I.hosts.update(l,V()),X({kind:"success",title:`Host ${l} 已更新`});else{const c=await I.hosts.create(V());X({kind:"success",title:`Host ${c.host.id} 已添加`})}$(),o("list")}catch(c){k(c instanceof Error?c.message:String(c))}finally{E(!1)}}},oe=async A=>{k(null);try{await I.hosts.delete(A.id),X({kind:"success",title:`Host ${A.id} 已删除`}),$()}catch(c){k(c instanceof Error?c.message:String(c))}},me=t.jsx("button",{type:"button",onClick:s,className:"btn-secondary",children:"关闭"}),ce=t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:()=>o("list"),disabled:R,className:"btn-secondary",children:"返回"}),t.jsx("button",{type:"submit",form:"host-form",disabled:!se||R,className:"btn-primary",children:R?"保存中…":"保存"})]});return t.jsxs(Ne,{open:e,onClose:s,title:"Host 管理",size:"md",footer:r==="list"?me:ce,children:[j&&t.jsx("div",{className:"mb-3 rounded-md border border-accent/25 bg-accent-soft px-3 py-2 text-sm text-accent",children:j}),r==="list"?t.jsxs("div",{className:"space-y-3",children:[n.length===0?t.jsx("p",{className:"text-sm text-og-500",children:"还没有配置 Host。点击下方「添加 Host」。"}):t.jsx("ul",{className:"space-y-1.5",children:n.map(A=>t.jsxs("li",{className:"flex items-center justify-between gap-3 rounded-md border border-og-100 px-3 py-2",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsx("div",{className:"truncate text-sm font-medium text-og-800",children:wr(A)}),t.jsxs("div",{className:"truncate text-xs text-og-500",children:[(A.user?`${A.user}@`:"")+A.hostname,A.port!=null?`:${A.port}`:"",A.password===Zt?" · 密码已保存":""]})]}),t.jsxs("div",{className:"flex shrink-0 gap-2",children:[t.jsx("button",{type:"button",onClick:()=>q(A),className:"text-xs text-accent transition-colors hover:text-accent-hover",children:"编辑"}),t.jsx("button",{type:"button",onClick:()=>oe(A),className:"text-xs text-accent transition-colors hover:opacity-80",children:"删除"})]})]},A.id))}),t.jsx("button",{type:"button",onClick:Z,className:"btn-secondary w-full",children:"+ 添加 Host"})]}):t.jsxs("form",{id:"host-form",onSubmit:le,className:"space-y-3",children:[t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host-hostname",children:"Host 地址"}),t.jsx("input",{id:"host-hostname",type:"text",value:x.hostname,onChange:A=>N({...x,hostname:A.target.value}),className:ae,placeholder:"remote.example.com",disabled:R})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host-port",children:"端口(可选)"}),t.jsx("input",{id:"host-port",type:"text",inputMode:"numeric",value:x.port,onChange:A=>N({...x,port:A.target.value}),className:ae,placeholder:"22",disabled:R}),x.port.trim()!==""&&!Q&&t.jsx("div",{className:"mt-1 text-xs text-accent",children:"端口需为 1–65535 的整数"})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host-alias",children:"别名(可选)"}),t.jsx("input",{id:"host-alias",type:"text",value:x.alias,onChange:A=>N({...x,alias:A.target.value}),className:ae,placeholder:"Prod worker",disabled:R})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host-user",children:"用户名(可选)"}),t.jsx("input",{id:"host-user",type:"text",value:x.user,onChange:A=>N({...x,user:A.target.value}),className:ae,placeholder:"留空则读 ~/.ssh/config 的 User",disabled:R})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host-password",children:"密码(可选)"}),t.jsx("input",{id:"host-password",type:"password",value:f?"":x.password,onChange:A=>N({...x,password:A.target.value}),className:ae,placeholder:v?"已设置,留空保持不变":"留空使用 key 认证",disabled:R||f,autoComplete:"new-password"}),l&&v&&t.jsxs("label",{className:"mt-1.5 flex items-center gap-2 text-xs text-og-700",children:[t.jsx("input",{type:"checkbox",className:"h-3.5 w-3.5 accent-accent",checked:f,onChange:A=>p(A.target.checked),disabled:R}),"清除已保存的密码(改用 key 登录)"]})]}),t.jsxs("div",{className:"rounded-md border border-accent/25 bg-accent-soft/60 px-3 py-2.5 text-xs text-accent",children:["建议为该 Host 配置好",t.jsx("strong",{className:"font-semibold",children:"免密码登入(SSH key)"}),"。 否则填写的密码将以",t.jsx("strong",{className:"font-semibold",children:"明文"}),"保存到 baxian.json 中。"]}),t.jsxs("div",{className:"space-y-1.5",children:[t.jsx("button",{type:"button",onClick:ie,disabled:!se||b||R||L,className:"text-xs text-accent transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",children:b?"测试中…":"测试连接"}),(w==null?void 0:w.ssh)&&t.jsxs("div",{className:`text-xs ${w.ssh.ok?"text-og-800":"text-accent"}`,children:["SSH: ",w.ssh.ok?"✓":"⨯"," ",w.ssh.message]}),w&&(w.tmux.ok?t.jsxs("div",{className:"text-xs text-og-800",children:["tmux: ✓ ",w.tmux.path??""]}):t.jsxs("div",{className:"text-xs text-accent",children:["tmux: ⨯ ",w.tmux.message,((ue=w.ssh)==null?void 0:ue.ok)&&t.jsx("button",{type:"button",onClick:re,disabled:L||R,className:"ml-2 text-accent underline transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",children:L?"安装中…":"一键安装"})]})),L&&t.jsx("div",{className:"text-xs text-og-500",children:"正在安装 tmux,可能需要几分钟,请勿关闭窗口…"}),!L&&F&&t.jsxs("div",{className:`break-all text-xs ${F.ok?"text-og-800":"text-accent"}`,children:[F.ok?"✓ ":"⨯ ",F.message]})]})]})]})}const $s="topbar-actions";function es(){return typeof document>"u"?null:document.getElementById($s)}function Ts({children:e}){const[s,n]=a.useState(es);return a.useEffect(()=>{s||n(es())},[s]),s?Js.createPortal(e,s):null}function Nr(e){return Array.from(new TextEncoder().encode(e)).map(s=>s.toString(16).padStart(2,"0")).join("")}function Sr(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/realtime`}const kr=(e,s)=>s&&s.length>0?new WebSocket(e,s):new WebSocket(e);class Er{constructor(s={}){te(this,"wsUrl");te(this,"wsFactory");te(this,"tokenProvider");te(this,"ws",null);te(this,"topics",new Map);te(this,"cache",new Map);te(this,"outbox",[]);te(this,"reconnectScheduler");te(this,"explicitlyClosed",!1);this.wsUrl=s.wsUrl??Sr(),this.wsFactory=s.wsFactory??kr,this.tokenProvider=s.tokenProvider??Et,this.reconnectScheduler=new Ns({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.topics.size>0})}subscribe(s,n,i){let r=this.topics.get(s);const o=!r;return r||(r={data:new Set,error:new Set},this.topics.set(s,r)),r.data.add(n),i&&r.error.add(i),o?(this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",topic:s})):this.cache.has(s)&&queueMicrotask(()=>{var l;(l=this.topics.get(s))!=null&&l.data.has(n)&&this.cache.has(s)&&n(this.cache.get(s))}),()=>this.unsubscribe(s,n,i)}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.topics.clear(),this.cache.clear(),this.outbox=[]}unsubscribe(s,n,i){const r=this.topics.get(s);r&&(r.data.delete(n),i&&r.error.delete(i),r.data.size===0&&r.error.size===0&&(this.topics.delete(s),this.cache.delete(s),this.wsSendOrQueue({op:"unsubscribe",topic:s}),this.topics.size===0&&this.teardownSocket()))}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const s=this.tokenProvider(),n=s?[`baxian.token.${Nr(s)}`]:void 0;let i;try{i=this.wsFactory(this.wsUrl,n)}catch(o){console.warn("[events-client] WebSocket constructor threw:",o),this.broadcastConnectionError({code:"connection_failed",message:o instanceof Error?o.message:"WebSocket constructor threw"}),this.scheduleReconnect();return}this.ws=i;let r=!1;i.onopen=()=>{if(i!==this.ws)return;r=!0,this.reconnectScheduler.reset();for(const l of this.topics.keys())try{i.send(JSON.stringify({op:"subscribe",topic:l}))}catch(u){console.warn("[events-client] resubscribe send failed:",u)}const o=this.outbox;this.outbox=[];for(const l of o)if(!(l.op==="subscribe"||l.op==="unsubscribe"))try{i.send(JSON.stringify(l))}catch(u){console.warn("[events-client] outbox flush failed:",u)}},i.onmessage=o=>{if(i!==this.ws)return;let l;try{const u=typeof o.data=="string"?o.data:String(o.data);l=JSON.parse(u)}catch{return}this.handleMessage(l)},i.onclose=()=>{i===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()))},i.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}broadcastConnectionError(s){for(const n of this.topics.values())for(const i of[...n.error])try{i(s)}catch(r){console.error("[events-client] error handler threw on connection error:",r)}}wsSendOrQueue(s){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(s));return}catch(n){console.warn("[events-client] send failed, will queue:",n)}this.outbox.push(s)}handleMessage(s){switch(s.type){case"data":{const n=this.topics.get(s.topic);if(this.cache.set(s.topic,s.data),!n)return;for(const i of[...n.data])try{i(s.data)}catch(r){console.error(`[events-client] handler threw on ${s.topic}:`,r)}break}case"error":{const n={code:s.code,message:s.message};if(s.topic){const i=this.topics.get(s.topic);if(i)for(const r of[...i.error])try{r(n)}catch(o){console.error(`[events-client] error handler threw on ${s.topic}:`,o)}}else console.warn("[events-client] connection-level error:",s.code,s.message);break}}}}let xt=null;function it(){return xt||(xt=new Er),xt}function It(){const[e,s]=a.useState(null),[n,i]=a.useState(!1),[r,o]=a.useState(null);return a.useEffect(()=>it().subscribe("agents",u=>{o(null),s(u),i(!0)},u=>o(u)),[]),{data:e,loaded:n,error:r}}function Pt(e){const[s,n]=a.useState(null),[i,r]=a.useState(!1),[o,l]=a.useState(null);return a.useEffect(()=>(n(null),r(!1),l(null),it().subscribe(`task:${e}`,m=>{l(null),n(m),r(!0)},m=>l(m))),[e]),{data:s,loaded:i,error:o}}function Is(e){const[s,n]=a.useState(null),[i,r]=a.useState(!1),[o,l]=a.useState(null);return a.useEffect(()=>{if(!e){n(null),r(!1),l(null);return}n(null),r(!1),l(null);let u=!1,m=!1,h=!1;const v=it().subscribe(`project-tasks:${e}`,d=>{u||(m=!0,l(null),n(d),r(!0))},d=>{u||(l(d),!(m||h)&&(h=!0,I.tasks.list(e).then(f=>{u||m||(n(f),r(!0))},f=>{console.warn(`[useProjectTasks] REST fallback failed for ${e}:`,f)})))});return()=>{u=!0,v()}},[e]),{data:s,loaded:i,error:o}}let Ze=null,ye=null,et=null,Oe=0;const jt=new Set;function Ps(){jt.forEach(e=>e())}async function Rr(){const e=Oe;try{const s=await I.projects.list();if(e!==Oe)return;Ze=s,et=null}catch(s){if(e!==Oe)return;et=s instanceof Error?s.message:String(s)}finally{e===Oe&&(ye=null,Ps())}}function wt(){return ye||(ye=Rr(),ye)}function Cr(){Oe+=1,Ze=null,ye=null,et=null,Ps()}typeof window<"u"&&window.addEventListener(Je,Cr);async function Ar(){const e=ye!==null;await wt(),e&&await wt()}function Ue(){const[,e]=a.useState(0);return a.useEffect(()=>{const s=()=>e(n=>n+1);return jt.add(s),Ze===null&&!ye&&wt(),()=>{jt.delete(s)}},[]),{projects:Ze,error:et,refresh:Ar}}const Dt="baxian.taskNotifications.enabled";function Lt(){if(typeof window>"u")return null;const e=window.Notification;return typeof e=="function"?e:null}function Qe(){const e=Lt();return e?e.permission:"unsupported"}function pt(){try{return localStorage.getItem(Dt)!=="0"}catch{return!0}}function Ke(e){try{localStorage.setItem(Dt,e?"1":"0")}catch{}}const Ds=a.createContext(null);function $r({children:e}){const[s,n]=a.useState(Qe),[i,r]=a.useState(pt),[o,l]=a.useState(!1),u=a.useRef(!1),m=a.useRef(0);a.useEffect(()=>{const d=()=>{n(Qe()),u.current||r(pt())},f=p=>{if(p.key!==null&&p.key!==Dt)return;n(Qe());const x=p.key===null?pt():p.newValue!=="0";x||(m.current+=1),r(x)};return window.addEventListener("focus",d),window.addEventListener("storage",f),()=>{window.removeEventListener("focus",d),window.removeEventListener("storage",f)}},[]);const h=a.useCallback(()=>{r(!0);const d=Lt();if(!d){Ke(!0);return}if(d.permission!=="default"){n(d.permission),Ke(!0);return}if(u.current)return;u.current=!0,l(!0);const f=m.current;d.requestPermission().then(n).catch(p=>{console.warn("[task-notifications] permission request failed:",p),n(Qe())}).finally(()=>{m.current===f&&Ke(!0),u.current=!1,l(!1)})},[]),v=a.useCallback(()=>{m.current+=1,r(!1),Ke(!1)},[]);return t.jsx(Ds.Provider,{value:{permission:s,preferenceEnabled:i,enabled:s==="granted"&&i,requesting:o,enable:h,disable:v},children:e})}function Ls(){const e=a.useContext(Ds);if(!e)throw new Error("useTaskNotifications must be used inside TaskNotificationsProvider");return e}function Tr(){const e=pe(),{projects:s,error:n,refresh:i}=Ue(),r=s??[],o=s!==null,[l,u]=a.useState(!1),[m,h]=a.useState(!1),[v,d]=a.useState(!1),[f,p]=a.useState({kind:"closed"}),{data:x,loaded:N,error:j}=It(),k=(j==null?void 0:j.message)??null,R=new Map((x??[]).map(w=>[w.id,w])),E=n??k,b=r.length===0,y=t.jsx("button",{type:"button",onClick:()=>h(!0),disabled:b,"aria-describedby":b?"create-task-hint":void 0,className:"btn-ghost",children:"+ 新建任务"});return t.jsxs("div",{children:[t.jsxs(Ts,{children:[b?t.jsx("span",{className:"inline-flex",title:"请先创建项目",children:y}):y,b&&t.jsx("span",{id:"create-task-hint",className:"sr-only",children:"请先创建项目"}),t.jsx(St,{ariaLabel:"更多操作",children:w=>t.jsxs(t.Fragment,{children:[t.jsx(he,{onClick:()=>{w(),u(!0)},children:"新建项目"}),t.jsx(he,{onClick:()=>{w(),d(!0)},children:"Host 管理"}),t.jsx(Ir,{onAction:w})]})})]}),t.jsx("h1",{className:"sr-only",children:"Dashboard"}),E&&t.jsxs("div",{className:"mb-4 text-sm text-accent",children:["加载失败:",E]}),o&&r.length===0&&!n&&t.jsx("div",{className:"rounded-lg border border-hairline bg-surface py-12 text-center text-sm text-og-500",children:'还没有项目。点击右上角"更多"菜单 → "新建项目"开始。'}),r.map(w=>t.jsx(Pr,{project:w,agentsById:R,agentsLoaded:N,agentsError:!!j,onAgentDeleted:i},w.id)),t.jsx(hr,{open:l,onClose:()=>u(!1),onCreated:w=>{u(!1),i(),p({kind:"asking",projectId:w})}}),t.jsx(yr,{open:v,onClose:()=>d(!1)}),t.jsx(Ne,{open:f.kind==="asking",onClose:()=>p({kind:"closed"}),title:"项目已创建",size:"sm",footer:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:()=>p({kind:"closed"}),className:"btn-secondary",children:"稍后再加"}),t.jsx("button",{type:"button",onClick:()=>{f.kind==="asking"&&p({kind:"addingAgent",projectId:f.projectId})},className:"btn-primary",children:"继续添加 Agent"})]}),children:t.jsx("p",{className:"text-sm text-og-700",children:"现在添加第一个 Agent,还是稍后再加?"})}),f.kind==="addingAgent"&&t.jsx(As,{open:!0,projectId:f.projectId,onClose:()=>p({kind:"closed"}),onCreated:()=>{i()}}),t.jsx(Tt,{open:m,onClose:()=>h(!1),onCreated:w=>e(Ce(w.projectId,w.id))})]})}function Ir({onAction:e}){const{permission:s,enabled:n,requesting:i,enable:r,disable:o}=Ls();return s==="unsupported"?null:s==="denied"?t.jsx(he,{disabled:!0,children:"浏览器已拒绝任务完成通知"}):t.jsx(he,{disabled:i,onClick:()=>{e(),n?o():r()},children:n?"关闭任务完成通知":"开启任务完成通知"})}function Pr({project:e,agentsById:s,agentsLoaded:n,agentsError:i,onAgentDeleted:r}){const{data:o,error:l}=Is(e.id),u=o??[],m=(l==null?void 0:l.message)??null;return t.jsxs("div",{className:"mb-10",children:[t.jsxs("div",{className:"mb-3 -mx-2 flex items-baseline gap-x-3 gap-y-1 px-2 py-1",children:[t.jsx("h2",{className:"min-w-0 truncate font-display text-sm font-semibold tracking-tight text-og-1000",title:e.id,children:t.jsx(Be,{to:`/project/${e.id}`,className:"hover:text-accent-hover",children:e.id})}),t.jsx("span",{className:"hidden min-w-0 truncate font-mono text-xs text-og-500 sm:inline-block",title:e.repo,children:e.repo}),t.jsx(Be,{to:`/project/${e.id}`,className:"ml-auto text-sm text-accent hover:text-accent-hover","aria-label":`详情 — ${e.id}`,children:"详情 →"})]}),m&&t.jsxs("div",{className:"mb-2 text-xs text-accent",children:["任务列表加载失败:",m]}),e.agent.flat().length===0?t.jsx("div",{className:"rounded-lg border border-hairline bg-surface py-6 text-center text-sm text-og-500",children:"还没有 Agent。进入 Details 添加。"}):t.jsx("div",{className:e.agent.length===1?"space-y-3":"grid grid-cols-1 gap-3 xl:grid-cols-2",children:e.agent.map((h,v)=>t.jsx(Cs,{group:h,projectId:e.id,agentsById:s,agentsLoaded:n,agentsError:i,tasks:u,onDeleted:r,terminalMode:"embedded-full"},h.map(d=>d.id).join(":")||v))})]})}const Ms="baxian.taskPanel.doneOpen";function Dr(){try{return localStorage.getItem(Ms)==="1"}catch{return!1}}function tt(e){const s=e.match(/^task-(\d+)$/);return s?parseInt(s[1],10):Number.NaN}function Lr(e,s){const n=tt(e.id),i=tt(s.id);return Number.isNaN(n)||Number.isNaN(i)?e.id.localeCompare(s.id):n-i}function Mr(e,s){const n=(s.updatedAt??"").localeCompare(e.updatedAt??"");if(n!==0)return n;const i=tt(e.id),r=tt(s.id);return Number.isNaN(i)||Number.isNaN(r)?s.id.localeCompare(e.id):r-i}function ts(e,s){const[n,i]=a.useState(at);a.useEffect(()=>i(at),[s]);const r=e.slice(0,n),o=e.length>r.length;return{items:r,hasMore:o,loadMore:()=>i(u=>u+at),total:e.length}}function _r(e){const[s,n]=a.useState([]),[i,r]=a.useState(!1),[o,l]=a.useState(!1),[u,m]=a.useState(!1),[h,v]=a.useState(null),d=a.useRef(0),f=a.useRef(0),p=a.useCallback(x=>{const N=++d.current,j=x==="first"?0:f.current;l(!0),v(null),I.tasks.page(e,{category:"done",offset:j}).then(k=>{d.current===N&&(n(R=>x==="first"?k.tasks:[...R,...k.tasks]),r(k.hasMore),f.current=k.nextOffset,m(!0),l(!1))},k=>{d.current===N&&(v(k instanceof Error?k.message:String(k)),l(!1))})},[e]);return a.useEffect(()=>{d.current+=1,f.current=0,n([]),r(!1),m(!1),v(null),l(!1)},[e]),{items:s,hasMore:i,loading:o,loaded:u,error:h,load:p}}function Or({projectId:e,openTasks:s,className:n=""}){const i=a.useMemo(()=>s.filter(d=>ps.has(d.status)).sort(Mr),[s]),r=a.useMemo(()=>s.filter(d=>d.status==="pending").sort(Lr),[s]),o=ts(i,e),l=ts(r,e),u=_r(e),[m,h]=a.useState(Dr);a.useEffect(()=>{try{localStorage.setItem(Ms,m?"1":"0")}catch{}},[m]),a.useEffect(()=>{m&&u.load("first")},[m,u.load]);const v=()=>h(d=>!d);return t.jsx("aside",{"aria-label":"任务面板",className:`flex flex-col rounded-lg border border-hairline bg-surface ${n}`,children:t.jsxs("div",{children:[t.jsx(ss,{title:"IN PROGRESS",section:o,emptyHint:"暂无正在处理的任务"}),t.jsx(ss,{title:"PENDING",section:l,emptyHint:"暂无待处理的任务"}),t.jsxs("div",{children:[t.jsxs("button",{type:"button",onClick:v,"aria-expanded":m,className:"flex w-full items-center justify-between px-3 py-2 text-left text-xs font-normal uppercase tracking-[0.05em] text-og-500 transition-colors hover:bg-og-50/40",children:[t.jsx("span",{children:"DONE"}),t.jsx("span",{className:"font-normal normal-case text-accent",children:m?"收起":"查看"})]}),m&&t.jsx(Fr,{state:u})]})]})})}function ss({title:e,section:s,emptyHint:n}){return t.jsxs("section",{"aria-label":e,className:"border-b border-hairline",children:[t.jsxs("div",{className:"px-3 py-2 text-xs font-normal uppercase tracking-[0.05em] text-og-500",children:[e," ",t.jsxs("span",{className:"text-og-400",children:["(",s.total,")"]})]}),s.items.length===0?t.jsx("div",{className:"px-3 pb-3 text-xs text-og-400",children:n}):t.jsxs("div",{className:"divide-y divide-hairline",children:[s.items.map(i=>t.jsx(_s,{task:i},i.id)),s.hasMore&&t.jsx("button",{type:"button",onClick:s.loadMore,className:"w-full px-3 py-2 text-center text-xs text-accent transition-colors hover:bg-og-50/40",children:"加载更多"})]})]})}function Fr({state:e}){const s=e.loaded&&!e.error&&e.items.length===0;return t.jsxs("div",{className:"divide-y divide-hairline",children:[e.items.map(n=>t.jsx(_s,{task:n},n.id)),e.error&&t.jsxs("div",{className:"px-3 py-2 text-xs text-accent",children:["加载失败:",e.error]}),s&&t.jsx("div",{className:"px-3 pb-3 pt-1 text-xs text-og-400",children:"暂无已处理的任务"}),e.loading&&e.items.length===0&&t.jsx("div",{className:"px-3 py-3 text-center text-xs text-og-400",children:"加载中…"}),e.hasMore&&t.jsx("button",{type:"button",onClick:()=>e.load("more"),disabled:e.loading,className:"w-full px-3 py-2 text-center text-xs text-accent transition-colors hover:bg-og-50/40 disabled:opacity-50",children:e.loading?"加载中…":"加载更多"})]})}function Br(e){const[s,n]=a.useState(!1);return a.useEffect(()=>{function i(){if(e.status!=="review"||!e.reviewDispatchedAt||!e.qaAgentId){n(!1);return}n(Date.now()-Date.parse(e.reviewDispatchedAt)>=gs)}i();const r=setInterval(i,3e4);return()=>clearInterval(r)},[e.status,e.reviewDispatchedAt,e.qaAgentId]),s}function _s({task:e}){const s=pe(),n=e.phase==="spec"?e.specReviewRound??0:e.reviewRound,i=Br(e);return t.jsxs("button",{type:"button",onClick:()=>s(Ce(e.projectId,e.id)),className:"flex w-full items-center gap-2 px-3 py-2 text-left text-sm transition-colors hover:bg-og-50/60",children:[t.jsx("span",{className:"shrink-0 font-mono text-xs text-og-500",title:e.id,children:$t(e.id)}),t.jsx("span",{className:"min-w-0 flex-1 truncate text-og-1000",title:e.title,children:e.title}),e.phase==="spec"&&t.jsx("span",{className:"pill pill-review shrink-0",children:"spec"}),i&&t.jsx("span",{className:"pill pill-warn shrink-0",title:"Review verdict missing",children:"!"}),t.jsxs("span",{"aria-label":`第 ${n} 轮`,className:"shrink-0 text-xs text-og-400",children:["R",n]}),t.jsx(cr,{status:e.status})]})}const Hr=[],Os="baxian.taskPanel.open";function Ur(){try{return localStorage.getItem(Os)!=="0"}catch{return!0}}function qr(){const{id:e}=He(),s=pe(),{show:n}=ve(),{refresh:i}=Ue(),[r,o]=a.useState(null),[l,u]=a.useState(null),[m,h]=a.useState(!1),[v,d]=a.useState(!1),f=a.useRef(null),[p,x]=a.useState(Ur),[N,j]=a.useState(!1),[k,R]=a.useState(""),[E,b]=a.useState(!1),[y,w]=a.useState(null),_=a.useRef(0),{data:L,loaded:T,error:F}=It(),{data:O,error:M}=Is(e),z=(F==null?void 0:F.message)??null,X=(M==null?void 0:M.message)??null,$=O??Hr,Z=new Map((L??[]).map(B=>[B.id,B])),q=l??z??X,V=a.useCallback(async B=>{const ie=++_.current;try{const re=await I.projects.get(B);if(ie!==_.current)return;o(re),u(null)}catch(re){if(ie!==_.current)return;u(re instanceof Error?re.message:String(re))}},[]);a.useEffect(()=>{e&&(o(null),u(null),V(e))},[e,V]),a.useEffect(()=>{N||(R(""),w(null))},[N]),a.useEffect(()=>{try{localStorage.setItem(Os,p?"1":"0")}catch{}},[p]);const U=(r==null?void 0:r.agent.flat().length)??0,Q=U===0,se=!!r&&k.trim()===r.id,de=async()=>{if(!(!r||!se||E)){b(!0),w(null);try{await I.projects.delete(r.id),await i(),n({kind:"success",title:`项目 ${r.id} 已删除`}),j(!1),s("/")}catch(B){w(B instanceof Error?B.message:String(B))}finally{b(!1)}}};return r?t.jsxs("div",{children:[t.jsxs(Ts,{children:[t.jsx("button",{type:"button",onClick:()=>d(!0),className:"btn-ghost",children:"+ 新建任务"}),t.jsx(St,{ariaLabel:`项目 ${r.id} 操作菜单`,menuClassName:"min-w-[180px]",triggerRef:f,children:B=>t.jsxs(t.Fragment,{children:[!p&&t.jsx(he,{onClick:()=>{B(),x(!0)},children:"显示任务面板"}),t.jsx(he,{onClick:()=>{B(),h(!0)},children:"添加 Agent"}),t.jsx("div",{role:"none",className:"my-1 border-t border-hairline"}),t.jsx(he,{onClick:()=>{B(),j(!0)},disabled:!Q,title:Q?void 0:`请先删除项目下的 ${U} 个 Agent`,children:"删除项目…"})]})})]}),q&&t.jsxs("div",{className:"mb-4 text-sm text-accent",children:["加载失败:",q]}),t.jsxs("div",{className:"mb-6 flex items-baseline gap-x-3",children:[t.jsx("h1",{className:"min-w-0 truncate font-display text-sm font-semibold tracking-tight text-og-1000",title:r.id,children:r.id}),t.jsx("span",{className:"hidden min-w-0 truncate font-mono text-xs text-og-500 sm:inline-block",title:r.repo,children:r.repo})]}),t.jsxs("div",{className:"flex flex-col gap-4 lg:flex-row lg:items-start",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsx("div",{className:"mb-3 flex h-8 items-center gap-2",children:t.jsx("h2",{className:"font-display text-xs font-semibold uppercase tracking-[0.06em] text-og-500",children:"Agents"})}),r.agent.flat().length===0?t.jsx("div",{className:"mb-8 rounded-lg border border-hairline bg-surface py-6 text-center text-sm text-og-500",children:"还没有 Agent,点击右上角菜单添加。"}):t.jsx("div",{className:"mb-8 space-y-5",children:r.agent.map((B,ie)=>t.jsx(Cs,{group:B,projectId:r.id,agentsById:Z,agentsLoaded:T,agentsError:!!F,tasks:$,onDeleted:()=>{V(r.id)},terminalMode:"embedded-full"},B.map(re=>re.id).join(":")||ie))})]}),p&&t.jsxs("div",{className:"w-full lg:w-[340px] lg:shrink-0 xl:w-[380px]",children:[t.jsxs("div",{className:"mb-3 flex h-8 items-center justify-between gap-2",children:[t.jsx("h2",{className:"font-display text-xs font-semibold uppercase tracking-[0.06em] text-og-500",children:"Tasks"}),t.jsx("button",{type:"button",onClick:()=>{var B;x(!1),(B=f.current)==null||B.focus()},"aria-label":"关闭任务面板",className:"flex h-7 w-7 items-center justify-center rounded text-og-500 transition-colors hover:bg-og-50 hover:text-og-1000",children:t.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[t.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),t.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),t.jsx(Or,{projectId:r.id,openTasks:$})]})]}),t.jsx(As,{open:m,projectId:r.id,onClose:()=>h(!1),onCreated:()=>{V(r.id)}}),t.jsx(Tt,{open:v,projectId:r.id,onClose:()=>d(!1),onCreated:B=>s(Ce(B.projectId,B.id))}),t.jsx(Ne,{open:N,onClose:()=>{E||j(!1)},title:"删除项目",size:"sm",footer:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:()=>j(!1),disabled:E,className:"btn-secondary",children:"取消"}),t.jsx("button",{type:"button",onClick:()=>void de(),disabled:!se||E,className:"btn-primary",children:E?"删除中…":"确认删除"})]}),children:t.jsxs("div",{className:"space-y-4",children:[t.jsxs("p",{className:"text-sm text-og-700",children:["将从 ",t.jsx("code",{className:"font-mono text-og-1000",children:"baxian.json"})," 中移除项目"," ",t.jsx("span",{className:"font-mono text-og-1000",children:r.id}),"。此操作不可撤销,且不会删除 Git 仓库本身。"]}),t.jsxs("p",{className:"text-sm text-og-700",children:["如需确认,请在下方输入项目 ID ",t.jsx("span",{className:"font-mono text-og-1000",children:r.id}),":"]}),t.jsx("input",{type:"text",value:k,onChange:B=>R(B.target.value),placeholder:r.id,autoComplete:"off",autoCorrect:"off",spellCheck:!1,disabled:E,"aria-label":"输入项目 ID 以确认删除",className:"w-full rounded border border-hairline bg-surface px-3 py-2 font-mono text-sm text-og-1000 focus:border-accent focus:outline-none"}),y&&t.jsx("div",{className:"rounded-md border border-accent/25 bg-accent-soft px-3 py-2 text-xs text-accent",children:y})]})})]}):l?t.jsxs("div",{className:"text-sm text-accent",children:["Error: ",l]}):t.jsx("div",{className:"text-sm text-og-500",children:"Loading…"})}function Fs(e,s){const[n,i]=a.useState(null),[r,o]=a.useState(!1),[l,u]=a.useState(null),m=a.useRef(e);return a.useEffect(()=>{let h=!0;return m.current!==e&&(m.current=e,i(null),o(!1)),u(null),I.tasks.reviews(e).then(v=>{h&&(i(v),o(!0))}).catch(v=>{h&&(u(v instanceof Error?v.message:String(v)),i([]),o(!0))}),()=>{h=!1}},[e,s]),{rounds:n,loaded:r,error:l}}const Bs={approve:"pill pill-live","request-changes":"pill pill-warn",comment:"pill"};function Hs(e){const s=[];let n=[];for(const i of e)i.kind==="review"?(s.push({items:n,review:i}),n=[]):n.push(i);return n.length>0&&s.push({items:n}),s}function st(e,s){return`${e.kind}-${e.id||e.commitSha||e.createdAt||e.body||s}`}function Us(e,s){return e.review?`round-${st(e.review,s)}`:`round-in-progress-${e.items[0]?st(e.items[0],s):s}`}function qs(e){return`${e.reviewRound}:${e.latestHeadSha??""}:${e.status}:${e.reviewDispatchedAt??""}:${e.prFeedbackReceivedAt??""}`}function Ws(e,s){const[n,i]=a.useState(null),[r,o]=a.useState(!1),[l,u]=a.useState(null),m=a.useRef(e),h=a.useRef(s),v=a.useRef(0),d=a.useRef(!1);return a.useEffect(()=>{if(m.current!==e)m.current=e,d.current=!1,i(null),o(!1);else if(h.current===void 0&&s!==void 0&&d.current){h.current=s;return}h.current=s;const p=++v.current;u(null),I.tasks.githubReview(e).then(x=>{v.current===p&&(d.current=x.available===!0&&!x.error,i(x),o(!0))}).catch(x=>{v.current===p&&(d.current=!1,u(x instanceof Error?x.message:String(x)),i(null),o(!0))})},[e,s]),{data:n,loaded:r,error:l}}function Fe({role:e,label:s,summary:n,badge:i,onClick:r}){return t.jsxs("button",{type:"button",onClick:r,className:"card flex w-full items-center gap-2 px-3 py-2 text-left text-sm",children:[t.jsx("span",{className:"shrink-0 min-w-[1.75rem] text-xs tracking-wide text-og-600",children:e==="qa"?"QA":e==="user"?"用户":"Dev"}),t.jsx("span",{className:"shrink-0 text-og-800",children:s}),i,t.jsx("span",{className:"min-w-0 flex-1 truncate text-og-500",children:n}),t.jsx("span",{"aria-hidden":!0,className:"shrink-0 text-og-300",children:"›"})]})}const ns={"server-mode":"该 task 为 server 评审模式,代码评审记录见 server 评审轮次。","no-pr":"该 task 还没有 PR,暂无代码评审记录。","not-github":"该 task 的仓库不是 GitHub 仓库,无法拉取 PR 评审记录。"};function Wr(e){return(e==null?void 0:e.trim().split(`
4
+ /Users/me/extra-repo`,disabled:b}),t.jsx("div",{className:ft,children:"透传到 --add-dir。当前 YOLO 模式下不影响权限拦截,主要用于让 CLI 把额外目录纳入工作根。"})]})]})]}),t.jsx("div",{className:"rounded-md border border-accent/25 bg-accent-soft/60 px-3 py-2.5",children:t.jsxs("label",{className:"flex cursor-pointer items-start gap-2",children:[t.jsx("input",{type:"checkbox",className:"mt-1 h-3.5 w-3.5 accent-accent",checked:r.yolo,onChange:g=>o({...r,yolo:g.target.checked}),disabled:b}),t.jsxs("div",{className:"text-sm text-og-800",children:[t.jsx("div",{className:"font-medium",children:"YOLO 模式(推荐开启)"}),t.jsxs("div",{className:"mt-1 text-xs text-accent",children:["开启后 Claude Code 以 ",t.jsx("code",{children:"--permission-mode bypassPermissions"})," 启动, Codex 以 ",t.jsx("code",{children:"--dangerously-bypass-approvals-and-sandbox"})," 启动。"]})]})]})})]})})}const Kt=200,Vt=16e3,gr="baxian.draft.createTask:";function vt(e){return`${gr}${e??"*"}`}function Jt(e){try{const s=localStorage.getItem(e);if(!s)return null;const n=JSON.parse(s);if(!n||typeof n!="object")return null;const i=n,r=typeof i.title=="string"?i.title:"",o=typeof i.description=="string"?i.description:"",l=typeof i.projectId=="string"?i.projectId:"",u=typeof i.preferredAgentId=="string"?i.preferredAgentId:"",m=typeof i.updatedAt=="number"?i.updatedAt:void 0;return!r.trim()&&!o.trim()?null:{title:r,description:o,projectId:l,preferredAgentId:u,updatedAt:m}}catch{return null}}function br(e,s){const n=!s.title.trim()&&!s.description.trim();try{n?localStorage.removeItem(e):localStorage.setItem(e,JSON.stringify({...s,updatedAt:Date.now()}))}catch{}}function Yt(e){try{localStorage.removeItem(e)}catch{}}function vr(e){const s=vt(e),n=Jt(s);if(!e)return n;const i=vt(void 0),r=Jt(i);if(!r||r.projectId!==e)return n;const o=!n||(r.updatedAt??0)>(n.updatedAt??0);if(o)try{localStorage.setItem(s,JSON.stringify(r))}catch{return r}try{localStorage.removeItem(i)}catch{}return o?r:n}const Xt="mt-1 text-right text-xs text-og-400",jr=Math.floor(nt/1024/1024);function Tt(e){const s=e.mode==="edit",{show:n}=ve(),i=s?e.task.projectId:e.projectId,r=s?e.task.title:"",o=s?e.task.description:"",l=s?e.task.preferredAgentId:"",[u,m]=a.useState([]),[h,v]=a.useState([]),[d,f]=a.useState(i??""),[p,x]=a.useState(l),[N,j]=a.useState(r),[k,R]=a.useState(o),[E,b]=a.useState([]),y=a.useRef(null),[w,_]=a.useState(!1),[L,T]=a.useState(null),[F,O]=a.useState(!1),M=a.useRef(0),z=a.useRef(0),X=a.useRef(0),$=a.useRef(new Set),Z=s?null:vt(i);a.useEffect(()=>{if(!e.open)return;M.current+=1,z.current+=1;const C=M.current;m([]),v([]),$.current=new Set;const D=Z?vr(i):null;D&&$.current.add(D.projectId),f(i??(D==null?void 0:D.projectId)??""),x((D==null?void 0:D.preferredAgentId)||l),j((D==null?void 0:D.title)||r),R((D==null?void 0:D.description)||o),O(D!==null),T(null),_(!1),b([]),Promise.all([I.projects.list(),I.agents.list()]).then(([Y,G])=>{C===M.current&&(m(Y),v(G))}).catch(Y=>{C===M.current&&T(Y instanceof Error?Y.message:String(Y))})},[e.open,i,r,o,l,Z]),a.useEffect(()=>{if(!(!e.open||!Z)){if(X.current!==z.current){X.current=z.current;return}br(Z,{title:N,description:k,projectId:d,preferredAgentId:p})}},[e.open,Z,N,k,d,p]);const q=a.useMemo(()=>u.find(C=>C.id===d)??null,[u,d]),V=a.useMemo(()=>q?q.agent.flat().filter(C=>C.role==="dev"):[],[q]),U=a.useMemo(()=>new Set(h.map(C=>C.id)),[h]),Q=a.useMemo(()=>V.filter(C=>U.has(C.id)),[V,U]),se=a.useMemo(()=>V.filter(C=>!U.has(C.id)),[V,U]);a.useEffect(()=>{s||q!==null&&p!==""&&!Q.find(C=>C.id===p)&&x("")},[q,Q,p,s]),a.useEffect(()=>{s||q&&Q.length!==0&&($.current.has(q.id)||($.current.add(q.id),x(C=>C===""?Q[0].id:C)))},[s,q,Q]);const de=!s||Q.find(C=>C.id===p),B=s&&!de&&!!p,ie=B&&se.some(C=>C.id===p),re=ie?`当前 Dev agent "${p}" 在 baxian.json 中存在但 runtime 未加载,可能是手动编辑过配置文件;重启 server 可拉起`:B?`当前 Dev agent "${p}" 不在 runtime(可能已从 project 配置移除);保存可能失败,请确认或选择新 Dev agent`:!d||Q.length>0?null:se.length>0?"baxian.json 里有 Dev agent 但 runtime 未加载(可能是手动编辑过配置);重启 server 后生效":null,le=N.trim(),oe=k.trim(),ce=!!d&&le.length>0&&!w,ue=()=>{w||e.onClose()},A=()=>{Z&&(Yt(Z),f(i??""),x(l),j(r),R(o),T(null),O(!1))},c=async C=>{var D,Y;if(C.preventDefault(),!!ce){_(!0),T(null);try{if(e.mode==="edit"){const G=await I.tasks.update(e.task.id,{title:le,description:oe,preferredAgentId:p});n({kind:"success",title:"任务已更新"}),(D=e.onUpdated)==null||D.call(e,G),e.onClose()}else{const G=E.length?await Promise.all(E.map(async ge=>({dataBase64:await bt(ge),filename:ge.name}))):void 0,je=await I.tasks.create({projectId:d,title:le,description:oe,preferredAgentId:p,...G?{images:G}:{}});Z&&Yt(Z),n({kind:"success",title:"任务已创建"}),(Y=e.onCreated)==null||Y.call(e,je),e.onClose()}}catch(G){T(G instanceof Error?G.message:String(G))}finally{_(!1)}}},g=C=>{const D=Array.from(C.target.files??[]);if(C.target.value="",D.length===0)return;const Y=D.filter(G=>G.size>nt?(n({kind:"error",title:"图片过大",body:`${G.name} 超过 ${jr} MiB`}),!1):!0);b(G=>(G.length+Y.length>qe&&n({kind:"warn",title:`最多 ${qe} 张图片`}),[...G,...Y].slice(0,qe)))},S=C=>b(D=>D.filter((Y,G)=>G!==C)),P=s?"编辑任务":"新建任务",K=s?w?"保存中…":"保存":w?"创建中…":"创建",J=!s&&!i;return t.jsx(Ne,{open:e.open,onClose:ue,title:P,size:"md",dismissOnBackdrop:!1,footer:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:ue,disabled:w,className:"btn-secondary",children:"取消"}),t.jsx("button",{type:"submit",form:"create-task-form",disabled:!ce,className:"btn-primary",children:K})]}),children:t.jsxs("form",{id:"create-task-form",onSubmit:c,className:"space-y-3",children:[!s&&F&&t.jsxs("div",{className:"flex items-center justify-between gap-3 rounded-md border border-accent-soft bg-accent-soft/30 px-3 py-2 text-xs text-accent",children:[t.jsx("span",{children:"已恢复上次未提交的草稿"}),t.jsx("button",{type:"button",onClick:A,className:"shrink-0 underline hover:text-accent-hover",children:"丢弃"})]}),L&&t.jsx("div",{className:"rounded-md border border-accent/25 bg-accent-soft px-3 py-2 text-sm text-accent",children:L}),J&&t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"task-project",children:"Project"}),t.jsxs("select",{id:"task-project",value:d,onChange:C=>f(C.target.value),className:ae,disabled:w,required:!0,children:[t.jsx("option",{value:"",disabled:!0,children:"选择项目"}),u.map(C=>t.jsx("option",{value:C.id,children:C.id},C.id))]})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"task-dev",children:"Dev agent"}),t.jsxs("select",{id:"task-dev",value:p,onChange:C=>x(C.target.value),className:ae,disabled:w,children:[t.jsx("option",{value:"",children:"暂不指定"}),B&&t.jsxs("option",{value:p,children:[p," ",ie?"(待重启)":"(不在 runtime)"]}),Q.map(C=>t.jsx("option",{value:C.id,children:C.id},C.id))]}),re&&t.jsx("div",{className:"mt-1 text-xs text-accent",children:re})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"task-title",children:"Title"}),t.jsx("input",{id:"task-title",type:"text",value:N,onChange:C=>j(C.target.value),maxLength:Kt,className:ae,placeholder:"一句话描述要做什么",disabled:w,required:!0}),t.jsxs("div",{className:Xt,children:[N.length," / ",Kt]})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"task-description",children:"Description(可选)"}),t.jsx("textarea",{id:"task-description",value:k,onChange:C=>R(C.target.value),maxLength:Vt,rows:8,className:`${ae} font-mono text-xs`,placeholder:"详细描述任务,支持 markdown;简单任务可不填",disabled:w}),t.jsxs("div",{className:Xt,children:[k.length," / ",Vt]})]}),!s&&t.jsxs("div",{children:[t.jsx("label",{className:ee,children:"图片(可选)"}),t.jsx("button",{type:"button",onClick:()=>{var C;return(C=y.current)==null?void 0:C.click()},disabled:w||E.length>=qe,className:"btn-secondary",children:"添加图片"}),t.jsx("input",{ref:y,type:"file",accept:"image/*",multiple:!0,className:"hidden",onChange:g}),E.length>0&&t.jsx("ul",{className:"mt-2 space-y-1",children:E.map((C,D)=>t.jsxs("li",{className:"flex items-center justify-between rounded-md border border-og-100 bg-surface px-2.5 py-1.5",children:[t.jsx("span",{title:C.name,className:"truncate text-xs text-og-700",children:C.name}),t.jsx("button",{type:"button","aria-label":`移除图片 ${C.name}`,onClick:()=>S(D),disabled:w,className:"ml-2 shrink-0 text-og-400 transition-colors",children:"✕"})]},`${C.name}-${D}`))})]})]})})}const Zt="***",ht={hostname:"",port:"",alias:"",user:"",password:""};function wr(e){return e.alias?e.alias:`${e.user?`${e.user}@`:""}${e.hostname}${e.port!=null?`:${e.port}`:""}`}function yr({open:e,onClose:s}){var ue;const[n,i]=a.useState([]),[r,o]=a.useState("list"),[l,u]=a.useState(null),[m,h]=a.useState(null),[v,d]=a.useState(!1),[f,p]=a.useState(!1),[x,N]=a.useState(ht),[j,k]=a.useState(null),[R,E]=a.useState(!1),[b,y]=a.useState(!1),[w,_]=a.useState(null),[L,T]=a.useState(!1),[F,O]=a.useState(null),M=a.useRef(0),z=a.useRef(null),{show:X}=ve(),$=a.useCallback(()=>{I.hosts.list().then(i).catch(A=>k(A instanceof Error?A.message:String(A)))},[]);a.useEffect(()=>{if(!e){z.current&&z.current.abort();return}o("list"),u(null),h(null),N(ht),k(null),$()},[e,$]),a.useEffect(()=>{M.current+=1,z.current&&z.current.abort(),y(!1),_(null),T(!1),O(null)},[x.hostname,x.user,x.port,x.password,f,r]),a.useEffect(()=>()=>{z.current&&z.current.abort()},[]);const Z=()=>{u(null),h(null),d(!1),p(!1),N(ht),k(null),o("form")},q=A=>{u(A.id??null),h(A),d(A.password===Zt),p(!1),N({hostname:A.hostname,port:A.port!=null?String(A.port):"",alias:A.alias??"",user:A.user??"",password:""}),k(null),o("form")},V=()=>{const A={hostname:x.hostname.trim()};return l?(A.port=x.port.trim()?Number(x.port):null,A.alias=x.alias.trim(),A.user=x.user.trim()):(x.port.trim()&&(A.port=Number(x.port)),x.alias.trim()&&(A.alias=x.alias.trim()),x.user.trim()&&(A.user=x.user.trim())),l&&f?A.password="":x.password&&(A.password=x.password),A},U=x.port.trim(),Q=U===""||/^\d+$/.test(U)&&Number(U)>0&&Number(U)<=65535,se=x.hostname.trim().length>0&&Q,de=!!m&&x.hostname.trim()===m.hostname&&x.user.trim()===(m.user??"")&&x.port.trim()===(m.port!=null?String(m.port):""),B=()=>l&&de&&!x.password&&!f?{hostId:l}:{host:{hostname:x.hostname.trim(),...x.user.trim()?{user:x.user.trim()}:{},...U?{port:Number(U)}:{},...!f&&x.password?{password:x.password}:{}}},ie=async()=>{if(!se||b)return;z.current&&z.current.abort();const A=new AbortController;z.current=A;const c=M.current;y(!0),_(null),O(null),k(null);try{const g=await I.agents.probe("remote",B(),{signal:A.signal});if(A.signal.aborted||M.current!==c)return;_(g)}catch(g){if(A.signal.aborted||M.current!==c)return;k(g instanceof Error?g.message:String(g))}finally{M.current===c&&y(!1)}},re=async()=>{if(L)return;const A=M.current;T(!0),O(null),k(null);try{const c=await I.agents.installTmux("remote",B());if(M.current!==A)return;O({ok:c.ok,message:c.message}),_(g=>g&&{...g,tmux:c.tmux})}catch(c){if(M.current!==A)return;k(c instanceof Error?c.message:String(c))}finally{M.current===A&&T(!1)}},le=async A=>{if(A.preventDefault(),!(!se||R)){E(!0),k(null);try{if(l)await I.hosts.update(l,V()),X({kind:"success",title:`Host ${l} 已更新`});else{const c=await I.hosts.create(V());X({kind:"success",title:`Host ${c.host.id} 已添加`})}$(),o("list")}catch(c){k(c instanceof Error?c.message:String(c))}finally{E(!1)}}},oe=async A=>{k(null);try{await I.hosts.delete(A.id),X({kind:"success",title:`Host ${A.id} 已删除`}),$()}catch(c){k(c instanceof Error?c.message:String(c))}},me=t.jsx("button",{type:"button",onClick:s,className:"btn-secondary",children:"关闭"}),ce=t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:()=>o("list"),disabled:R,className:"btn-secondary",children:"返回"}),t.jsx("button",{type:"submit",form:"host-form",disabled:!se||R,className:"btn-primary",children:R?"保存中…":"保存"})]});return t.jsxs(Ne,{open:e,onClose:s,title:"Host 管理",size:"md",footer:r==="list"?me:ce,children:[j&&t.jsx("div",{className:"mb-3 rounded-md border border-accent/25 bg-accent-soft px-3 py-2 text-sm text-accent",children:j}),r==="list"?t.jsxs("div",{className:"space-y-3",children:[n.length===0?t.jsx("p",{className:"text-sm text-og-500",children:"还没有配置 Host。点击下方「添加 Host」。"}):t.jsx("ul",{className:"space-y-1.5",children:n.map(A=>t.jsxs("li",{className:"flex items-center justify-between gap-3 rounded-md border border-og-100 px-3 py-2",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsx("div",{className:"truncate text-sm font-medium text-og-800",children:wr(A)}),t.jsxs("div",{className:"truncate text-xs text-og-500",children:[(A.user?`${A.user}@`:"")+A.hostname,A.port!=null?`:${A.port}`:"",A.password===Zt?" · 密码已保存":""]})]}),t.jsxs("div",{className:"flex shrink-0 gap-2",children:[t.jsx("button",{type:"button",onClick:()=>q(A),className:"text-xs text-accent transition-colors hover:text-accent-hover",children:"编辑"}),t.jsx("button",{type:"button",onClick:()=>oe(A),className:"text-xs text-accent transition-colors hover:opacity-80",children:"删除"})]})]},A.id))}),t.jsx("button",{type:"button",onClick:Z,className:"btn-secondary w-full",children:"+ 添加 Host"})]}):t.jsxs("form",{id:"host-form",onSubmit:le,className:"space-y-3",children:[t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host-hostname",children:"Host 地址"}),t.jsx("input",{id:"host-hostname",type:"text",value:x.hostname,onChange:A=>N({...x,hostname:A.target.value}),className:ae,placeholder:"remote.example.com",disabled:R})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host-port",children:"端口(可选)"}),t.jsx("input",{id:"host-port",type:"text",inputMode:"numeric",value:x.port,onChange:A=>N({...x,port:A.target.value}),className:ae,placeholder:"22",disabled:R}),x.port.trim()!==""&&!Q&&t.jsx("div",{className:"mt-1 text-xs text-accent",children:"端口需为 1–65535 的整数"})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host-alias",children:"别名(可选)"}),t.jsx("input",{id:"host-alias",type:"text",value:x.alias,onChange:A=>N({...x,alias:A.target.value}),className:ae,placeholder:"Prod worker",disabled:R})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host-user",children:"用户名(可选)"}),t.jsx("input",{id:"host-user",type:"text",value:x.user,onChange:A=>N({...x,user:A.target.value}),className:ae,placeholder:"留空则读 ~/.ssh/config 的 User",disabled:R})]}),t.jsxs("div",{children:[t.jsx("label",{className:ee,htmlFor:"host-password",children:"密码(可选)"}),t.jsx("input",{id:"host-password",type:"password",value:f?"":x.password,onChange:A=>N({...x,password:A.target.value}),className:ae,placeholder:v?"已设置,留空保持不变":"留空使用 key 认证",disabled:R||f,autoComplete:"new-password"}),l&&v&&t.jsxs("label",{className:"mt-1.5 flex items-center gap-2 text-xs text-og-700",children:[t.jsx("input",{type:"checkbox",className:"h-3.5 w-3.5 accent-accent",checked:f,onChange:A=>p(A.target.checked),disabled:R}),"清除已保存的密码(改用 key 登录)"]})]}),t.jsxs("div",{className:"rounded-md border border-accent/25 bg-accent-soft/60 px-3 py-2.5 text-xs text-accent",children:["建议为该 Host 配置好",t.jsx("strong",{className:"font-semibold",children:"免密码登入(SSH key)"}),"。 否则填写的密码将以",t.jsx("strong",{className:"font-semibold",children:"明文"}),"保存到 baxian.json 中。"]}),t.jsxs("div",{className:"space-y-1.5",children:[t.jsx("button",{type:"button",onClick:ie,disabled:!se||b||R||L,className:"text-xs text-accent transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",children:b?"测试中…":"测试连接"}),(w==null?void 0:w.ssh)&&t.jsxs("div",{className:`text-xs ${w.ssh.ok?"text-og-800":"text-accent"}`,children:["SSH: ",w.ssh.ok?"✓":"⨯"," ",w.ssh.message]}),w&&(w.tmux.ok?t.jsxs("div",{className:"text-xs text-og-800",children:["tmux: ✓ ",w.tmux.path??""]}):t.jsxs("div",{className:"text-xs text-accent",children:["tmux: ⨯ ",w.tmux.message,((ue=w.ssh)==null?void 0:ue.ok)&&t.jsx("button",{type:"button",onClick:re,disabled:L||R,className:"ml-2 text-accent underline transition-colors hover:text-accent-hover disabled:cursor-not-allowed disabled:opacity-50",children:L?"安装中…":"一键安装"})]})),L&&t.jsx("div",{className:"text-xs text-og-500",children:"正在安装 tmux,可能需要几分钟,请勿关闭窗口…"}),!L&&F&&t.jsxs("div",{className:`break-all text-xs ${F.ok?"text-og-800":"text-accent"}`,children:[F.ok?"✓ ":"⨯ ",F.message]})]})]})]})}const $s="topbar-actions";function es(){return typeof document>"u"?null:document.getElementById($s)}function Ts({children:e}){const[s,n]=a.useState(es);return a.useEffect(()=>{s||n(es())},[s]),s?Js.createPortal(e,s):null}function Nr(e){return Array.from(new TextEncoder().encode(e)).map(s=>s.toString(16).padStart(2,"0")).join("")}function Sr(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/realtime`}const kr=(e,s)=>s&&s.length>0?new WebSocket(e,s):new WebSocket(e);class Er{constructor(s={}){te(this,"wsUrl");te(this,"wsFactory");te(this,"tokenProvider");te(this,"ws",null);te(this,"topics",new Map);te(this,"cache",new Map);te(this,"outbox",[]);te(this,"reconnectScheduler");te(this,"explicitlyClosed",!1);this.wsUrl=s.wsUrl??Sr(),this.wsFactory=s.wsFactory??kr,this.tokenProvider=s.tokenProvider??Et,this.reconnectScheduler=new Ns({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.topics.size>0})}subscribe(s,n,i){let r=this.topics.get(s);const o=!r;return r||(r={data:new Set,error:new Set},this.topics.set(s,r)),r.data.add(n),i&&r.error.add(i),o?(this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",topic:s})):this.cache.has(s)&&queueMicrotask(()=>{var l;(l=this.topics.get(s))!=null&&l.data.has(n)&&this.cache.has(s)&&n(this.cache.get(s))}),()=>this.unsubscribe(s,n,i)}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.topics.clear(),this.cache.clear(),this.outbox=[]}unsubscribe(s,n,i){const r=this.topics.get(s);r&&(r.data.delete(n),i&&r.error.delete(i),r.data.size===0&&r.error.size===0&&(this.topics.delete(s),this.cache.delete(s),this.wsSendOrQueue({op:"unsubscribe",topic:s}),this.topics.size===0&&this.teardownSocket()))}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const s=this.tokenProvider(),n=s?[`baxian.token.${Nr(s)}`]:void 0;let i;try{i=this.wsFactory(this.wsUrl,n)}catch(o){console.warn("[events-client] WebSocket constructor threw:",o),this.broadcastConnectionError({code:"connection_failed",message:o instanceof Error?o.message:"WebSocket constructor threw"}),this.scheduleReconnect();return}this.ws=i;let r=!1;i.onopen=()=>{if(i!==this.ws)return;r=!0,this.reconnectScheduler.reset();for(const l of this.topics.keys())try{i.send(JSON.stringify({op:"subscribe",topic:l}))}catch(u){console.warn("[events-client] resubscribe send failed:",u)}const o=this.outbox;this.outbox=[];for(const l of o)if(!(l.op==="subscribe"||l.op==="unsubscribe"))try{i.send(JSON.stringify(l))}catch(u){console.warn("[events-client] outbox flush failed:",u)}},i.onmessage=o=>{if(i!==this.ws)return;let l;try{const u=typeof o.data=="string"?o.data:String(o.data);l=JSON.parse(u)}catch{return}this.handleMessage(l)},i.onclose=()=>{i===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()))},i.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}broadcastConnectionError(s){for(const n of this.topics.values())for(const i of[...n.error])try{i(s)}catch(r){console.error("[events-client] error handler threw on connection error:",r)}}wsSendOrQueue(s){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(s));return}catch(n){console.warn("[events-client] send failed, will queue:",n)}this.outbox.push(s)}handleMessage(s){switch(s.type){case"data":{const n=this.topics.get(s.topic);if(this.cache.set(s.topic,s.data),!n)return;for(const i of[...n.data])try{i(s.data)}catch(r){console.error(`[events-client] handler threw on ${s.topic}:`,r)}break}case"error":{const n={code:s.code,message:s.message};if(s.topic){const i=this.topics.get(s.topic);if(i)for(const r of[...i.error])try{r(n)}catch(o){console.error(`[events-client] error handler threw on ${s.topic}:`,o)}}else console.warn("[events-client] connection-level error:",s.code,s.message);break}}}}let xt=null;function it(){return xt||(xt=new Er),xt}function It(){const[e,s]=a.useState(null),[n,i]=a.useState(!1),[r,o]=a.useState(null);return a.useEffect(()=>it().subscribe("agents",u=>{o(null),s(u),i(!0)},u=>o(u)),[]),{data:e,loaded:n,error:r}}function Pt(e){const[s,n]=a.useState(null),[i,r]=a.useState(!1),[o,l]=a.useState(null);return a.useEffect(()=>(n(null),r(!1),l(null),it().subscribe(`task:${e}`,m=>{l(null),n(m),r(!0)},m=>l(m))),[e]),{data:s,loaded:i,error:o}}function Is(e){const[s,n]=a.useState(null),[i,r]=a.useState(!1),[o,l]=a.useState(null);return a.useEffect(()=>{if(!e){n(null),r(!1),l(null);return}n(null),r(!1),l(null);let u=!1,m=!1,h=!1;const v=it().subscribe(`project-tasks:${e}`,d=>{u||(m=!0,l(null),n(d),r(!0))},d=>{u||(l(d),!(m||h)&&(h=!0,I.tasks.list(e).then(f=>{u||m||(n(f),r(!0))},f=>{console.warn(`[useProjectTasks] REST fallback failed for ${e}:`,f)})))});return()=>{u=!0,v()}},[e]),{data:s,loaded:i,error:o}}let Ze=null,ye=null,et=null,Oe=0;const jt=new Set;function Ps(){jt.forEach(e=>e())}async function Rr(){const e=Oe;try{const s=await I.projects.list();if(e!==Oe)return;Ze=s,et=null}catch(s){if(e!==Oe)return;et=s instanceof Error?s.message:String(s)}finally{e===Oe&&(ye=null,Ps())}}function wt(){return ye||(ye=Rr(),ye)}function Cr(){Oe+=1,Ze=null,ye=null,et=null,Ps()}typeof window<"u"&&window.addEventListener(Je,Cr);async function Ar(){const e=ye!==null;await wt(),e&&await wt()}function Ue(){const[,e]=a.useState(0);return a.useEffect(()=>{const s=()=>e(n=>n+1);return jt.add(s),Ze===null&&!ye&&wt(),()=>{jt.delete(s)}},[]),{projects:Ze,error:et,refresh:Ar}}const Dt="baxian.taskNotifications.enabled";function Lt(){if(typeof window>"u")return null;const e=window.Notification;return typeof e=="function"?e:null}function Qe(){const e=Lt();return e?e.permission:"unsupported"}function pt(){try{return localStorage.getItem(Dt)!=="0"}catch{return!0}}function Ke(e){try{localStorage.setItem(Dt,e?"1":"0")}catch{}}const Ds=a.createContext(null);function $r({children:e}){const[s,n]=a.useState(Qe),[i,r]=a.useState(pt),[o,l]=a.useState(!1),u=a.useRef(!1),m=a.useRef(0);a.useEffect(()=>{const d=()=>{n(Qe()),u.current||r(pt())},f=p=>{if(p.key!==null&&p.key!==Dt)return;n(Qe());const x=p.key===null?pt():p.newValue!=="0";x||(m.current+=1),r(x)};return window.addEventListener("focus",d),window.addEventListener("storage",f),()=>{window.removeEventListener("focus",d),window.removeEventListener("storage",f)}},[]);const h=a.useCallback(()=>{r(!0);const d=Lt();if(!d){Ke(!0);return}if(d.permission!=="default"){n(d.permission),Ke(!0);return}if(u.current)return;u.current=!0,l(!0);const f=m.current;d.requestPermission().then(n).catch(p=>{console.warn("[task-notifications] permission request failed:",p),n(Qe())}).finally(()=>{m.current===f&&Ke(!0),u.current=!1,l(!1)})},[]),v=a.useCallback(()=>{m.current+=1,r(!1),Ke(!1)},[]);return t.jsx(Ds.Provider,{value:{permission:s,preferenceEnabled:i,enabled:s==="granted"&&i,requesting:o,enable:h,disable:v},children:e})}function Ls(){const e=a.useContext(Ds);if(!e)throw new Error("useTaskNotifications must be used inside TaskNotificationsProvider");return e}function Tr(){const e=pe(),{projects:s,error:n,refresh:i}=Ue(),r=s??[],o=s!==null,[l,u]=a.useState(!1),[m,h]=a.useState(!1),[v,d]=a.useState(!1),[f,p]=a.useState({kind:"closed"}),{data:x,loaded:N,error:j}=It(),k=(j==null?void 0:j.message)??null,R=new Map((x??[]).map(w=>[w.id,w])),E=n??k,b=r.length===0,y=t.jsx("button",{type:"button",onClick:()=>h(!0),disabled:b,"aria-describedby":b?"create-task-hint":void 0,className:"btn-ghost",children:"+ 新建任务"});return t.jsxs("div",{children:[t.jsxs(Ts,{children:[b?t.jsx("span",{className:"inline-flex",title:"请先创建项目",children:y}):y,b&&t.jsx("span",{id:"create-task-hint",className:"sr-only",children:"请先创建项目"}),t.jsx(St,{ariaLabel:"更多操作",children:w=>t.jsxs(t.Fragment,{children:[t.jsx(he,{onClick:()=>{w(),u(!0)},children:"新建项目"}),t.jsx(he,{onClick:()=>{w(),d(!0)},children:"Host 管理"}),t.jsx(Ir,{onAction:w})]})})]}),t.jsx("h1",{className:"sr-only",children:"Dashboard"}),E&&t.jsxs("div",{className:"mb-4 text-sm text-accent",children:["加载失败:",E]}),o&&r.length===0&&!n&&t.jsx("div",{className:"rounded-lg border border-hairline bg-surface py-12 text-center text-sm text-og-500",children:'还没有项目。点击右上角"更多"菜单 → "新建项目"开始。'}),r.map(w=>t.jsx(Pr,{project:w,agentsById:R,agentsLoaded:N,agentsError:!!j,onAgentDeleted:i},w.id)),t.jsx(hr,{open:l,onClose:()=>u(!1),onCreated:w=>{u(!1),i(),p({kind:"asking",projectId:w})}}),t.jsx(yr,{open:v,onClose:()=>d(!1)}),t.jsx(Ne,{open:f.kind==="asking",onClose:()=>p({kind:"closed"}),title:"项目已创建",size:"sm",footer:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:()=>p({kind:"closed"}),className:"btn-secondary",children:"稍后再加"}),t.jsx("button",{type:"button",onClick:()=>{f.kind==="asking"&&p({kind:"addingAgent",projectId:f.projectId})},className:"btn-primary",children:"继续添加 Agent"})]}),children:t.jsx("p",{className:"text-sm text-og-700",children:"现在添加第一个 Agent,还是稍后再加?"})}),f.kind==="addingAgent"&&t.jsx(As,{open:!0,projectId:f.projectId,onClose:()=>p({kind:"closed"}),onCreated:()=>{i()}}),t.jsx(Tt,{open:m,onClose:()=>h(!1),onCreated:w=>e(Ce(w.projectId,w.id))})]})}function Ir({onAction:e}){const{permission:s,enabled:n,requesting:i,enable:r,disable:o}=Ls();return s==="unsupported"?null:s==="denied"?t.jsx(he,{disabled:!0,children:"浏览器已拒绝任务完成通知"}):t.jsx(he,{disabled:i,onClick:()=>{e(),n?o():r()},children:n?"关闭任务完成通知":"开启任务完成通知"})}function Pr({project:e,agentsById:s,agentsLoaded:n,agentsError:i,onAgentDeleted:r}){const{data:o,error:l}=Is(e.id),u=o??[],m=(l==null?void 0:l.message)??null;return t.jsxs("div",{className:"mb-10",children:[t.jsxs("div",{className:"mb-3 -mx-2 flex items-baseline gap-x-3 gap-y-1 px-2 py-1",children:[t.jsx("h2",{className:"min-w-0 truncate font-display text-sm font-semibold tracking-tight text-og-1000",title:e.id,children:t.jsx(Be,{to:`/project/${e.id}`,className:"hover:text-accent-hover",children:e.id})}),t.jsx("span",{className:"hidden min-w-0 truncate font-mono text-xs text-og-500 sm:inline-block",title:e.repo,children:e.repo}),t.jsx(Be,{to:`/project/${e.id}`,className:"ml-auto text-sm text-accent hover:text-accent-hover","aria-label":`详情 — ${e.id}`,children:"详情 →"})]}),m&&t.jsxs("div",{className:"mb-2 text-xs text-accent",children:["任务列表加载失败:",m]}),e.agent.flat().length===0?t.jsx("div",{className:"rounded-lg border border-hairline bg-surface py-6 text-center text-sm text-og-500",children:"还没有 Agent。进入 Details 添加。"}):t.jsx("div",{className:e.agent.length===1?"space-y-3":"grid grid-cols-1 gap-3 xl:grid-cols-2",children:e.agent.map((h,v)=>t.jsx(Cs,{group:h,projectId:e.id,agentsById:s,agentsLoaded:n,agentsError:i,tasks:u,onDeleted:r,terminalMode:"embedded-full"},h.map(d=>d.id).join(":")||v))})]})}const Ms="baxian.taskPanel.doneOpen";function Dr(){try{return localStorage.getItem(Ms)==="1"}catch{return!1}}function tt(e){const s=e.match(/^task-(\d+)$/);return s?parseInt(s[1],10):Number.NaN}function Lr(e,s){const n=tt(e.id),i=tt(s.id);return Number.isNaN(n)||Number.isNaN(i)?e.id.localeCompare(s.id):n-i}function Mr(e,s){const n=(s.updatedAt??"").localeCompare(e.updatedAt??"");if(n!==0)return n;const i=tt(e.id),r=tt(s.id);return Number.isNaN(i)||Number.isNaN(r)?s.id.localeCompare(e.id):r-i}function ts(e,s){const[n,i]=a.useState(at);a.useEffect(()=>i(at),[s]);const r=e.slice(0,n),o=e.length>r.length;return{items:r,hasMore:o,loadMore:()=>i(u=>u+at),total:e.length}}function _r(e){const[s,n]=a.useState([]),[i,r]=a.useState(!1),[o,l]=a.useState(!1),[u,m]=a.useState(!1),[h,v]=a.useState(null),d=a.useRef(0),f=a.useRef(0),p=a.useCallback(x=>{const N=++d.current,j=x==="first"?0:f.current;l(!0),v(null),I.tasks.page(e,{category:"done",offset:j}).then(k=>{d.current===N&&(n(R=>x==="first"?k.tasks:[...R,...k.tasks]),r(k.hasMore),f.current=k.nextOffset,m(!0),l(!1))},k=>{d.current===N&&(v(k instanceof Error?k.message:String(k)),l(!1))})},[e]);return a.useEffect(()=>{d.current+=1,f.current=0,n([]),r(!1),m(!1),v(null),l(!1)},[e]),{items:s,hasMore:i,loading:o,loaded:u,error:h,load:p}}function Or({projectId:e,openTasks:s,className:n=""}){const i=a.useMemo(()=>s.filter(d=>ps.has(d.status)).sort(Mr),[s]),r=a.useMemo(()=>s.filter(d=>d.status==="pending").sort(Lr),[s]),o=ts(i,e),l=ts(r,e),u=_r(e),[m,h]=a.useState(Dr);a.useEffect(()=>{try{localStorage.setItem(Ms,m?"1":"0")}catch{}},[m]),a.useEffect(()=>{m&&u.load("first")},[m,u.load]);const v=()=>h(d=>!d);return t.jsx("aside",{"aria-label":"任务面板",className:`flex flex-col rounded-lg border border-hairline bg-surface ${n}`,children:t.jsxs("div",{children:[t.jsx(ss,{title:"IN PROGRESS",section:o,emptyHint:"暂无正在处理的任务"}),t.jsx(ss,{title:"PENDING",section:l,emptyHint:"暂无待处理的任务"}),t.jsxs("div",{children:[t.jsxs("button",{type:"button",onClick:v,"aria-expanded":m,className:"flex w-full items-center justify-between px-3 py-2 text-left text-xs font-normal uppercase tracking-[0.05em] text-og-500 transition-colors hover:bg-og-50/40",children:[t.jsx("span",{children:"DONE"}),t.jsx("span",{className:"font-normal normal-case text-accent",children:m?"收起":"查看"})]}),m&&t.jsx(Fr,{state:u})]})]})})}function ss({title:e,section:s,emptyHint:n}){return t.jsxs("section",{"aria-label":e,className:"border-b border-hairline",children:[t.jsxs("div",{className:"px-3 py-2 text-xs font-normal uppercase tracking-[0.05em] text-og-500",children:[e," ",t.jsxs("span",{className:"text-og-400",children:["(",s.total,")"]})]}),s.items.length===0?t.jsx("div",{className:"px-3 pb-3 text-xs text-og-400",children:n}):t.jsxs("div",{className:"divide-y divide-hairline",children:[s.items.map(i=>t.jsx(_s,{task:i},i.id)),s.hasMore&&t.jsx("button",{type:"button",onClick:s.loadMore,className:"w-full px-3 py-2 text-center text-xs text-accent transition-colors hover:bg-og-50/40",children:"加载更多"})]})]})}function Fr({state:e}){const s=e.loaded&&!e.error&&e.items.length===0;return t.jsxs("div",{className:"divide-y divide-hairline",children:[e.items.map(n=>t.jsx(_s,{task:n},n.id)),e.error&&t.jsxs("div",{className:"px-3 py-2 text-xs text-accent",children:["加载失败:",e.error]}),s&&t.jsx("div",{className:"px-3 pb-3 pt-1 text-xs text-og-400",children:"暂无已处理的任务"}),e.loading&&e.items.length===0&&t.jsx("div",{className:"px-3 py-3 text-center text-xs text-og-400",children:"加载中…"}),e.hasMore&&t.jsx("button",{type:"button",onClick:()=>e.load("more"),disabled:e.loading,className:"w-full px-3 py-2 text-center text-xs text-accent transition-colors hover:bg-og-50/40 disabled:opacity-50",children:e.loading?"加载中…":"加载更多"})]})}function Br(e){const[s,n]=a.useState(!1);return a.useEffect(()=>{function i(){if(e.status!=="review"||!e.reviewDispatchedAt||!e.qaAgentId){n(!1);return}n(Date.now()-Date.parse(e.reviewDispatchedAt)>=gs)}i();const r=setInterval(i,3e4);return()=>clearInterval(r)},[e.status,e.reviewDispatchedAt,e.qaAgentId]),s}function _s({task:e}){const s=pe(),n=e.phase==="spec"?e.specReviewRound??0:e.reviewRound,i=Br(e);return t.jsxs("button",{type:"button",onClick:()=>s(Ce(e.projectId,e.id)),className:"flex w-full items-center gap-2 px-3 py-2 text-left text-sm transition-colors hover:bg-og-50/60",children:[t.jsx("span",{className:"shrink-0 font-mono text-xs text-og-500",title:e.id,children:$t(e.id)}),t.jsx("span",{className:"min-w-0 flex-1 truncate text-og-1000",title:e.title,children:e.title}),e.phase==="spec"&&t.jsx("span",{className:"pill pill-review shrink-0",children:"spec"}),i&&t.jsx("span",{className:"pill pill-warn shrink-0",title:"Review verdict missing",children:"!"}),t.jsxs("span",{"aria-label":`第 ${n} 轮`,className:"shrink-0 text-xs text-og-400",children:["R",n]}),t.jsx(cr,{status:e.status})]})}const Hr=[],Os="baxian.taskPanel.open";function Ur(){try{return localStorage.getItem(Os)!=="0"}catch{return!0}}function qr(){const{id:e}=He(),s=pe(),{show:n}=ve(),{refresh:i}=Ue(),[r,o]=a.useState(null),[l,u]=a.useState(null),[m,h]=a.useState(!1),[v,d]=a.useState(!1),f=a.useRef(null),[p,x]=a.useState(Ur),[N,j]=a.useState(!1),[k,R]=a.useState(""),[E,b]=a.useState(!1),[y,w]=a.useState(null),_=a.useRef(0),{data:L,loaded:T,error:F}=It(),{data:O,error:M}=Is(e),z=(F==null?void 0:F.message)??null,X=(M==null?void 0:M.message)??null,$=O??Hr,Z=new Map((L??[]).map(B=>[B.id,B])),q=l??z??X,V=a.useCallback(async B=>{const ie=++_.current;try{const re=await I.projects.get(B);if(ie!==_.current)return;o(re),u(null)}catch(re){if(ie!==_.current)return;u(re instanceof Error?re.message:String(re))}},[]);a.useEffect(()=>{e&&(o(null),u(null),V(e))},[e,V]),a.useEffect(()=>{N||(R(""),w(null))},[N]),a.useEffect(()=>{try{localStorage.setItem(Os,p?"1":"0")}catch{}},[p]);const U=(r==null?void 0:r.agent.flat().length)??0,Q=U===0,se=!!r&&k.trim()===r.id,de=async()=>{if(!(!r||!se||E)){b(!0),w(null);try{await I.projects.delete(r.id),await i(),n({kind:"success",title:`项目 ${r.id} 已删除`}),j(!1),s("/")}catch(B){w(B instanceof Error?B.message:String(B))}finally{b(!1)}}};return r?t.jsxs("div",{children:[t.jsxs(Ts,{children:[t.jsx("button",{type:"button",onClick:()=>d(!0),className:"btn-ghost",children:"+ 新建任务"}),t.jsx(St,{ariaLabel:`项目 ${r.id} 操作菜单`,menuClassName:"min-w-[180px]",triggerRef:f,children:B=>t.jsxs(t.Fragment,{children:[!p&&t.jsx(he,{onClick:()=>{B(),x(!0)},children:"显示任务面板"}),t.jsx(he,{onClick:()=>{B(),h(!0)},children:"添加 Agent"}),t.jsx("div",{role:"none",className:"my-1 border-t border-hairline"}),t.jsx(he,{onClick:()=>{B(),j(!0)},disabled:!Q,title:Q?void 0:`请先删除项目下的 ${U} 个 Agent`,children:"删除项目…"})]})})]}),q&&t.jsxs("div",{className:"mb-4 text-sm text-accent",children:["加载失败:",q]}),t.jsxs("div",{className:"mb-6 flex items-baseline gap-x-3",children:[t.jsx("h1",{className:"min-w-0 truncate font-display text-sm font-semibold tracking-tight text-og-1000",title:r.id,children:r.id}),t.jsx("span",{className:"hidden min-w-0 truncate font-mono text-xs text-og-500 sm:inline-block",title:r.repo,children:r.repo})]}),t.jsxs("div",{className:"flex flex-col gap-4 lg:flex-row lg:items-start",children:[t.jsxs("div",{className:"min-w-0 flex-1",children:[t.jsx("div",{className:"mb-3 flex h-8 items-center gap-2",children:t.jsx("h2",{className:"font-display text-xs font-semibold uppercase tracking-[0.06em] text-og-500",children:"Agents"})}),r.agent.flat().length===0?t.jsx("div",{className:"mb-8 rounded-lg border border-hairline bg-surface py-6 text-center text-sm text-og-500",children:"还没有 Agent,点击右上角菜单添加。"}):t.jsx("div",{className:"mb-8 space-y-5",children:r.agent.map((B,ie)=>t.jsx(Cs,{group:B,projectId:r.id,agentsById:Z,agentsLoaded:T,agentsError:!!F,tasks:$,onDeleted:()=>{V(r.id)},terminalMode:"embedded-full"},B.map(re=>re.id).join(":")||ie))})]}),p&&t.jsxs("div",{className:"w-full lg:w-[340px] lg:shrink-0 xl:w-[380px]",children:[t.jsxs("div",{className:"mb-3 flex h-8 items-center justify-between gap-2",children:[t.jsx("h2",{className:"font-display text-xs font-semibold uppercase tracking-[0.06em] text-og-500",children:"Tasks"}),t.jsx("button",{type:"button",onClick:()=>{var B;x(!1),(B=f.current)==null||B.focus()},"aria-label":"关闭任务面板",className:"flex h-7 w-7 items-center justify-center rounded text-og-500 transition-colors hover:bg-og-50 hover:text-og-1000",children:t.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[t.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),t.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]}),t.jsx(Or,{projectId:r.id,openTasks:$})]})]}),t.jsx(As,{open:m,projectId:r.id,onClose:()=>h(!1),onCreated:()=>{V(r.id)}}),t.jsx(Tt,{open:v,projectId:r.id,onClose:()=>d(!1),onCreated:B=>s(Ce(B.projectId,B.id))}),t.jsx(Ne,{open:N,onClose:()=>{E||j(!1)},title:"删除项目",size:"sm",footer:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",onClick:()=>j(!1),disabled:E,className:"btn-secondary",children:"取消"}),t.jsx("button",{type:"button",onClick:()=>void de(),disabled:!se||E,className:"btn-primary",children:E?"删除中…":"确认删除"})]}),children:t.jsxs("div",{className:"space-y-4",children:[t.jsxs("p",{className:"text-sm text-og-700",children:["将从 ",t.jsx("code",{className:"font-mono text-og-1000",children:"baxian.json"})," 中移除项目"," ",t.jsx("span",{className:"font-mono text-og-1000",children:r.id}),"。此操作不可撤销,且不会删除 Git 仓库本身。"]}),t.jsxs("p",{className:"text-sm text-og-700",children:["如需确认,请在下方输入项目 ID ",t.jsx("span",{className:"font-mono text-og-1000",children:r.id}),":"]}),t.jsx("input",{type:"text",value:k,onChange:B=>R(B.target.value),placeholder:r.id,autoComplete:"off",autoCorrect:"off",spellCheck:!1,disabled:E,"aria-label":"输入项目 ID 以确认删除",className:"w-full rounded border border-hairline bg-surface px-3 py-2 font-mono text-sm text-og-1000 focus:border-accent focus:outline-none"}),y&&t.jsx("div",{className:"rounded-md border border-accent/25 bg-accent-soft px-3 py-2 text-xs text-accent",children:y})]})})]}):l?t.jsxs("div",{className:"text-sm text-accent",children:["Error: ",l]}):t.jsx("div",{className:"text-sm text-og-500",children:"Loading…"})}function Fs(e,s){const[n,i]=a.useState(null),[r,o]=a.useState(!1),[l,u]=a.useState(null),m=a.useRef(e);return a.useEffect(()=>{let h=!0;return m.current!==e&&(m.current=e,i(null),o(!1)),u(null),I.tasks.reviews(e).then(v=>{h&&(i(v),o(!0))}).catch(v=>{h&&(u(v instanceof Error?v.message:String(v)),i([]),o(!0))}),()=>{h=!1}},[e,s]),{rounds:n,loaded:r,error:l}}const Bs={approve:"pill pill-live","request-changes":"pill pill-warn",comment:"pill"};function Hs(e){const s=[];let n=[];for(const i of e)i.kind==="review"?(s.push({items:n,review:i}),n=[]):n.push(i);return n.length>0&&s.push({items:n}),s}function st(e,s){return`${e.kind}-${e.id||e.commitSha||e.createdAt||e.body||s}`}function Us(e,s){return e.review?`round-${st(e.review,s)}`:`round-in-progress-${e.items[0]?st(e.items[0],s):s}`}function qs(e){return`${e.reviewRound}:${e.latestHeadSha??""}:${e.status}:${e.reviewDispatchedAt??""}:${e.prFeedbackReceivedAt??""}`}function Ws(e,s){const[n,i]=a.useState(null),[r,o]=a.useState(!1),[l,u]=a.useState(null),m=a.useRef(e),h=a.useRef(s),v=a.useRef(0),d=a.useRef(!1);return a.useEffect(()=>{if(m.current!==e)m.current=e,d.current=!1,i(null),o(!1);else if(h.current===void 0&&s!==void 0&&d.current){h.current=s;return}h.current=s;const p=++v.current;u(null),I.tasks.githubReview(e).then(x=>{v.current===p&&(d.current=x.available===!0&&!x.error,i(x),o(!0))}).catch(x=>{v.current===p&&(d.current=!1,u(x instanceof Error?x.message:String(x)),i(null),o(!0))})},[e,s]),{data:n,loaded:r,error:l}}function Fe({role:e,label:s,summary:n,badge:i,onClick:r}){return t.jsxs("button",{type:"button",onClick:r,className:"card flex w-full items-center gap-2 px-3 py-2 text-left text-sm",children:[t.jsx("span",{className:"shrink-0 min-w-[1.75rem] text-xs tracking-wide text-og-600",children:e==="qa"?"QA":e==="user"?"用户":"Dev"}),t.jsx("span",{className:"shrink-0 text-og-800",children:s}),i,t.jsx("span",{className:"min-w-0 flex-1 truncate text-og-500",children:n}),t.jsx("span",{"aria-hidden":!0,className:"shrink-0 text-og-300",children:"›"})]})}const ns={"server-mode":"该 task 为 server 评审模式,代码评审记录见 server 评审轮次。","no-pr":"该 task 还没有 PR,暂无代码评审记录。","not-github":"该 task 的仓库不是 GitHub 仓库,无法拉取 PR 评审记录。"};function Wr(e){return(e==null?void 0:e.trim().split(`
5
5
  `,1)[0])??""}function zr(e){var s;return(s=e.commitSha)==null?void 0:s.slice(0,9)}function Gr(e){if(!(e.kind!=="review-comment"||!e.path))return e.line!==void 0?`${e.path}:${e.line}`:e.path}function Qr(e){return e.bodyTruncated?"(已截断)":""}function Kr(e){const s=Wr(e.body),n=Qr(e);if(e.kind==="commit"){const i=zr(e);return i&&s?`${i} ${s}${n}`:`${s||i||"commit"}${n}`}if(e.kind==="review-comment"){const i=Gr(e);if(e.inReplyTo){const r=[e.author,i,s].filter(o=>!!o);if(r.length>0)return`${r.join(" · ")}${n}`}return i&&s?`${i} · ${s}${n}`:`${s||i||"行内评论"}${n}`}return e.kind==="issue-comment"?e.author&&s?`${e.author} · ${s}${n}`:`${s||e.author||"评论"}${n}`:`${s||"无评审正文"}${n}`}function Vr(e){return e.kind==="commit"?"提交代码改动":e.kind==="review"?"评审":e.kind==="review-comment"?e.inReplyTo?"反馈":"行内评论":"评论"}function Jr(e){return e.kind==="commit"||e.kind==="issue-comment"||e.inReplyTo?"dev":"qa"}function Yr({task:e}){const s=pe(),n=qs(e),{data:i,loaded:r,error:o}=Ws(e.id,n);function l(){s(`/tasks/${encodeURIComponent(e.id)}/github-review`)}if(o)return t.jsx(Me,{children:t.jsxs("div",{className:"text-sm text-accent",children:["加载评审记录失败:",o]})});if(!r)return t.jsx(Me,{children:t.jsx("div",{className:"text-sm text-og-400",children:"加载评审记录…"})});if(!(i!=null&&i.available))return t.jsx(Me,{children:t.jsx("div",{className:"text-sm text-og-400",children:ns[(i==null?void 0:i.reason)??"no-pr"]??ns["no-pr"]})});if(i.items.length===0)return t.jsx(Me,{children:i.error?t.jsxs("div",{className:"text-sm text-accent",children:["评审记录拉取失败:",i.error]}):t.jsx("div",{className:"text-sm text-og-400",children:"评审尚未开始"})});const u=Hs(i.items);return t.jsxs(Me,{children:[i.error&&t.jsxs("div",{className:"text-xs text-accent",children:["部分评审记录拉取失败:",i.error,"(仅展示已获取的部分)"]}),u.map((m,h)=>t.jsx(Xr,{round:m,index:h,onOpen:l},Us(m,String(h))))]})}function Me({children:e}){return t.jsxs("div",{children:[t.jsx("div",{className:"mb-1.5 text-xs text-og-700",children:"代码评审"}),t.jsx("div",{className:"space-y-3",children:e})]})}function Xr({round:e,index:s,onOpen:n}){const i=e.review?`第 ${s+1} 轮`:"进行中";return t.jsxs("div",{children:[t.jsx("div",{className:"mb-1 text-xs text-og-400",children:i}),t.jsxs("div",{className:"space-y-1.5",children:[e.items.map((r,o)=>t.jsx(rs,{item:r,onOpen:n},st(r,`${s}-${o}`))),e.review&&t.jsx(rs,{item:e.review,onOpen:n})]})]})}function rs({item:e,onOpen:s}){const n=e.kind==="review"?e.verdict:void 0;return t.jsx(Fe,{role:Jr(e),label:Vr(e),badge:n?t.jsx("span",{className:Bs[n],children:n}):void 0,summary:Kr(e),onClick:s})}const Zr={spec:"Spec 评审",code:"代码评审"},is={approve:"pill pill-live","request-changes":"pill pill-warn"};function as(e){if(!e)return 0;const s=e.endsWith(`
6
6
  `)?e.slice(0,-1):e;return s===""?0:s.split(`
7
7
  `).length}function ei(e){return e.phase==="code"?(e.diffstat??"").split(`
8
- `).map(n=>n.trim()).filter(Boolean).pop()??`diff ${as(e.content)} 行`:`规格文档 ${as(e.content)} 行`}function ti(e){const s={critical:0,major:0,minor:0};for(const r of e.findings)r.severity in s&&s[r.severity]++;const n=[];return s.critical&&n.push(`${s.critical} critical`),s.major&&n.push(`${s.major} major`),s.minor&&n.push(`${s.minor} minor`),`${e.findings.length} 条 findings${n.length?`(${n.join(", ")})`:""}`}function si(e){const s={fix:0,reject:0,"out-of-scope":0};for(const i of e.responses)i.action in s&&s[i.action]++;const n=[];return s.fix&&n.push(`${s.fix} fixed`),s.reject&&n.push(`${s.reject} rejected`),s["out-of-scope"]&&n.push(`${s["out-of-scope"]} out-of-scope`),n.join(" · ")||`${e.responses.length} 条反馈`}function ni({task:e}){const s=e.reviewMode==="server"||(e.specReviewRound??0)>0,n=e.reviewMode!=="server"&&e.prNumber!==void 0;return!s&&!n?null:t.jsxs("section",{className:"mt-4","aria-label":"评审记录",children:[t.jsx("div",{className:"mb-2 text-sm text-og-700",children:"评审记录"}),t.jsxs("div",{className:"space-y-4",children:[s&&t.jsx(ri,{task:e}),n&&t.jsx(Yr,{task:e})]})]})}function ri({task:e}){const s=pe(),n=`${e.specReviewRound??0}:${e.reviewRound}:${e.status}:${e.phase??"code"}`,{rounds:i,loaded:r,error:o}=Fs(e.id,n);function l(u,m,h){s(`/tasks/${encodeURIComponent(e.id)}/rounds/${u}/${m}${h}`)}return o?t.jsxs("div",{className:"text-sm text-accent",children:["加载评审记录失败:",o]}):r?((i==null?void 0:i.length)??0)===0?t.jsx("div",{className:"text-sm text-og-400",children:"评审尚未开始"}):t.jsx(t.Fragment,{children:["spec","code"].map(u=>{const m=(i??[]).filter(h=>h.phase===u).sort((h,v)=>h.round-v.round);return m.length===0?null:t.jsx(ii,{title:Zr[u],children:m.map(h=>t.jsx(ai,{round:h,onOpen:l},`${u}-${h.round}`))},u)})}):t.jsx("div",{className:"text-sm text-og-400",children:"加载评审记录…"})}function ii({title:e,children:s}){return t.jsxs("div",{children:[t.jsx("div",{className:"mb-1.5 text-xs text-og-700",children:e}),t.jsx("div",{className:"space-y-3",children:s})]})}function ai({round:e,onOpen:s}){const n=e.phase==="spec";return t.jsxs("div",{children:[t.jsxs("div",{className:"mb-1 text-xs text-og-400",children:["第 ",e.round," 轮"]}),t.jsxs("div",{className:"space-y-1.5",children:[t.jsx(Fe,{role:"dev",label:n?"提交规格稿":"提交代码改动",summary:ei(e),onClick:()=>s(e.phase,e.round,"")}),e.findings&&t.jsx(Fe,{role:"qa",label:"评审",badge:t.jsx("span",{className:is[e.findings.verdict],children:e.findings.verdict}),summary:ti(e.findings),onClick:()=>s(e.phase,e.round,"#review")}),e.response&&t.jsx(Fe,{role:"dev",label:"反馈",summary:si(e.response),onClick:()=>s(e.phase,e.round,"#response")}),e.userDecision&&t.jsx(Fe,{role:"user",label:e.userDecision.verdict==="approve"?"通过 Spec":"打回 Spec",badge:t.jsx("span",{className:is[e.userDecision.verdict],children:e.userDecision.verdict}),summary:e.userDecision.comments??"",onClick:()=>s(e.phase,e.round,"#review")})]})]})}const os=xs;function oi(e){const[s,n]=a.useState(!1);return a.useEffect(()=>{function i(){if(!e||e.status!=="review"||!e.reviewDispatchedAt||!e.qaAgentId){n(!1);return}const o=Date.now()-Date.parse(e.reviewDispatchedAt);n(o>=gs)}i();const r=setInterval(i,3e4);return()=>clearInterval(r)},[e==null?void 0:e.status,e==null?void 0:e.reviewDispatchedAt,e==null?void 0:e.qaAgentId]),s}function ci(e,s){if(!e||!s)return null;const n=e.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/pull\/\d+/);if(!n)return null;const i=s.split("/").map(encodeURIComponent).join("/");return`${n[1]}/tree/${i}`}function li(){const{taskId:e=""}=He();return t.jsx(di,{taskId:e},e)}function di({taskId:e}){const s=pe(),{show:n}=ve(),i=Ct(),[r,o]=a.useState(!1),[l,u]=a.useState(!1),[m,h]=a.useState(!1),[v,d]=a.useState(!1),[f,p]=a.useState(!1),[x,N]=a.useState(!1),[j,k]=a.useState(!1),[R,E]=a.useState(""),[b,y]=a.useState(null),{data:w,loaded:_,error:L}=Pt(e),{projects:T}=Ue(),{data:F,loaded:O,error:M}=It(),{activeAgentId:z,activateAgentCard:X}=Es(),$=b??w,Z=oi($),q=(L==null?void 0:L.message)??null,V=a.useMemo(()=>new Map((F??[]).map(c=>[c.id,c])),[F]);a.useEffect(()=>{b&&w&&w.updatedAt>=b.updatedAt&&y(null)},[b,w]);const U=c=>{y(c)},Q=async()=>{if($&&await i({title:`取消任务 ${$.id}?`,confirmLabel:"取消任务",cancelLabel:"返回"})){u(!0);try{const c=await I.tasks.update($.id,{status:"cancelled"});U(c),n({kind:"success",title:"任务已取消"})}catch(c){n({kind:"error",title:"取消失败",body:c instanceof Error?c.message:String(c)})}finally{u(!1)}}},se=async()=>{if(!$)return;const c=xs.has($.status);if(await i(c?{title:"重审已结束的任务?",body:`任务 ${$.id} 已是「${Ie($.status)}」状态。手动请 QA agent 重审会再跑一轮 review,但状态机不会把 QA agent 的结果带回主流程。`,confirmLabel:"发起重审"}:{title:"发起 QA 重审?",body:`QA agent 将对任务 ${$.id} 立即开始新一轮 review(reviewRound +1)。`,confirmLabel:"发起重审"})){d(!0);try{const S=await I.tasks.review($.id);U(S),n({kind:"success",title:`已发起 QA 重审(第 ${S.reviewRound} 轮)`})}catch(S){n({kind:"error",title:"发起评审失败",body:S instanceof Error?S.message:String(S)})}finally{d(!1)}}},de=async()=>{if(!(!$||!await i({title:`重试任务 ${$.id}?`,body:$.status==="merged"?"任务已合并。重试会用同样的标题/描述新建一个任务从头跑。":"会新建一个任务从头开始,旧任务保留为历史。",confirmLabel:"重试"}))){h(!0);try{const g=await I.tasks.retry($.id);n({kind:"success",title:`已新建 task ${g.id}`}),s(Ce(g.projectId,g.id))}catch(g){n({kind:"error",title:"重试失败",body:g instanceof Error?g.message:String(g)})}finally{h(!1)}}},B=async()=>{if($&&await i({title:"标记完成并合并?",body:`将合并 PR #${$.prNumber} 并收尾:删本地分支、压缩 agent 上下文。`,confirmLabel:"标记完成"})){p(!0);try{const c=await I.tasks.complete($.id);U(c),n({kind:"success",title:"已标记完成,开始收尾"})}catch(c){n({kind:"error",title:"标记完成失败",body:c instanceof Error?c.message:String(c)})}finally{p(!1)}}},ie=async()=>{if($&&await i({title:"继续一轮?",body:`让 Dev agent 再修一轮(第 ${$.reviewRound+1} 轮),完成后自动转 QA review。`,confirmLabel:"继续一轮"})){N(!0);try{const c=await I.tasks.continue($.id);U(c),n({kind:"success",title:`已继续一轮(第 ${c.reviewRound} 轮)`})}catch(c){n({kind:"error",title:"继续一轮失败",body:c instanceof Error?c.message:String(c)})}finally{N(!1)}}},re=async()=>{if($&&await i({title:"通过 Spec 并开始编码?",body:`任务 ${$.id} 将进入编码阶段。`,confirmLabel:"通过 Spec"})){k(!0);try{const c=await I.tasks.spec($.id,{verdict:"approve"});U(c),E(""),n({kind:"success",title:"Spec 已通过,已发起编码"})}catch(c){n({kind:"error",title:"Spec 通过失败",body:c instanceof Error?c.message:String(c)})}finally{k(!1)}}},le=async()=>{if(!$)return;const c=R.trim();if(c){k(!0);try{const g=await I.tasks.spec($.id,{verdict:"request-changes",comments:c});U(g),E(""),n({kind:"success",title:"Spec 已打回,Dev agent 开始修订"})}catch(g){n({kind:"error",title:"Spec 打回失败",body:g instanceof Error?g.message:String(g)})}finally{k(!1)}}},oe=async()=>{if($&&await i({title:`确认完成任务 ${$.id}?`,body:"project.merge 为 auto 时由 baxian 自动执行合并。",confirmLabel:"确认完成"})){p(!0);try{const c=await I.tasks.complete($.id);U(c),n({kind:"success",title:`已确认(${c.status})`})}catch(c){n({kind:"error",title:"确认失败",body:c instanceof Error?c.message:String(c)})}finally{p(!1)}}};return t.jsxs("div",{children:[t.jsx("button",{type:"button",onClick:()=>s(-1),className:"btn-ghost mb-3",children:"← 返回"}),q&&!$&&t.jsxs("div",{className:"text-sm text-accent",children:["加载失败:",q]}),_&&!$&&!q&&t.jsxs("div",{className:"text-sm text-accent",children:["任务不存在:",e]}),!$&&!q&&!_&&t.jsx("div",{className:"text-sm text-og-500",children:"Loading…"}),$&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"mb-4",children:t.jsxs("h1",{className:"flex min-w-0 items-baseline gap-2",children:[t.jsx("span",{className:"shrink-0 font-mono text-sm text-og-400",children:$.id}),t.jsx("span",{className:"min-w-0 truncate font-display text-sm font-semibold tracking-tight text-og-1000",title:$.title,children:$.title})]})}),t.jsxs("div",{className:"grid grid-cols-1 items-start gap-6 lg:grid-cols-2",children:[t.jsx("section",{className:"min-w-0",children:me($)}),t.jsx("aside",{className:"min-w-0 space-y-4",children:ce($)})]})]}),r&&$&&t.jsx(Tt,{mode:"edit",open:!0,onClose:()=>o(!1),task:$,onUpdated:U})]});function me(c){const g=c.preferredAgentId==="",S=c.status==="approved"&&c.prNumber!==void 0,P=c.status==="merge-ready"&&c.prNumber!==void 0,K=c.status==="spec-ready",J=c.status==="ready",C=c.status==="max_rounds"&&c.phase!=="spec",D=c.status==="max_rounds"&&c.phase==="spec",Y=ci(c.prUrl,c.branch??"");return t.jsxs("div",{children:[q&&t.jsxs("div",{className:"mb-4 text-sm text-accent",children:["加载失败:",q]}),g&&t.jsx("div",{className:"mb-4 rounded-md border border-accent/25 bg-accent-soft/60 px-3 py-2.5 text-xs text-accent",children:c.status==="pending"?t.jsx(t.Fragment,{children:"任务还没有指定 Dev agent:点「编辑」选择,或在任一空闲 Dev agent 卡片上点「发起」。"}):t.jsxs(t.Fragment,{children:["历史任务,无指定 Dev agent,当前状态 ",t.jsx("b",{className:"font-semibold",children:Ie(c.status)}),",只读。"]})}),t.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-3",children:[t.jsx("span",{className:`${Rs[c.status]} text-sm`,title:c.status,children:Ie(c.status)}),t.jsxs("span",{className:"text-sm text-og-500",children:["评审 ",t.jsx("span",{className:"text-og-800",children:c.reviewRound})," 轮"]}),t.jsxs("span",{className:"text-sm text-og-500",children:["Spec ",t.jsx("span",{className:"text-og-800",children:c.specReviewRound??0})," 轮"]})]}),t.jsx("div",{className:"mb-4 flex flex-wrap items-center gap-2",children:A(c)}),t.jsxs("div",{className:"mb-4 text-sm text-og-500",children:["创建于 ",mt(c.createdAt,!1)," · 更新于 ",mt(c.updatedAt,!1)]}),Z&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent/25 bg-accent-soft p-4 text-sm text-accent",children:[t.jsx("div",{className:"font-semibold",children:"评审逾期未交"}),t.jsxs("div",{className:"mt-1 text-og-700",children:["QA agent 于 ",mt(c.reviewDispatchedAt)," 接单,超过 10 分钟未提交结论。 可打开 QA agent 终端查看,或点「发起评审」重新发起。"]})]}),S&&t.jsxs("div",{className:"mb-4 rounded-lg border border-hairline bg-og-25 p-4 text-sm text-og-800",children:[t.jsx("div",{className:"font-semibold",children:"QA agent 已通过 · 正在核对反馈"}),t.jsx("div",{className:"mt-1 text-og-700",children:"Dev agent 正在确认所有评审反馈均已处理,完成后进入收尾。"}),c.prUrl&&t.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"btn-secondary mt-3",children:["查看 PR #",c.prNumber]})]}),J&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent/25 bg-accent-soft p-4 text-sm text-accent",children:[t.jsx("div",{className:"font-semibold",children:"评审通过 · 等你确认"}),t.jsxs("div",{className:"mt-1 text-og-700",children:["Server 评审通过,共 ",c.reviewRound," 轮。点「确认」收尾,或「取消」丢弃。"]}),t.jsx(ls,{taskId:c.id}),c.prUrl&&t.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"btn-secondary mt-3",children:["查看 PR #",c.prNumber]})]}),P&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent/25 bg-accent-soft p-4 text-sm text-accent",children:[t.jsx("div",{className:"font-semibold",children:"PR 就绪 · 等你确认"}),t.jsx("div",{className:"mt-1 text-og-700",children:"Dev agent 已完成收尾自检,点「确认」交由 baxian 收尾。"}),c.prUrl&&t.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"btn-secondary mt-3",children:["查看 PR #",c.prNumber]})]}),K&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent-soft bg-accent-soft/40 p-4 text-sm text-accent",children:[t.jsx("div",{className:"font-semibold",children:"Spec 需由人类审核"}),t.jsxs("div",{className:"mt-1 text-og-700",children:["QA agent 已通过第 ",c.specReviewRound??0," 轮 Spec,全文见下方评审记录。 通过即开始编码;打回意见将交 Dev agent 修订后复审。"]}),t.jsxs("div",{className:"mt-3 flex flex-col gap-2",children:[t.jsx("textarea",{value:R,onChange:G=>E(G.target.value),placeholder:"打回意见(打回时必填)",rows:3,disabled:j,className:ae}),t.jsxs("div",{className:"flex flex-wrap gap-2",children:[t.jsx("button",{type:"button",disabled:j,onClick:re,className:"btn-primary",children:j?"提交中…":"通过 Spec,开始编码"}),t.jsx("button",{type:"button",disabled:j||R.trim()==="",onClick:le,title:R.trim()===""?"先填写打回意见":"意见将作为 findings 交 Dev agent 修订",className:"btn-secondary",children:j?"提交中…":"打回 Spec"})]})]})]}),C&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent/25 bg-accent-soft/60 p-4 text-sm text-accent",children:[t.jsxs("div",{className:"font-semibold",children:["评审已达 ",c.reviewRound," 轮上限"]}),t.jsx("div",{className:"mt-1 text-og-700",children:"可「标记完成」先合并成果,或「继续一轮」再修订。剩余问题建议另开任务,轮次越多 agent 越容易偏题。"})]}),D&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent/25 bg-accent-soft/60 p-4 text-sm text-accent",children:[t.jsxs("div",{className:"font-semibold",children:["Spec 评审已达 ",c.specReviewRound??0," 轮上限"]}),t.jsx("div",{className:"mt-1 text-og-700",children:"多轮未达成一致,任务已暂停。可「重试」新建任务从头跑,或「取消」。建议先看评审记录定位分歧、细化描述后再重试。"}),t.jsx(ls,{taskId:c.id})]}),t.jsxs("div",{className:"card mb-4 flex flex-wrap items-center gap-x-6 gap-y-1 p-4 text-sm",children:[t.jsxs("span",{className:"text-og-500",children:["PR:"," ",c.prNumber?c.prUrl?t.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"text-accent hover:text-accent-hover",children:["#",c.prNumber]}):t.jsxs("span",{className:"font-mono text-og-800",children:["#",c.prNumber]}):t.jsx("span",{className:"text-og-400",children:"—"})]}),t.jsxs("span",{className:"text-og-500",children:["Branch:"," ",c.branch?Y?t.jsx("a",{href:Y,target:"_blank",rel:"noopener noreferrer",className:"font-mono text-accent hover:text-accent-hover",children:c.branch}):t.jsx("span",{className:"font-mono text-og-800",children:c.branch}):t.jsx("span",{className:"text-og-400",children:"—"})]})]}),t.jsx("pre",{className:"card mb-4 whitespace-pre-wrap p-4 text-sm text-og-800",children:c.description||t.jsx("span",{className:"text-og-400",children:"(无描述)"})}),t.jsx(ni,{task:c})]})}function ce(c){if(T===null)return t.jsx("div",{className:"rounded-lg border border-hairline bg-surface px-3 py-6 text-center text-sm text-og-400",children:"加载中…"});const g=T.find(C=>C.id===c.projectId),S=c.agentId||c.preferredAgentId,P=(g==null?void 0:g.agent.find(C=>C.some(D=>D.id===S)))??(c.qaAgentId?g==null?void 0:g.agent.find(C=>C.some(D=>D.id===c.qaAgentId)):void 0),K=P==null?void 0:P.find(C=>C.role==="dev"),J=P==null?void 0:P.find(C=>C.role==="qa");return!K&&!J?t.jsx("div",{className:"rounded-lg border border-hairline bg-surface px-3 py-6 text-center text-sm text-og-400",children:"暂无关联 Agent"}):t.jsxs(t.Fragment,{children:[K?ue(c,K):t.jsx(cs,{role:"dev"}),J?ue(c,J):t.jsx(cs,{role:"qa"})]})}function ue(c,g){const S=V.get(g.id),P=S??{id:g.id,projectId:c.projectId,runtimeStatus:"unknown",tmuxSessionStatus:"unknown",stale:!0};return t.jsx(ks,{agent:P,projectId:c.projectId,role:g.role,runtime:g.runtime,pendingRestart:O&&!S,terminalLoading:!O&&!S&&!M,showTaskBinding:!1,terminalMode:"embedded-full",active:z===g.id,onActivate:()=>X(g.id)},g.id)}function A(c){const g=c.status==="max_rounds",S=g&&c.phase!=="spec",P=g&&c.phase==="spec",K=c.status==="ready"||c.status==="merge-ready",J=c.reviewMode==="server"&&c.status==="approved",C=c.status==="pending",D=c.status==="pending"||c.status==="in_progress"||c.status==="spec-ready"||g||K||J,Y=(os.has(c.status)||P)&&!!c.preferredAgentId,G=!!c.prNumber&&!P&&c.reviewMode!=="server",je=c.reviewMode==="server",ge=S&&(!!c.prNumber||je),Ae=S&&(!!c.prNumber||je)&&!!c.agentId,be=je&&c.status==="approved",we=c.preferredAgentId==="";return t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",disabled:!C,onClick:()=>o(!0),className:"btn-secondary",children:"编辑"}),t.jsx("button",{type:"button",disabled:!D||l,onClick:Q,className:"btn-secondary",children:l?"取消中…":"取消"}),!S&&t.jsx("button",{type:"button",disabled:!Y||m,onClick:de,title:os.has(c.status)||P?we?"历史任务没有指定 Dev agent,无法重试":"新建一个任务从头跑,丢弃当前 worktree/branch":`当前状态「${Ie(c.status)}」不可重试`,className:"btn-secondary",children:m?"重试中…":"重试"}),t.jsx("button",{type:"button",disabled:!G||v,onClick:se,title:c.prNumber?P?"spec 阶段达上限不支持 Call review":"让 QA agent 立即开始新一轮 review(reviewRound +1)":"该任务还没有 PR,无法发起评审",className:"btn-secondary",children:v?"发起中…":"发起评审"}),S&&t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",disabled:!Ae||x,onClick:ie,title:"让 Dev agent 再修一轮,完成后自动转 QA review",className:"btn-secondary",children:x?"继续中…":"继续一轮"}),t.jsx("button",{type:"button",disabled:!ge||f,onClick:B,title:"合并 PR 并收尾(删本地分支 + 压缩上下文)",className:"btn-primary",children:f?"完成中…":"标记完成"})]}),K&&t.jsx("button",{type:"button",disabled:f,onClick:oe,title:"确认完成;merge:auto 时由 baxian 执行合并",className:"btn-primary",children:f?"确认中…":"确认"}),be&&t.jsx("button",{type:"button",disabled:f,onClick:oe,title:"发布失败后重试 push/PR 步骤",className:"btn-primary",children:f?"重试中…":"重试发布"})]})}}function cs({role:e}){return t.jsxs("div",{className:"rounded-lg border border-hairline bg-surface px-3 py-6 text-center text-sm text-og-400",children:["暂无 ",e==="dev"?"Dev":"QA"," agent"]})}function ls({taskId:e}){var o;const[s,n]=a.useState(null);if(a.useEffect(()=>{let l=!0;return I.tasks.reviews(e).then(u=>{l&&n(u)}).catch(()=>{l&&n([])}),()=>{l=!1}},[e]),!s||s.length===0)return null;const i=s[s.length-1],r=s.reduce((l,u)=>{var m;return l+(((m=u.findings)==null?void 0:m.findings.length)??0)},0);return t.jsxs("div",{className:"mt-2 text-xs text-og-700",children:["Review ",s.length," 轮 · 最终 verdict ",t.jsx("span",{className:"font-mono",children:((o=i.findings)==null?void 0:o.verdict)??"—"})," ","· findings 共 ",r," 条"]})}function ui(){const{agentId:e}=He(),{projects:s}=Ue(),n=a.useMemo(()=>{if(e)for(const i of s??[])for(const r of i.agent){const o=r.find(l=>l.id===e);if(o)return o.runtime}},[e,s]);return e?t.jsxs("div",{"data-testid":"terminal-page-container",className:"flex min-h-0 flex-1 flex-col overflow-hidden border border-hairline bg-surface",children:[t.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-xs text-og-500",children:[t.jsx("span",{"aria-hidden":!0,className:"block h-1.5 w-1.5 rounded-full bg-og-1000"}),t.jsx("span",{className:"text-og-700",title:hs(e,n),children:e})]}),t.jsx("div",{className:"min-h-0 flex-1",children:t.jsx(_e,{agentId:e,mode:"full",interactive:!0,arrowKeys:!0})})]}):t.jsx("div",{className:"text-sm text-accent",children:"No agent specified"})}function mi(e){return e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("--- ")||e.startsWith("+++ ")||e.startsWith("new file")||e.startsWith("deleted file")||e.startsWith("rename ")||e.startsWith("similarity ")||e.startsWith("old mode")||e.startsWith("new mode")}function fi(e){if(!e)return[];const s=[];let n=!1;for(const i of e.split(/\r?\n/)){let r;i.startsWith("@@")?(r="hunk",n=!0):i.startsWith("diff --git")?(r="file",n=!1):i.startsWith("\\")?r="meta":n?r=i.startsWith("+")?"add":i.startsWith("-")?"del":"context":mi(i)?r="file":r="context",s.push({type:r,text:i})}return s}const hi={file:"bg-og-50 font-semibold text-og-700",hunk:"bg-accent-soft text-accent",add:"bg-diff-add text-diff-add-ink",del:"bg-diff-del text-diff-del-ink",context:"text-og-700",meta:"text-og-400"};function xi({content:e,diffstat:s}){const n=fi(e);return n.length===0?t.jsx("div",{className:"text-sm text-og-400",children:"无内容"}):t.jsxs("div",{children:[s&&t.jsx("pre",{className:"mb-2 overflow-x-auto rounded-md border border-hairline bg-og-50 p-3 font-mono text-xs text-og-700",children:s.trimEnd()}),t.jsx("div",{className:"overflow-auto rounded-md border border-hairline bg-surface font-mono text-xs leading-[1.5] [max-height:70vh]",children:n.map((i,r)=>t.jsx("div",{className:`whitespace-pre px-3 ${hi[i.type]}`,children:i.text===""?" ":i.text},r))})]})}const pi={critical:"pill pill-warn font-semibold",major:"pill pill-warn",minor:"pill"},gi={fix:"pill pill-live",reject:"pill pill-review","out-of-scope":"pill"};function ds(e){if(!e)return"";const s=e.match(/^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2})/);return s?`${s[1]} ${s[2]}`:e}function us(e){return e.file?e.line?`${e.file}:${e.line}`:e.file:e.location??""}function bi(){const{taskId:e="",phase:s="",round:n=""}=He(),i=pe(),{hash:r}=ms(),{data:o}=Pt(e),l=o?`${o.specReviewRound??0}:${o.reviewRound}:${o.status}:${o.phase??"code"}`:void 0,{rounds:u,loaded:m,error:h}=Fs(e,l),v=Number(n),d=(u??[]).find(f=>f.phase===s&&f.round===v)??null;return a.useEffect(()=>{if(!d||!r)return;const f=document.getElementById(r.replace("#",""));f==null||f.scrollIntoView({behavior:"smooth",block:"start"})},[d,r]),t.jsxs("div",{className:"mx-auto w-full max-w-5xl",children:[t.jsx("button",{type:"button",onClick:()=>i(-1),className:"btn-ghost mb-3",children:"← 返回"}),t.jsxs("div",{className:"mb-1 flex flex-wrap items-baseline gap-2",children:[t.jsx("span",{className:"font-mono text-og-400",children:e}),t.jsx("span",{className:"text-sm font-semibold text-og-1000",children:(o==null?void 0:o.title)??""})]}),t.jsxs("div",{className:"mb-4 flex flex-wrap items-center gap-2 text-xs text-og-500",children:[t.jsx("span",{className:"pill",children:s}),t.jsxs("span",{children:["第 ",n," 轮"]}),(d==null?void 0:d.findings)&&t.jsx("span",{className:d.findings.verdict==="approve"?"pill pill-live":"pill pill-warn",children:d.findings.verdict}),d&&t.jsxs("span",{className:"text-og-400",children:[ds(d.startedAt),d.completedAt?` → ${ds(d.completedAt)}`:""]})]}),!m&&t.jsx("div",{className:"text-sm text-og-500",children:"加载中…"}),m&&h&&t.jsxs("div",{className:"text-sm text-accent",children:["加载评审记录失败:",h]}),m&&!h&&!d&&t.jsxs("div",{className:"text-sm text-accent",children:["未找到该轮评审(",s," 第 ",n," 轮)。"]}),d&&t.jsx(vi,{round:d})]})}function vi({round:e}){var r,o;const s=((r=e.findings)==null?void 0:r.findings)??[],n=((o=e.response)==null?void 0:o.responses)??[],i=new Map(s.map(l=>[l.id,l]));return t.jsxs("div",{className:"space-y-6",children:[t.jsxs("section",{id:"diff",children:[t.jsx("h2",{className:"mb-2 text-sm font-semibold text-og-800",children:e.phase==="spec"?"规格稿":"代码改动"}),e.contentTruncated&&t.jsx("div",{className:"mb-2 text-xs text-accent",children:"内容较大,展示的是截断后的片段。"}),e.content?e.phase==="spec"?t.jsx("pre",{className:"card whitespace-pre-wrap break-words p-4 text-sm text-og-800",children:e.content}):t.jsx(xi,{content:e.content,diffstat:e.diffstat}):t.jsx("div",{className:"text-sm text-og-400",children:"无内容"})]}),t.jsxs("section",{id:"review",children:[t.jsx("h2",{className:"mb-2 text-sm font-semibold text-og-800",children:"QA 评审"}),e.findings===void 0?t.jsx("div",{className:"text-sm text-og-400",children:"评审尚未提交。"}):s.length===0?t.jsx("div",{className:"text-sm text-og-400",children:"本轮无 findings。"}):t.jsx("div",{className:"space-y-2",children:s.map(l=>t.jsxs("div",{className:"card p-3 text-sm",children:[t.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[t.jsx("span",{className:"font-mono text-og-400",children:l.id}),t.jsx("span",{className:pi[l.severity],children:l.severity}),us(l)&&t.jsx("span",{className:"min-w-0 break-all font-mono text-xs text-og-500",children:us(l)})]}),t.jsx("div",{className:"whitespace-pre-wrap break-words text-og-800",children:l.message})]},l.id))})]}),n.length>0&&t.jsxs("section",{id:"response",children:[t.jsx("h2",{className:"mb-2 text-sm font-semibold text-og-800",children:"Dev 反馈"}),t.jsx("div",{className:"space-y-2",children:n.map(l=>{const u=i.get(l.findingId);return t.jsxs("div",{className:"card p-3 text-sm",children:[t.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[t.jsx("span",{className:"font-mono text-og-400",children:l.findingId}),t.jsx("span",{className:gi[l.action],children:l.action}),l.commitSha&&t.jsx("span",{className:"font-mono text-xs text-og-500",children:l.commitSha.slice(0,9)})]}),u&&t.jsxs("div",{className:"mb-1 break-words text-xs text-og-500",children:["↳ ",u.message]}),t.jsx("div",{className:"whitespace-pre-wrap break-words text-og-800",children:l.rationale})]},l.findingId)})})]})]})}const ji={approve:"approve","request-changes":"request-changes",comment:"comment"},wi={"server-mode":"该 task 为 server 评审模式,代码评审记录见任务详情的「评审记录」。","no-pr":"该 task 还没有 PR,暂无代码评审记录。","not-github":"该 task 的仓库不是 GitHub 仓库,无法拉取 PR 评审记录。"};function yi(e){return e==="server-mode"||e==="no-pr"||e==="not-github"?e:void 0}function yt(e){if(!e)return"";const s=e.match(/^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2})/);return s?`${s[1]} ${s[2]}`:e}function Ni(){const{taskId:e=""}=He(),s=pe(),{data:n}=Pt(e),i=n?qs(n):void 0,{data:r,loaded:o,error:l}=Ws(e,i),u=(r==null?void 0:r.prNumber)??(n==null?void 0:n.prNumber),m=(r==null?void 0:r.prUrl)??(n==null?void 0:n.prUrl),h=r?Hs(r.items):[];return t.jsxs("div",{className:"mx-auto w-full max-w-5xl",children:[t.jsx("button",{type:"button",onClick:()=>s(-1),className:"btn-ghost mb-3",children:"← 返回"}),t.jsxs("div",{className:"mb-1 flex flex-wrap items-baseline gap-2",children:[t.jsx("span",{className:"font-mono text-og-400",children:e}),t.jsx("span",{className:"text-sm font-semibold text-og-1000",children:(n==null?void 0:n.title)??""})]}),t.jsxs("div",{className:"mb-4 flex flex-wrap items-center gap-2 text-xs text-og-500",children:[t.jsx("span",{className:"pill",children:"代码评审"}),m&&u!==void 0&&t.jsxs("a",{href:m,target:"_blank",rel:"noopener noreferrer",className:"text-accent hover:text-accent-hover",children:["查看 PR #",u]})]}),!o&&t.jsx("div",{className:"text-sm text-og-500",children:"加载中…"}),o&&l&&t.jsxs("div",{className:"text-sm text-accent",children:["加载评审记录失败:",l]}),o&&!l&&r&&!r.available&&t.jsx("div",{className:"text-sm text-og-500",children:wi[yi(r.reason)??"no-pr"]}),o&&!l&&(r==null?void 0:r.available)&&(r.items.length===0?r.error?t.jsxs("div",{className:"text-sm text-accent",children:["评审记录拉取失败:",r.error]}):t.jsx("div",{className:"text-sm text-og-400",children:"评审尚未开始"}):t.jsxs(t.Fragment,{children:[r.error&&t.jsxs("div",{className:"mb-3 text-xs text-accent",children:["部分评审记录拉取失败:",r.error,"(仅展示已获取的部分)"]}),t.jsx("div",{className:"space-y-5",children:h.map((v,d)=>t.jsx(Si,{round:v,index:d},Us(v,String(d))))})]}))]})}function Si({round:e,index:s}){const n=e.review?`第 ${s+1} 轮`:"进行中";return t.jsxs("div",{children:[t.jsx("div",{className:"mb-1.5 text-xs font-medium text-og-700",children:n}),t.jsxs("div",{className:"space-y-2",children:[e.items.map((i,r)=>t.jsx(ki,{item:i},st(i,`${s}-${r}`))),e.review&&t.jsx(Ei,{item:e.review})]})]})}function ki({item:e}){if(e.kind==="commit")return t.jsxs("div",{className:"card p-3 text-sm",children:[t.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[t.jsx("span",{className:"pill shrink-0",children:"提交"}),e.commitSha&&t.jsx("span",{className:"font-mono text-xs text-og-500",children:e.commitSha.slice(0,9)}),e.author&&t.jsx("span",{className:"text-xs text-og-400",children:e.author}),e.createdAt&&t.jsx("span",{className:"text-xs text-og-400",children:yt(e.createdAt)})]}),e.body&&t.jsx("div",{className:"whitespace-pre-wrap break-words text-og-800",children:e.body})]});const s=e.kind==="review-comment";return t.jsxs("div",{className:"card p-3 text-sm",children:[t.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[t.jsx("span",{className:"pill shrink-0",children:s?"行内评论":"评论"}),e.author&&t.jsx("span",{className:"font-medium text-og-700",children:e.author}),s&&e.path&&t.jsx("span",{className:"min-w-0 break-all font-mono text-xs text-og-500",children:e.line!==void 0?`${e.path}:${e.line}`:e.path}),e.inReplyTo&&t.jsx("span",{className:"text-xs text-og-400",children:"↩ 回复"}),e.createdAt&&t.jsx("span",{className:"text-xs text-og-400",children:yt(e.createdAt)})]}),t.jsx(zs,{item:e})]})}function Ei({item:e}){const s=e.verdict??"comment";return t.jsxs("div",{className:"card p-3 text-sm",children:[t.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[t.jsx("span",{className:"shrink-0 min-w-[1.75rem] text-xs font-semibold tracking-wide text-og-600",children:"QA"}),t.jsx("span",{className:Bs[s],children:ji[s]}),e.author&&t.jsx("span",{className:"text-xs text-og-400",children:e.author}),e.commitSha&&t.jsx("span",{className:"font-mono text-xs text-og-500",children:e.commitSha.slice(0,9)}),e.createdAt&&t.jsx("span",{className:"text-xs text-og-400",children:yt(e.createdAt)})]}),t.jsx(zs,{item:e,placeholder:"(无评审正文)"})]})}function zs({item:e,placeholder:s}){return t.jsxs(t.Fragment,{children:[e.body?t.jsx("div",{className:"whitespace-pre-wrap break-words text-og-800",children:e.body}):s?t.jsx("div",{className:"text-og-400",children:s}):null,e.bodyTruncated&&t.jsx("div",{className:"mt-1 text-xs text-accent",children:"内容较大,已截断。"})]})}function Ri(){const[e,s]=a.useState(!1);return t.jsx("button",{type:"button",onClick:()=>s(n=>!n),"aria-label":e?"切换为 Logo 图标":"切换为 Logo 文字",className:"flex h-7 min-w-[60px] shrink-0 items-center justify-center font-display text-sm font-semibold tracking-tight text-og-1000",children:e?t.jsx("span",{className:"inline-flex h-6 items-center leading-none",children:"baxian"}):t.jsx("img",{src:"/baxian-logo.png",alt:"baxian",width:20,height:24,className:"block h-6 w-auto"})})}function Ci(){const{phase:e,count:s,error:n,triggerRestart:i}=rt();return e==="idle"?null:e==="failed"?t.jsxs("div",{className:"flex items-center justify-between border-b border-accent/25 bg-accent-soft px-4 py-2",children:[t.jsxs("div",{className:"text-sm text-accent",children:["重启失败:",n]}),t.jsx("button",{onClick:()=>{i()},className:"btn-ghost",children:"重试"})]}):e==="restarting"?t.jsx("div",{className:"border-b border-accent-soft bg-accent-soft/40 px-4 py-2 text-sm text-accent",children:"重启中…"}):t.jsxs("div",{className:"flex items-center justify-between border-b border-accent/25 bg-accent-soft/60 px-4 py-2",children:[t.jsxs("div",{className:"text-sm text-accent",children:["有 ",s," 项配置变更待重启 baxian server 才生效"]}),t.jsx("button",{onClick:()=>{i()},className:"btn-primary",children:"现在重启"})]})}const Ai=new Set(["done","merged"]);function gt(e,s){const n=e.trim().replace(/\s+/g," ");return n.length>s?`${n.slice(0,s-1)}…`:n}function $i(e,s){return e?e.repo?`${e.id} · ${e.repo}`:e.id:s}function Ti(e){return e.title?`${e.id} · ${e.title}`:e.id}function Ii(e){return Ai.has(e)}function Pi(e,s,n){const i=Lt();if(!(!i||i.permission!=="granted"))try{const r=new i(`任务完成:${gt(e.title||e.id,80)}`,{body:[`项目:${gt(s,120)}`,`任务:${gt(Ti(e),120)}`,`状态:${Ie(e.status)}`].join(`
8
+ `).map(n=>n.trim()).filter(Boolean).pop()??`diff ${as(e.content)} 行`:`规格文档 ${as(e.content)} 行`}function ti(e){const s={critical:0,major:0,minor:0};for(const r of e.findings)r.severity in s&&s[r.severity]++;const n=[];return s.critical&&n.push(`${s.critical} critical`),s.major&&n.push(`${s.major} major`),s.minor&&n.push(`${s.minor} minor`),`${e.findings.length} 条 findings${n.length?`(${n.join(", ")})`:""}`}function si(e){const s={fix:0,reject:0,"out-of-scope":0};for(const i of e.responses)i.action in s&&s[i.action]++;const n=[];return s.fix&&n.push(`${s.fix} fixed`),s.reject&&n.push(`${s.reject} rejected`),s["out-of-scope"]&&n.push(`${s["out-of-scope"]} out-of-scope`),n.join(" · ")||`${e.responses.length} 条反馈`}function ni({task:e}){const s=e.reviewMode==="server"||(e.specReviewRound??0)>0,n=e.reviewMode!=="server"&&e.prNumber!==void 0;return!s&&!n?null:t.jsxs("section",{className:"mt-4","aria-label":"评审记录",children:[t.jsx("div",{className:"mb-2 text-sm text-og-700",children:"评审记录"}),t.jsxs("div",{className:"space-y-4",children:[s&&t.jsx(ri,{task:e}),n&&t.jsx(Yr,{task:e})]})]})}function ri({task:e}){const s=pe(),n=`${e.specReviewRound??0}:${e.reviewRound}:${e.status}:${e.phase??"code"}`,{rounds:i,loaded:r,error:o}=Fs(e.id,n);function l(u,m,h){s(`/tasks/${encodeURIComponent(e.id)}/rounds/${u}/${m}${h}`)}return o?t.jsxs("div",{className:"text-sm text-accent",children:["加载评审记录失败:",o]}):r?((i==null?void 0:i.length)??0)===0?t.jsx("div",{className:"text-sm text-og-400",children:"评审尚未开始"}):t.jsx(t.Fragment,{children:["spec","code"].map(u=>{const m=(i??[]).filter(h=>h.phase===u).sort((h,v)=>h.round-v.round);return m.length===0?null:t.jsx(ii,{title:Zr[u],children:m.map(h=>t.jsx(ai,{round:h,onOpen:l},`${u}-${h.round}`))},u)})}):t.jsx("div",{className:"text-sm text-og-400",children:"加载评审记录…"})}function ii({title:e,children:s}){return t.jsxs("div",{children:[t.jsx("div",{className:"mb-1.5 text-xs text-og-700",children:e}),t.jsx("div",{className:"space-y-3",children:s})]})}function ai({round:e,onOpen:s}){const n=e.phase==="spec";return t.jsxs("div",{children:[t.jsxs("div",{className:"mb-1 text-xs text-og-400",children:["第 ",e.round," 轮"]}),t.jsxs("div",{className:"space-y-1.5",children:[t.jsx(Fe,{role:"dev",label:n?"提交规格稿":"提交代码改动",summary:ei(e),onClick:()=>s(e.phase,e.round,"")}),e.findings&&t.jsx(Fe,{role:"qa",label:"评审",badge:t.jsx("span",{className:is[e.findings.verdict],children:e.findings.verdict}),summary:ti(e.findings),onClick:()=>s(e.phase,e.round,"#review")}),e.response&&t.jsx(Fe,{role:"dev",label:"反馈",summary:si(e.response),onClick:()=>s(e.phase,e.round,"#response")}),e.userDecision&&t.jsx(Fe,{role:"user",label:e.userDecision.verdict==="approve"?"通过 Spec":"打回 Spec",badge:t.jsx("span",{className:is[e.userDecision.verdict],children:e.userDecision.verdict}),summary:e.userDecision.comments??"",onClick:()=>s(e.phase,e.round,"#review")})]})]})}const os=xs;function oi(e){const[s,n]=a.useState(!1);return a.useEffect(()=>{function i(){if(!e||e.status!=="review"||!e.reviewDispatchedAt||!e.qaAgentId){n(!1);return}const o=Date.now()-Date.parse(e.reviewDispatchedAt);n(o>=gs)}i();const r=setInterval(i,3e4);return()=>clearInterval(r)},[e==null?void 0:e.status,e==null?void 0:e.reviewDispatchedAt,e==null?void 0:e.qaAgentId]),s}function ci(e,s){if(!e||!s)return null;const n=e.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/pull\/\d+/);if(!n)return null;const i=s.split("/").map(encodeURIComponent).join("/");return`${n[1]}/tree/${i}`}function li(){const{taskId:e=""}=He();return t.jsx(di,{taskId:e},e)}function di({taskId:e}){const s=pe(),{show:n}=ve(),i=Ct(),[r,o]=a.useState(!1),[l,u]=a.useState(!1),[m,h]=a.useState(!1),[v,d]=a.useState(!1),[f,p]=a.useState(!1),[x,N]=a.useState(!1),[j,k]=a.useState(!1),[R,E]=a.useState(""),[b,y]=a.useState(null),{data:w,loaded:_,error:L}=Pt(e),{projects:T}=Ue(),{data:F,loaded:O,error:M}=It(),{activeAgentId:z,activateAgentCard:X}=Es(),$=b??w,Z=oi($),q=(L==null?void 0:L.message)??null,V=a.useMemo(()=>new Map((F??[]).map(c=>[c.id,c])),[F]);a.useEffect(()=>{b&&w&&w.updatedAt>=b.updatedAt&&y(null)},[b,w]);const U=c=>{y(c)},Q=async()=>{if($&&await i({title:`取消任务 ${$.id}?`,confirmLabel:"取消任务",cancelLabel:"返回"})){u(!0);try{const c=await I.tasks.update($.id,{status:"cancelled"});U(c),n({kind:"success",title:"任务已取消"})}catch(c){n({kind:"error",title:"取消失败",body:c instanceof Error?c.message:String(c)})}finally{u(!1)}}},se=async()=>{if(!$)return;const c=xs.has($.status);if(await i(c?{title:"重审已结束的任务?",body:`任务 ${$.id} 已是「${Ie($.status)}」状态。手动请 QA agent 重审会再跑一轮 review,但状态机不会把 QA agent 的结果带回主流程。`,confirmLabel:"发起重审"}:{title:"发起 QA 重审?",body:`QA agent 将对任务 ${$.id} 立即开始新一轮 review(reviewRound +1)。`,confirmLabel:"发起重审"})){d(!0);try{const S=await I.tasks.review($.id);U(S),n({kind:"success",title:`已发起 QA 重审(第 ${S.reviewRound} 轮)`})}catch(S){n({kind:"error",title:"发起评审失败",body:S instanceof Error?S.message:String(S)})}finally{d(!1)}}},de=async()=>{if(!(!$||!await i({title:`重试任务 ${$.id}?`,body:$.status==="merged"?"任务已合并。重试会用同样的标题/描述新建一个任务从头跑。":"会新建一个任务从头开始,旧任务保留为历史。",confirmLabel:"重试"}))){h(!0);try{const g=await I.tasks.retry($.id);n({kind:"success",title:`已新建 task ${g.id}`}),s(Ce(g.projectId,g.id))}catch(g){n({kind:"error",title:"重试失败",body:g instanceof Error?g.message:String(g)})}finally{h(!1)}}},B=async()=>{if($&&await i({title:"标记完成并合并?",body:`将合并 PR #${$.prNumber} 并收尾:删本地分支、压缩 agent 上下文。`,confirmLabel:"标记完成"})){p(!0);try{const c=await I.tasks.complete($.id);U(c),n({kind:"success",title:"已标记完成,开始收尾"})}catch(c){n({kind:"error",title:"标记完成失败",body:c instanceof Error?c.message:String(c)})}finally{p(!1)}}},ie=async()=>{if($&&await i({title:"继续一轮?",body:`让 Dev agent 再修一轮(第 ${$.reviewRound+1} 轮),完成后自动转 QA review。`,confirmLabel:"继续一轮"})){N(!0);try{const c=await I.tasks.continue($.id);U(c),n({kind:"success",title:`已继续一轮(第 ${c.reviewRound} 轮)`})}catch(c){n({kind:"error",title:"继续一轮失败",body:c instanceof Error?c.message:String(c)})}finally{N(!1)}}},re=async()=>{if($&&await i({title:"通过 Spec 并开始编码?",body:`任务 ${$.id} 将进入编码阶段。`,confirmLabel:"通过 Spec"})){k(!0);try{const c=await I.tasks.spec($.id,{verdict:"approve"});U(c),E(""),n({kind:"success",title:"Spec 已通过,已发起编码"})}catch(c){n({kind:"error",title:"Spec 通过失败",body:c instanceof Error?c.message:String(c)})}finally{k(!1)}}},le=async()=>{if(!$)return;const c=R.trim();if(c){k(!0);try{const g=await I.tasks.spec($.id,{verdict:"request-changes",comments:c});U(g),E(""),n({kind:"success",title:"Spec 已打回,Dev agent 开始修订"})}catch(g){n({kind:"error",title:"Spec 打回失败",body:g instanceof Error?g.message:String(g)})}finally{k(!1)}}},oe=async()=>{if($&&await i({title:`确认完成任务 ${$.id}?`,body:"project.merge 为 auto 时由 baxian 自动执行合并。",confirmLabel:"确认完成"})){p(!0);try{const c=await I.tasks.complete($.id);U(c),n({kind:"success",title:`已确认(${c.status})`})}catch(c){n({kind:"error",title:"确认失败",body:c instanceof Error?c.message:String(c)})}finally{p(!1)}}};return t.jsxs("div",{children:[t.jsx("button",{type:"button",onClick:()=>s(-1),className:"btn-ghost mb-3",children:"← 返回"}),q&&!$&&t.jsxs("div",{className:"text-sm text-accent",children:["加载失败:",q]}),_&&!$&&!q&&t.jsxs("div",{className:"text-sm text-accent",children:["任务不存在:",e]}),!$&&!q&&!_&&t.jsx("div",{className:"text-sm text-og-500",children:"Loading…"}),$&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"mb-4",children:t.jsxs("h1",{className:"flex min-w-0 items-baseline gap-2",children:[t.jsx("span",{className:"shrink-0 font-mono text-sm text-og-400",children:$.id}),t.jsx("span",{className:"min-w-0 truncate font-display text-sm font-semibold tracking-tight text-og-1000",title:$.title,children:$.title})]})}),t.jsxs("div",{className:"grid grid-cols-1 items-start gap-6 lg:grid-cols-2",children:[t.jsx("section",{className:"min-w-0",children:me($)}),t.jsx("aside",{className:"min-w-0 space-y-4",children:ce($)})]})]}),r&&$&&t.jsx(Tt,{mode:"edit",open:!0,onClose:()=>o(!1),task:$,onUpdated:U})]});function me(c){const g=c.preferredAgentId==="",S=c.status==="approved"&&c.prNumber!==void 0,P=c.status==="merge-ready"&&c.prNumber!==void 0,K=c.status==="spec-ready",J=c.status==="ready",C=c.status==="max_rounds"&&c.phase!=="spec",D=c.status==="max_rounds"&&c.phase==="spec",Y=ci(c.prUrl,c.branch??"");return t.jsxs("div",{children:[q&&t.jsxs("div",{className:"mb-4 text-sm text-accent",children:["加载失败:",q]}),g&&t.jsx("div",{className:"mb-4 rounded-md border border-accent/25 bg-accent-soft/60 px-3 py-2.5 text-xs text-accent",children:c.status==="pending"?t.jsx(t.Fragment,{children:"任务还没有指定 Dev agent:点「编辑」选择,或在任一空闲 Dev agent 卡片上点「发起」。"}):t.jsxs(t.Fragment,{children:["历史任务,无指定 Dev agent,当前状态 ",t.jsx("b",{className:"font-semibold",children:Ie(c.status)}),",只读。"]})}),t.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-3",children:[t.jsx("span",{className:`${Rs[c.status]} text-sm`,title:c.status,children:Ie(c.status)}),t.jsxs("span",{className:"text-sm text-og-500",children:["评审 ",t.jsx("span",{className:"text-og-800",children:c.reviewRound})," 轮"]}),t.jsxs("span",{className:"text-sm text-og-500",children:["Spec ",t.jsx("span",{className:"text-og-800",children:c.specReviewRound??0})," 轮"]})]}),t.jsx("div",{className:"mb-4 flex flex-wrap items-center gap-2",children:A(c)}),t.jsxs("div",{className:"mb-4 text-sm text-og-500",children:["创建于 ",mt(c.createdAt,!1)," · 更新于 ",mt(c.updatedAt,!1)]}),Z&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent/25 bg-accent-soft p-4 text-sm text-accent",children:[t.jsx("div",{className:"font-semibold",children:"评审逾期未交"}),t.jsxs("div",{className:"mt-1 text-og-700",children:["QA agent 于 ",mt(c.reviewDispatchedAt)," 接单,超过 10 分钟未提交结论。 可打开 QA agent 终端查看,或点「发起评审」重新发起。"]})]}),S&&t.jsxs("div",{className:"mb-4 rounded-lg border border-hairline bg-og-25 p-4 text-sm text-og-800",children:[t.jsx("div",{className:"font-semibold",children:"QA agent 已通过 · 正在核对反馈"}),t.jsx("div",{className:"mt-1 text-og-700",children:"Dev agent 正在确认所有评审反馈均已处理,完成后进入收尾。"}),c.prUrl&&t.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"btn-secondary mt-3",children:["查看 PR #",c.prNumber]})]}),J&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent/25 bg-accent-soft p-4 text-sm text-accent",children:[t.jsx("div",{className:"font-semibold",children:"评审通过 · 等你确认"}),t.jsxs("div",{className:"mt-1 text-og-700",children:["Server 评审通过,共 ",c.reviewRound," 轮。点「确认」收尾,或「取消」丢弃。"]}),t.jsx(ls,{taskId:c.id}),c.prUrl&&t.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"btn-secondary mt-3",children:["查看 PR #",c.prNumber]})]}),P&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent/25 bg-accent-soft p-4 text-sm text-accent",children:[t.jsx("div",{className:"font-semibold",children:"PR 就绪 · 等你确认"}),t.jsx("div",{className:"mt-1 text-og-700",children:"Dev agent 已完成收尾自检,点「确认」交由 baxian 收尾。"}),c.prUrl&&t.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"btn-secondary mt-3",children:["查看 PR #",c.prNumber]})]}),K&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent-soft bg-accent-soft/40 p-4 text-sm text-accent",children:[t.jsx("div",{className:"font-semibold",children:"Spec 需由人类审核"}),t.jsxs("div",{className:"mt-1 text-og-700",children:["QA agent 已通过第 ",c.specReviewRound??0," 轮 Spec,全文见下方评审记录。 通过即开始编码;打回意见将交 Dev agent 修订后复审。"]}),t.jsxs("div",{className:"mt-3 flex flex-col gap-2",children:[t.jsx("textarea",{value:R,onChange:G=>E(G.target.value),placeholder:"打回意见(打回时必填)",rows:3,disabled:j,className:ae}),t.jsxs("div",{className:"flex flex-wrap gap-2",children:[t.jsx("button",{type:"button",disabled:j,onClick:re,className:"btn-primary",children:j?"提交中…":"通过 Spec,开始编码"}),t.jsx("button",{type:"button",disabled:j||R.trim()==="",onClick:le,title:R.trim()===""?"先填写打回意见":"意见将作为 findings 交 Dev agent 修订",className:"btn-secondary",children:j?"提交中…":"打回 Spec"})]})]})]}),C&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent/25 bg-accent-soft/60 p-4 text-sm text-accent",children:[t.jsxs("div",{className:"font-semibold",children:["评审已达 ",c.reviewRound," 轮上限"]}),t.jsx("div",{className:"mt-1 text-og-700",children:"可「标记完成」先合并成果,或「继续一轮」再修订。剩余问题建议另开任务,轮次越多 agent 越容易偏题。"})]}),D&&t.jsxs("div",{className:"mb-4 rounded-lg border border-accent/25 bg-accent-soft/60 p-4 text-sm text-accent",children:[t.jsxs("div",{className:"font-semibold",children:["Spec 评审已达 ",c.specReviewRound??0," 轮上限"]}),t.jsx("div",{className:"mt-1 text-og-700",children:"多轮未达成一致,任务已暂停。可「重试」新建任务从头跑,或「取消」。建议先看评审记录定位分歧、细化描述后再重试。"}),t.jsx(ls,{taskId:c.id})]}),t.jsxs("div",{className:"card mb-4 flex flex-wrap items-center gap-x-6 gap-y-1 p-4 text-sm",children:[t.jsxs("span",{className:"text-og-500",children:["PR:"," ",c.prNumber?c.prUrl?t.jsxs("a",{href:c.prUrl,target:"_blank",rel:"noopener noreferrer",className:"text-accent hover:text-accent-hover",children:["#",c.prNumber]}):t.jsxs("span",{className:"font-mono text-og-800",children:["#",c.prNumber]}):t.jsx("span",{className:"text-og-400",children:"—"})]}),t.jsxs("span",{className:"text-og-500",children:["Branch:"," ",c.branch?Y?t.jsx("a",{href:Y,target:"_blank",rel:"noopener noreferrer",className:"font-mono text-accent hover:text-accent-hover",children:c.branch}):t.jsx("span",{className:"font-mono text-og-800",children:c.branch}):t.jsx("span",{className:"text-og-400",children:"—"})]})]}),t.jsx("pre",{className:"card mb-4 whitespace-pre-wrap p-4 text-sm text-og-800",children:c.description||t.jsx("span",{className:"text-og-400",children:"(无描述)"})}),t.jsx(ni,{task:c})]})}function ce(c){if(T===null)return t.jsx("div",{className:"rounded-lg border border-hairline bg-surface px-3 py-6 text-center text-sm text-og-400",children:"加载中…"});const g=T.find(C=>C.id===c.projectId),S=c.agentId||c.preferredAgentId,P=(g==null?void 0:g.agent.find(C=>C.some(D=>D.id===S)))??(c.qaAgentId?g==null?void 0:g.agent.find(C=>C.some(D=>D.id===c.qaAgentId)):void 0),K=P==null?void 0:P.find(C=>C.role==="dev"),J=P==null?void 0:P.find(C=>C.role==="qa");return!K&&!J?t.jsx("div",{className:"rounded-lg border border-hairline bg-surface px-3 py-6 text-center text-sm text-og-400",children:"暂无关联 Agent"}):t.jsxs(t.Fragment,{children:[K?ue(c,K):t.jsx(cs,{role:"dev"}),J?ue(c,J):t.jsx(cs,{role:"qa"})]})}function ue(c,g){const S=V.get(g.id),P=S??{id:g.id,projectId:c.projectId,runtimeStatus:"unknown",tmuxSessionStatus:"unknown",stale:!0};return t.jsx(ks,{agent:P,projectId:c.projectId,role:g.role,runtime:g.runtime,pendingRestart:O&&!S,terminalLoading:!O&&!S&&!M,showTaskBinding:!1,terminalMode:"embedded-full",active:z===g.id,onActivate:()=>X(g.id)},g.id)}function A(c){const g=c.status==="max_rounds",S=g&&c.phase!=="spec",P=g&&c.phase==="spec",K=c.status==="ready"||c.status==="merge-ready",J=c.reviewMode==="server"&&c.status==="approved",C=c.status==="pending",D=c.status==="pending"||c.status==="in_progress"||c.status==="spec-ready"||g||K||J,Y=(os.has(c.status)||P)&&!!c.preferredAgentId,G=!!c.prNumber&&!P&&c.reviewMode!=="server",je=c.reviewMode==="server",ge=S&&(!!c.prNumber||je),Ae=S&&(!!c.prNumber||je)&&!!c.agentId,be=je&&c.status==="approved",we=c.preferredAgentId==="";return t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",disabled:!C,onClick:()=>o(!0),className:"btn-secondary",children:"编辑"}),t.jsx("button",{type:"button",disabled:!D||l,onClick:Q,className:"btn-secondary",children:l?"取消中…":"取消"}),!S&&t.jsx("button",{type:"button",disabled:!Y||m,onClick:de,title:os.has(c.status)||P?we?"历史任务没有指定 Dev agent,无法重试":"新建一个任务从头跑,丢弃当前 worktree/branch":`当前状态「${Ie(c.status)}」不可重试`,className:"btn-secondary",children:m?"重试中…":"重试"}),t.jsx("button",{type:"button",disabled:!G||v,onClick:se,title:c.prNumber?P?"spec 阶段达上限不支持 Call review":"让 QA agent 立即开始新一轮 review(reviewRound +1)":"该任务还没有 PR,无法发起评审",className:"btn-secondary",children:v?"发起中…":"发起评审"}),S&&t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",disabled:!Ae||x,onClick:ie,title:"让 Dev agent 再修一轮,完成后自动转 QA review",className:"btn-secondary",children:x?"继续中…":"继续一轮"}),t.jsx("button",{type:"button",disabled:!ge||f,onClick:B,title:"合并 PR 并收尾(删本地分支 + 压缩上下文)",className:"btn-primary",children:f?"完成中…":"标记完成"})]}),K&&t.jsx("button",{type:"button",disabled:f,onClick:oe,title:"确认完成;merge:auto 时由 baxian 执行合并",className:"btn-primary",children:f?"确认中…":"确认"}),be&&t.jsx("button",{type:"button",disabled:f,onClick:oe,title:"发布失败后重试 push/PR 步骤",className:"btn-primary",children:f?"重试中…":"重试发布"})]})}}function cs({role:e}){return t.jsxs("div",{className:"rounded-lg border border-hairline bg-surface px-3 py-6 text-center text-sm text-og-400",children:["暂无 ",e==="dev"?"Dev":"QA"," agent"]})}function ls({taskId:e}){var o;const[s,n]=a.useState(null);if(a.useEffect(()=>{let l=!0;return I.tasks.reviews(e).then(u=>{l&&n(u)}).catch(()=>{l&&n([])}),()=>{l=!1}},[e]),!s||s.length===0)return null;const i=s[s.length-1],r=s.reduce((l,u)=>{var m;return l+(((m=u.findings)==null?void 0:m.findings.length)??0)},0);return t.jsxs("div",{className:"mt-2 text-xs text-og-700",children:["Review ",s.length," 轮 · 最终 verdict ",t.jsx("span",{className:"font-mono",children:((o=i.findings)==null?void 0:o.verdict)??"—"})," ","· findings 共 ",r," 条"]})}function ui(){const{agentId:e}=He(),{projects:s}=Ue(),n=a.useMemo(()=>{if(e)for(const i of s??[])for(const r of i.agent){const o=r.find(l=>l.id===e);if(o)return o.runtime}},[e,s]);return e?t.jsxs("div",{"data-testid":"terminal-page-container",className:"flex min-h-0 flex-1 flex-col overflow-hidden border border-hairline bg-surface",children:[t.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-xs text-og-500",children:[t.jsx("span",{"aria-hidden":!0,className:"block h-1.5 w-1.5 rounded-full bg-og-1000"}),t.jsx("span",{className:"text-og-700",title:hs(e,n),children:e})]}),t.jsx("div",{className:"min-h-0 flex-1",children:t.jsx(_e,{agentId:e,mode:"full",interactive:!0,arrowKeys:!0})})]}):t.jsx("div",{className:"text-sm text-accent",children:"No agent specified"})}function mi(e){return e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("--- ")||e.startsWith("+++ ")||e.startsWith("new file")||e.startsWith("deleted file")||e.startsWith("rename ")||e.startsWith("similarity ")||e.startsWith("old mode")||e.startsWith("new mode")}function fi(e){if(!e)return[];const s=[];let n=!1;for(const i of e.split(/\r?\n/)){let r;i.startsWith("@@")?(r="hunk",n=!0):i.startsWith("diff --git")?(r="file",n=!1):i.startsWith("\\")?r="meta":n?r=i.startsWith("+")?"add":i.startsWith("-")?"del":"context":mi(i)?r="file":r="context",s.push({type:r,text:i})}return s}const hi={file:"bg-og-50 font-semibold text-og-700",hunk:"bg-accent-soft text-accent",add:"bg-diff-add text-diff-add-ink",del:"bg-diff-del text-diff-del-ink",context:"text-og-700",meta:"text-og-400"};function xi({content:e,diffstat:s}){const n=fi(e);return n.length===0?t.jsx("div",{className:"text-sm text-og-400",children:"无内容"}):t.jsxs("div",{children:[s&&t.jsx("pre",{className:"mb-2 overflow-x-auto rounded-md border border-hairline bg-og-50 p-3 font-mono text-xs text-og-700",children:s.trimEnd()}),t.jsx("div",{className:"overflow-auto rounded-md border border-hairline bg-surface font-mono text-xs leading-[1.5] [max-height:70vh]",children:n.map((i,r)=>t.jsx("div",{className:`whitespace-pre px-3 ${hi[i.type]}`,children:i.text===""?" ":i.text},r))})]})}const pi={critical:"pill pill-danger font-semibold",major:"pill pill-warn",minor:"pill"},gi={fix:"pill pill-live",reject:"pill pill-warn","out-of-scope":"pill"};function ds(e){if(!e)return"";const s=e.match(/^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2})/);return s?`${s[1]} ${s[2]}`:e}function us(e){return e.file?e.line?`${e.file}:${e.line}`:e.file:e.location??""}function bi(){const{taskId:e="",phase:s="",round:n=""}=He(),i=pe(),{hash:r}=ms(),{data:o}=Pt(e),l=o?`${o.specReviewRound??0}:${o.reviewRound}:${o.status}:${o.phase??"code"}`:void 0,{rounds:u,loaded:m,error:h}=Fs(e,l),v=Number(n),d=(u??[]).find(f=>f.phase===s&&f.round===v)??null;return a.useEffect(()=>{if(!d||!r)return;const f=document.getElementById(r.replace("#",""));f==null||f.scrollIntoView({behavior:"smooth",block:"start"})},[d,r]),t.jsxs("div",{className:"mx-auto w-full max-w-5xl",children:[t.jsx("button",{type:"button",onClick:()=>i(-1),className:"btn-ghost mb-3",children:"← 返回"}),t.jsxs("div",{className:"mb-1 flex flex-wrap items-baseline gap-2",children:[t.jsx("span",{className:"font-mono text-og-400",children:e}),t.jsx("span",{className:"text-sm font-semibold text-og-1000",children:(o==null?void 0:o.title)??""})]}),t.jsxs("div",{className:"mb-4 flex flex-wrap items-center gap-2 text-xs text-og-500",children:[t.jsx("span",{className:"pill",children:s}),t.jsxs("span",{children:["第 ",n," 轮"]}),(d==null?void 0:d.findings)&&t.jsx("span",{className:d.findings.verdict==="approve"?"pill pill-live":"pill pill-warn",children:d.findings.verdict}),d&&t.jsxs("span",{className:"text-og-400",children:[ds(d.startedAt),d.completedAt?` → ${ds(d.completedAt)}`:""]})]}),!m&&t.jsx("div",{className:"text-sm text-og-500",children:"加载中…"}),m&&h&&t.jsxs("div",{className:"text-sm text-accent",children:["加载评审记录失败:",h]}),m&&!h&&!d&&t.jsxs("div",{className:"text-sm text-accent",children:["未找到该轮评审(",s," 第 ",n," 轮)。"]}),d&&t.jsx(vi,{round:d})]})}function vi({round:e}){var r,o;const s=((r=e.findings)==null?void 0:r.findings)??[],n=((o=e.response)==null?void 0:o.responses)??[],i=new Map(s.map(l=>[l.id,l]));return t.jsxs("div",{className:"space-y-6",children:[t.jsxs("section",{id:"diff",children:[t.jsx("h2",{className:"mb-2 text-sm font-semibold text-og-800",children:e.phase==="spec"?"规格稿":"代码改动"}),e.contentTruncated&&t.jsx("div",{className:"mb-2 text-xs text-accent",children:"内容较大,展示的是截断后的片段。"}),e.content?e.phase==="spec"?t.jsx("pre",{className:"card whitespace-pre-wrap break-words p-4 text-sm text-og-800",children:e.content}):t.jsx(xi,{content:e.content,diffstat:e.diffstat}):t.jsx("div",{className:"text-sm text-og-400",children:"无内容"})]}),t.jsxs("section",{id:"review",children:[t.jsx("h2",{className:"mb-2 text-sm font-semibold text-og-800",children:"QA 评审"}),e.findings===void 0?t.jsx("div",{className:"text-sm text-og-400",children:"评审尚未提交。"}):s.length===0?t.jsx("div",{className:"text-sm text-og-400",children:"本轮无 findings。"}):t.jsx("div",{className:"space-y-2",children:s.map(l=>t.jsxs("div",{className:"card p-3 text-sm",children:[t.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[t.jsx("span",{className:"font-mono text-og-400",children:l.id}),t.jsx("span",{className:pi[l.severity],children:l.severity}),us(l)&&t.jsx("span",{className:"min-w-0 break-all font-mono text-xs text-og-500",children:us(l)})]}),t.jsx("div",{className:"whitespace-pre-wrap break-words text-og-800",children:l.message})]},l.id))})]}),n.length>0&&t.jsxs("section",{id:"response",children:[t.jsx("h2",{className:"mb-2 text-sm font-semibold text-og-800",children:"Dev 反馈"}),t.jsx("div",{className:"space-y-2",children:n.map(l=>{const u=i.get(l.findingId);return t.jsxs("div",{className:"card p-3 text-sm",children:[t.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[t.jsx("span",{className:"font-mono text-og-400",children:l.findingId}),t.jsx("span",{className:gi[l.action],children:l.action}),l.commitSha&&t.jsx("span",{className:"font-mono text-xs text-og-500",children:l.commitSha.slice(0,9)})]}),u&&t.jsxs("div",{className:"mb-1 break-words text-xs text-og-500",children:["↳ ",u.message]}),t.jsx("div",{className:"whitespace-pre-wrap break-words text-og-800",children:l.rationale})]},l.findingId)})})]})]})}const ji={approve:"approve","request-changes":"request-changes",comment:"comment"},wi={"server-mode":"该 task 为 server 评审模式,代码评审记录见任务详情的「评审记录」。","no-pr":"该 task 还没有 PR,暂无代码评审记录。","not-github":"该 task 的仓库不是 GitHub 仓库,无法拉取 PR 评审记录。"};function yi(e){return e==="server-mode"||e==="no-pr"||e==="not-github"?e:void 0}function yt(e){if(!e)return"";const s=e.match(/^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2})/);return s?`${s[1]} ${s[2]}`:e}function Ni(){const{taskId:e=""}=He(),s=pe(),{data:n}=Pt(e),i=n?qs(n):void 0,{data:r,loaded:o,error:l}=Ws(e,i),u=(r==null?void 0:r.prNumber)??(n==null?void 0:n.prNumber),m=(r==null?void 0:r.prUrl)??(n==null?void 0:n.prUrl),h=r?Hs(r.items):[];return t.jsxs("div",{className:"mx-auto w-full max-w-5xl",children:[t.jsx("button",{type:"button",onClick:()=>s(-1),className:"btn-ghost mb-3",children:"← 返回"}),t.jsxs("div",{className:"mb-1 flex flex-wrap items-baseline gap-2",children:[t.jsx("span",{className:"font-mono text-og-400",children:e}),t.jsx("span",{className:"text-sm font-semibold text-og-1000",children:(n==null?void 0:n.title)??""})]}),t.jsxs("div",{className:"mb-4 flex flex-wrap items-center gap-2 text-xs text-og-500",children:[t.jsx("span",{className:"pill",children:"代码评审"}),m&&u!==void 0&&t.jsxs("a",{href:m,target:"_blank",rel:"noopener noreferrer",className:"text-accent hover:text-accent-hover",children:["查看 PR #",u]})]}),!o&&t.jsx("div",{className:"text-sm text-og-500",children:"加载中…"}),o&&l&&t.jsxs("div",{className:"text-sm text-accent",children:["加载评审记录失败:",l]}),o&&!l&&r&&!r.available&&t.jsx("div",{className:"text-sm text-og-500",children:wi[yi(r.reason)??"no-pr"]}),o&&!l&&(r==null?void 0:r.available)&&(r.items.length===0?r.error?t.jsxs("div",{className:"text-sm text-accent",children:["评审记录拉取失败:",r.error]}):t.jsx("div",{className:"text-sm text-og-400",children:"评审尚未开始"}):t.jsxs(t.Fragment,{children:[r.error&&t.jsxs("div",{className:"mb-3 text-xs text-accent",children:["部分评审记录拉取失败:",r.error,"(仅展示已获取的部分)"]}),t.jsx("div",{className:"space-y-5",children:h.map((v,d)=>t.jsx(Si,{round:v,index:d},Us(v,String(d))))})]}))]})}function Si({round:e,index:s}){const n=e.review?`第 ${s+1} 轮`:"进行中";return t.jsxs("div",{children:[t.jsx("div",{className:"mb-1.5 text-xs font-medium text-og-700",children:n}),t.jsxs("div",{className:"space-y-2",children:[e.items.map((i,r)=>t.jsx(ki,{item:i},st(i,`${s}-${r}`))),e.review&&t.jsx(Ei,{item:e.review})]})]})}function ki({item:e}){if(e.kind==="commit")return t.jsxs("div",{className:"card p-3 text-sm",children:[t.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[t.jsx("span",{className:"pill shrink-0",children:"提交"}),e.commitSha&&t.jsx("span",{className:"font-mono text-xs text-og-500",children:e.commitSha.slice(0,9)}),e.author&&t.jsx("span",{className:"text-xs text-og-400",children:e.author}),e.createdAt&&t.jsx("span",{className:"text-xs text-og-400",children:yt(e.createdAt)})]}),e.body&&t.jsx("div",{className:"whitespace-pre-wrap break-words text-og-800",children:e.body})]});const s=e.kind==="review-comment";return t.jsxs("div",{className:"card p-3 text-sm",children:[t.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[t.jsx("span",{className:"pill shrink-0",children:s?"行内评论":"评论"}),e.author&&t.jsx("span",{className:"font-medium text-og-700",children:e.author}),s&&e.path&&t.jsx("span",{className:"min-w-0 break-all font-mono text-xs text-og-500",children:e.line!==void 0?`${e.path}:${e.line}`:e.path}),e.inReplyTo&&t.jsx("span",{className:"text-xs text-og-400",children:"↩ 回复"}),e.createdAt&&t.jsx("span",{className:"text-xs text-og-400",children:yt(e.createdAt)})]}),t.jsx(zs,{item:e})]})}function Ei({item:e}){const s=e.verdict??"comment";return t.jsxs("div",{className:"card p-3 text-sm",children:[t.jsxs("div",{className:"mb-1 flex flex-wrap items-center gap-2",children:[t.jsx("span",{className:"shrink-0 min-w-[1.75rem] text-xs font-semibold tracking-wide text-og-600",children:"QA"}),t.jsx("span",{className:Bs[s],children:ji[s]}),e.author&&t.jsx("span",{className:"text-xs text-og-400",children:e.author}),e.commitSha&&t.jsx("span",{className:"font-mono text-xs text-og-500",children:e.commitSha.slice(0,9)}),e.createdAt&&t.jsx("span",{className:"text-xs text-og-400",children:yt(e.createdAt)})]}),t.jsx(zs,{item:e,placeholder:"(无评审正文)"})]})}function zs({item:e,placeholder:s}){return t.jsxs(t.Fragment,{children:[e.body?t.jsx("div",{className:"whitespace-pre-wrap break-words text-og-800",children:e.body}):s?t.jsx("div",{className:"text-og-400",children:s}):null,e.bodyTruncated&&t.jsx("div",{className:"mt-1 text-xs text-accent",children:"内容较大,已截断。"})]})}function Ri(){const[e,s]=a.useState(!1);return t.jsx("button",{type:"button",onClick:()=>s(n=>!n),"aria-label":e?"切换为 Logo 图标":"切换为 Logo 文字",className:"flex h-7 min-w-[60px] shrink-0 items-center justify-center font-display text-sm font-semibold tracking-tight text-og-1000",children:e?t.jsx("span",{className:"inline-flex h-6 items-center leading-none",children:"baxian"}):t.jsx("img",{src:"/baxian-logo.png",alt:"baxian",width:20,height:24,className:"block h-6 w-auto"})})}function Ci(){const{phase:e,count:s,error:n,triggerRestart:i}=rt();return e==="idle"?null:e==="failed"?t.jsxs("div",{className:"flex items-center justify-between border-b border-accent/25 bg-accent-soft px-4 py-2",children:[t.jsxs("div",{className:"text-sm text-accent",children:["重启失败:",n]}),t.jsx("button",{onClick:()=>{i()},className:"btn-ghost",children:"重试"})]}):e==="restarting"?t.jsx("div",{className:"border-b border-accent-soft bg-accent-soft/40 px-4 py-2 text-sm text-accent",children:"重启中…"}):t.jsxs("div",{className:"flex items-center justify-between border-b border-accent/25 bg-accent-soft/60 px-4 py-2",children:[t.jsxs("div",{className:"text-sm text-accent",children:["有 ",s," 项配置变更待重启 baxian server 才生效"]}),t.jsx("button",{onClick:()=>{i()},className:"btn-primary",children:"现在重启"})]})}const Ai=new Set(["done","merged"]);function gt(e,s){const n=e.trim().replace(/\s+/g," ");return n.length>s?`${n.slice(0,s-1)}…`:n}function $i(e,s){return e?e.repo?`${e.id} · ${e.repo}`:e.id:s}function Ti(e){return e.title?`${e.id} · ${e.title}`:e.id}function Ii(e){return Ai.has(e)}function Pi(e,s,n){const i=Lt();if(!(!i||i.permission!=="granted"))try{const r=new i(`任务完成:${gt(e.title||e.id,80)}`,{body:[`项目:${gt(s,120)}`,`任务:${gt(Ti(e),120)}`,`状态:${Ie(e.status)}`].join(`
9
9
  `),icon:"/baxian-logo.png",tag:`baxian-task-${e.id}`});r.onclick=()=>{window.focus(),n(),r.close()}}catch(r){console.warn("[task-notifications] failed to show notification:",r)}}function Di(e,s,n){const i=a.useRef(new Map),r=a.useRef(new Set),o=a.useRef(new Map),l=a.useRef(new Set),u=a.useRef(new Set),m=a.useRef(new Map),h=a.useRef(s),v=a.useRef(new Map),d=a.useMemo(()=>n?(e??[]).map(f=>f.id).sort().join("\0"):"",[n,e]);a.useEffect(()=>{h.current=s},[s]),a.useEffect(()=>{v.current=new Map((e??[]).map(f=>[f.id,$i(f,f.id)]))},[e]),a.useEffect(()=>{const f=j=>{m.current.set(j,(m.current.get(j)??0)+1)};if(d===""){for(const j of u.current)f(j);u.current=new Set,i.current.clear(),o.current.clear(),l.current.clear();return}const p=d.split("\0"),x=new Set(p);for(const j of u.current)x.has(j)||f(j);u.current=x;for(const j of i.current.keys())x.has(j)||i.current.delete(j);for(const j of o.current.keys())x.has(j)||o.current.delete(j);const N=p.map(j=>it().subscribe(`project-tasks:${j}`,k=>{const R=i.current.get(j),E=new Map(k.map(y=>[y.id,y]));i.current.set(j,E);const b=o.current.get(j)??new Set;if(o.current.set(j,b),!R){for(const y of E.keys())b.delete(y);return}for(const[y]of R)E.has(y)||r.current.has(y)||b.add(y);for(const y of[...b]){if(E.has(y)){b.delete(y);continue}const w=m.current.get(j)??0,_=`${j}:${w}:${y}`;l.current.has(_)||(l.current.add(_),I.tasks.get(y).then(L=>{if((m.current.get(j)??0)!==w)return;if(!L||L.projectId!==j||!Ii(L.status)){b.delete(y);return}b.delete(y),r.current.add(L.id);const T=v.current.get(j)??j;Pi(L,T,()=>h.current(L))}).catch(L=>{console.warn(`[task-notifications] failed to confirm completed task ${y}:`,L)}).finally(()=>{l.current.delete(_)}))}},k=>{console.warn(`[task-notifications] project task stream failed for ${j}:`,k)}));return()=>{for(const j of N)j()}},[d])}function Li(){const e=ms(),s=pe(),{projects:n}=Ue(),{enabled:i}=Ls(),r=!e.pathname.startsWith("/terminal/");return Di(n,o=>s(Ce(o.projectId,o.id)),i),t.jsxs("div",{className:"flex h-dvh flex-col bg-page",children:[t.jsxs("nav",{className:"flex h-12 flex-none items-center border-b border-hairline bg-surface px-3 sm:px-6",children:[t.jsxs(Be,{to:"/",className:"flex shrink-0 items-center gap-2 font-display text-sm font-semibold tracking-tight text-og-1000",children:[t.jsx("span",{"aria-hidden":!0,className:"block h-2.5 w-2.5 rounded-full bg-accent"}),"baxian"]}),t.jsx("div",{id:$s,className:"ml-auto flex min-w-0 items-center justify-end gap-2"})]}),t.jsx(Ci,{}),t.jsxs("main",{className:"flex min-h-0 flex-1 flex-col overflow-y-auto px-3 py-6 sm:px-6",children:[t.jsxs(tn,{children:[t.jsx($e,{path:"/",element:t.jsx(Tr,{})}),t.jsx($e,{path:"/project/:id",element:t.jsx(qr,{})}),t.jsx($e,{path:"/project/:id/task/:taskId",element:t.jsx(li,{})}),t.jsx($e,{path:"/terminal/:agentId",element:t.jsx(ui,{})}),t.jsx($e,{path:"/tasks/:taskId/rounds/:phase/:round",element:t.jsx(bi,{})}),t.jsx($e,{path:"/tasks/:taskId/github-review",element:t.jsx(Ni,{})})]}),r&&t.jsx("footer",{className:"mt-auto flex justify-center pb-4 pt-24",children:t.jsx(Ri,{})})]})]})}function Mi(){return t.jsx(en,{children:t.jsx($r,{children:t.jsx(Li,{})})})}function _i({children:e}){const[s,n]=a.useState({kind:"probing"}),i=a.useRef(s);a.useEffect(()=>{i.current=s},[s]);const r=a.useCallback(async()=>{n({kind:"probing"});try{await I.config.get(),n({kind:"authorized"})}catch(o){if(o instanceof Pe&&o.status===401){n({kind:"unauthorized"});return}const l=o instanceof Error?o.message:"无法连接服务器";n({kind:"error",message:l})}},[]);return a.useEffect(()=>{r()},[r]),a.useEffect(()=>{const o=()=>{i.current.kind!=="probing"&&n({kind:"unauthorized",message:"登录已失效,请重新输入令牌"})};return window.addEventListener(Je,o),()=>window.removeEventListener(Je,o)},[]),s.kind==="authorized"?t.jsx(t.Fragment,{children:e}):s.kind==="error"?t.jsxs(Nt,{title:"无法连接服务器",children:[t.jsx("p",{className:"text-sm text-og-600",children:s.message}),t.jsx("button",{type:"button",onClick:()=>{r()},className:"btn-primary mt-4 w-full",children:"重试"})]}):s.kind==="probing"?t.jsx(Nt,{title:"加载中",children:t.jsx("p",{className:"text-sm text-og-500",children:"正在检查登录状态…"})}):t.jsx(Oi,{message:s.message,onSubmit:async o=>{an(o);try{await I.config.get(),n({kind:"authorized"})}catch(l){if(on(),l instanceof Pe&&l.status===401){n({kind:"unauthorized",message:"令牌无效,请重试"});return}const u=l instanceof Error?l.message:"登录失败";n({kind:"error",message:u})}}})}function Nt({title:e,children:s}){return t.jsx("div",{className:"flex min-h-dvh items-center justify-center bg-page px-4",children:t.jsxs("div",{className:"w-full max-w-sm rounded-lg border border-hairline bg-surface px-6 py-6",children:[t.jsx("h1",{className:"mb-3 font-display text-sm font-semibold tracking-tight text-og-1000",children:e}),s]})})}function Oi({message:e,onSubmit:s}){const[n,i]=a.useState(""),[r,o]=a.useState(!1),[l,u]=a.useState(void 0),m=async v=>{v.preventDefault();const d=n.trim();if(!d){u("请输入访问令牌");return}u(void 0),o(!0);try{await s(d)}finally{o(!1)}},h=l??e;return t.jsxs(Nt,{title:"登录 baxian",children:[t.jsx("p",{className:"mb-4 text-sm text-og-600",children:"服务器开启了访问鉴权,请输入访问令牌继续。"}),t.jsxs("form",{onSubmit:v=>{m(v)},children:[t.jsx("label",{className:ee,htmlFor:"baxian-token",children:"访问令牌"}),t.jsx("input",{id:"baxian-token",type:"password",autoComplete:"current-password",autoFocus:!0,value:n,onChange:v=>i(v.target.value),className:`${ae} font-mono`,placeholder:"请输入服务器配置的 token",disabled:r}),h&&t.jsx("p",{role:"alert",className:"mt-2 text-xs text-accent",children:h}),t.jsx("button",{type:"submit",disabled:r,className:"btn-primary mt-4 w-full",children:r?"登录中…":"登录"})]})]})}Ys.createRoot(document.getElementById("root")).render(t.jsx(a.StrictMode,{children:t.jsx(Nn,{children:t.jsx(pn,{children:t.jsx(bn,{children:t.jsx(_i,{children:t.jsx(Mi,{})})})})})}));
@@ -6,12 +6,12 @@
6
6
  <link rel="icon" type="image/png" href="/baxian-logo.png" />
7
7
  <link rel="apple-touch-icon" href="/baxian-logo.png" />
8
8
  <title>baxian</title>
9
- <script type="module" crossorigin src="/assets/index-C4dkSuQo.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-Dz_YaWeU.js"></script>
10
10
  <link rel="modulepreload" crossorigin href="/assets/react-BFCkCmbU.js">
11
11
  <link rel="modulepreload" crossorigin href="/assets/xterm-D5X2JljJ.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/router-BgSDZqI0.js">
13
13
  <link rel="stylesheet" crossorigin href="/assets/xterm-CFbL2ovg.css">
14
- <link rel="stylesheet" crossorigin href="/assets/index-DGbCcR1h.css">
14
+ <link rel="stylesheet" crossorigin href="/assets/index-CRXN_oyU.css">
15
15
  </head>
16
16
  <body>
17
17
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baxian",
3
- "version": "1.2.43",
3
+ "version": "1.2.44",
4
4
  "description": "AI agent orchestration",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -1 +0,0 @@
1
- @font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-regular.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-italic.woff2) format("woff2");font-weight:400;font-style:italic;font-display:swap}@font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-bold.woff2) format("woff2");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:iA Writer Quattro S;src:url(/fonts/ia-writer-quattro-s-bolditalic.woff2) format("woff2");font-weight:700;font-style:italic;font-display:swap}@font-face{font-family:Lilex;src:url(/fonts/lilex-variable.woff2) format("woff2-variations");font-weight:200 700;font-style:normal;font-display:swap}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:iA Writer Quattro S,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}body{--tw-bg-opacity: 1;background-color:rgb(250 250 250 / var(--tw-bg-opacity, 1));font-family:iA Writer Quattro S,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1));font-size:14px;line-height:1.55;-webkit-font-smoothing:antialiased;text-rendering:geometricprecision;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%}.\!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:4px;--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1));padding:.375rem .75rem;font-size:14px;line-height:1.55;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:4px;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:14px;line-height:1.55;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:4px;background-color:transparent;padding:.375rem .75rem;font-size:14px;line-height:1.55;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:12px;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(227 228 231 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(71 76 85 / var(--tw-text-opacity, 1))}.pill-live:before{--tw-bg-opacity: 1;background-color:rgb(13 13 15 / var(--tw-bg-opacity, 1))}.pill-warn{--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-warn:before{--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1))}.pill-review{--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(98 105 118 / var(--tw-text-opacity, 1))}.pill-review:before{--tw-bg-opacity: 1;background-color:rgb(135 142 155 / var(--tw-bg-opacity, 1))}.pill-idle{--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(109 116 132 / var(--tw-text-opacity, 1))}.pill-idle:before{--tw-bg-opacity: 1;background-color:rgb(192 195 202 / var(--tw-bg-opacity, 1))}.card{border-radius:6px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(232 233 236 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.card:hover{--tw-border-opacity: 1;border-color:rgb(206 209 214 / var(--tw-border-opacity, 1))}.status-dot{display:inline-block;height:.725rem;width:.725rem;flex-shrink:0;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(227 228 231 / var(--tw-bg-opacity, 1))}.status-dot--warn,.status-dot--danger,.status-dot--info{--tw-bg-opacity: 1;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1));animation:breathe 1.8s ease-in-out 2}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.inset-x-4{left:1rem;right:1rem}.-top-4{top:-1rem}.bottom-full{bottom:100%}.right-0{right:0}.right-7{right:1.75rem}.top-4{top:1rem}.top-full{top:100%}.z-10{z-index:10}.z-50{z-index:50}.z-\[60\]{z-index:60}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.-mr-1{margin-right:-.25rem}.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-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-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-auto{margin-top:auto}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-12{height:3rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-3\.5{height:.875rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-80{height:20rem}.h-dvh{height:100dvh}.h-full{height:100%}.max-h-28{max-height:7rem}.max-h-\[90dvh\]{max-height:90dvh}.min-h-0{min-height:0px}.min-h-dvh{min-height:100dvh}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-3\.5{width:.875rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-auto{width:auto}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[1\.75rem\]{min-width:1.75rem}.min-w-\[140px\]{min-width:140px}.min-w-\[180px\]{min-width:180px}.min-w-\[60px\]{min-width:60px}.max-w-2xl{max-width:42rem}.max-w-5xl{max-width:64rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xs{max-width:20rem}.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))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[1fr_auto_1fr\]{grid-template-columns:1fr auto 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-6{gap:1.5rem}.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}.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-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * 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))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * 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))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.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{white-space:pre}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:4px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:6px}.rounded-md{border-radius:4px}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-accent{--tw-border-opacity: 1;border-color:rgb(19 72 220 / var(--tw-border-opacity, 1))}.border-accent-soft{--tw-border-opacity: 1;border-color:rgb(234 240 255 / var(--tw-border-opacity, 1))}.border-accent\/25{border-color:#1348dc40}.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-accent{--tw-bg-opacity: 1;background-color:rgb(19 72 220 / var(--tw-bg-opacity, 1))}.bg-accent-soft{--tw-bg-opacity: 1;background-color:rgb(234 240 255 / var(--tw-bg-opacity, 1))}.bg-accent-soft\/30{background-color:#eaf0ff4d}.bg-accent-soft\/40{background-color:#eaf0ff66}.bg-accent-soft\/60{background-color:#eaf0ff99}.bg-diff-add{--tw-bg-opacity: 1;background-color:rgb(230 244 236 / var(--tw-bg-opacity, 1))}.bg-diff-del{--tw-bg-opacity: 1;background-color:rgb(253 236 234 / var(--tw-bg-opacity, 1))}.bg-og-1000{--tw-bg-opacity: 1;background-color:rgb(13 13 15 / var(--tw-bg-opacity, 1))}.bg-og-1000\/45{background-color:#0d0d0f73}.bg-og-25{--tw-bg-opacity: 1;background-color:rgb(241 242 244 / var(--tw-bg-opacity, 1))}.bg-og-300{--tw-bg-opacity: 1;background-color:rgb(171 175 184 / var(--tw-bg-opacity, 1))}.bg-og-400{--tw-bg-opacity: 1;background-color:rgb(135 142 155 / var(--tw-bg-opacity, 1))}.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-surface{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-term{--tw-bg-opacity: 1;background-color:rgb(253 253 253 / var(--tw-bg-opacity, 1))}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.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-5{padding-left:1.25rem;padding-right:1.25rem}.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-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pr-28{padding-right:7rem}.pt-1{padding-top:.25rem}.pt-24{padding-top:6rem}.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-sm{font-size:14px;line-height:1.55}.text-xs{font-size:12px;line-height:1.4}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.normal-case{text-transform:none}.leading-\[1\.5\]{line-height:1.5}.leading-none{line-height:1}.tracking-\[0\.05em\]{letter-spacing:.05em}.tracking-\[0\.06em\]{letter-spacing:.06em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-accent{--tw-text-opacity: 1;color:rgb(19 72 220 / var(--tw-text-opacity, 1))}.text-current{color:currentColor}.text-diff-add-ink{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-diff-del-ink{--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-300{--tw-text-opacity: 1;color:rgb(171 175 184 / 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))}.underline{text-decoration-line:underline}.accent-accent{accent-color:#1348dc}.opacity-50{opacity:.5}.opacity-80{opacity:.8}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px 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-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)}.ring-2{--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)}.ring-accent{--tw-ring-opacity: 1;--tw-ring-color: rgb(19 72 220 / var(--tw-ring-opacity, 1))}.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}.scrollbar-none{-ms-overflow-style:none;scrollbar-width:none}.scrollbar-none::-webkit-scrollbar{display:none}.\[max-height\:70vh\]{max-height:70vh}@media(pointer:coarse){input:not([type=checkbox]):not([type=radio]):not([type=button]):not([type=submit]):not([type=file]),select,textarea{font-size:16px!important}}@keyframes breathe{0%,to{opacity:1}50%{opacity:.35}}.placeholder\:text-og-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.placeholder\:text-og-400::placeholder{--tw-text-opacity: 1;color:rgb(135 142 155 / var(--tw-text-opacity, 1))}.hover\: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-accent-hover:hover{--tw-text-opacity: 1;color:rgb(15 59 184 / var(--tw-text-opacity, 1))}.hover\:text-og-1000:hover{--tw-text-opacity: 1;color:rgb(13 13 15 / 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\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:opacity-80:hover{opacity:.8}.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))}.active\:bg-og-200:active{--tw-bg-opacity: 1;background-color:rgb(192 195 202 / var(--tw-bg-opacity, 1))}.disabled\:cursor-default:disabled{cursor:default}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:640px){.sm\:inline-block{display:inline-block}.sm\:inline{display:inline}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media(min-width:1024px){.lg\:w-\[340px\]{width:340px}.lg\:shrink-0{flex-shrink:0}.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))}.lg\:flex-row{flex-direction:row}.lg\:items-start{align-items:flex-start}}@media(min-width:1280px){.xl\:w-\[380px\]{width:380px}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}