baxian 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/agent/bootstrap-poller.d.ts +6 -0
- package/dist/agent/bootstrap-poller.d.ts.map +1 -1
- package/dist/agent/bootstrap-poller.js +30 -0
- package/dist/agent/bootstrap-poller.js.map +1 -1
- package/dist/agent/bootstrap.d.ts +7 -0
- package/dist/agent/bootstrap.d.ts.map +1 -1
- package/dist/agent/bootstrap.js +104 -5
- package/dist/agent/bootstrap.js.map +1 -1
- package/dist/agent/manager.js +5 -5
- package/dist/agent/manager.js.map +1 -1
- package/dist/agent/marker-protocol.d.ts +10 -4
- package/dist/agent/marker-protocol.d.ts.map +1 -1
- package/dist/agent/marker-protocol.js +42 -34
- package/dist/agent/marker-protocol.js.map +1 -1
- package/dist/agent/post-approve-marker-watcher.d.ts.map +1 -1
- package/dist/agent/post-approve-marker-watcher.js +3 -7
- package/dist/agent/post-approve-marker-watcher.js.map +1 -1
- package/dist/agent/prompt.d.ts +3 -1
- package/dist/agent/prompt.d.ts.map +1 -1
- package/dist/agent/prompt.js +33 -51
- package/dist/agent/prompt.js.map +1 -1
- package/dist/agent/spec-review-marker-watcher.d.ts +3 -2
- package/dist/agent/spec-review-marker-watcher.d.ts.map +1 -1
- package/dist/agent/spec-review-marker-watcher.js +5 -7
- package/dist/agent/spec-review-marker-watcher.js.map +1 -1
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +16 -0
- package/dist/api/config.js.map +1 -1
- package/dist/api/projects.d.ts.map +1 -1
- package/dist/api/projects.js +30 -0
- package/dist/api/projects.js.map +1 -1
- package/dist/app.d.ts +2 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js.map +1 -1
- package/dist/event/handlers.js +2 -2
- package/dist/event/handlers.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -9
- package/dist/index.js.map +1 -1
- package/dist/shared/types.d.ts +1 -8
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/state/error-record-store.d.ts +12 -0
- package/dist/state/error-record-store.d.ts.map +1 -1
- package/dist/state/error-record-store.js +130 -1
- package/dist/state/error-record-store.js.map +1 -1
- package/dist/state/snapshot.d.ts +8 -2
- package/dist/state/snapshot.d.ts.map +1 -1
- package/dist/state/snapshot.js +45 -4
- package/dist/state/snapshot.js.map +1 -1
- package/dist/web/assets/index-53CBbz4w.js +4 -0
- package/dist/web/assets/{index-BztIjbNF.css → index-B9D6BV08.css} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-eKI0WBRQ.js +0 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.fixed{position:fixed}.inset-0{top:0;right:0;bottom:0;left:0}.right-4{right:1rem}.top-4{top:1rem}.z-50{z-index:50}.z-\[60\]{z-index:60}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-2{height:.5rem}.h-8{height:2rem}.h-80{height:20rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-28{max-height:7rem}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0px}.min-h-screen{min-height:100vh}.w-2{width:.5rem}.w-80{width:20rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-none{flex:none}.shrink-0{flex-shrink:0}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-1{row-gap:.25rem}.gap-y-2{row-gap:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.self-center{align-self:center}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-500{--tw-border-opacity: 1;border-color:rgb(245 158 11 / var(--tw-border-opacity, 1))}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-blue-300{--tw-border-opacity: 1;border-color:rgb(147 197 253 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-green-300{--tw-border-opacity: 1;border-color:rgb(134 239 172 / var(--tw-border-opacity, 1))}.border-purple-300{--tw-border-opacity: 1;border-color:rgb(216 180 254 / var(--tw-border-opacity, 1))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-red-300{--tw-border-opacity: 1;border-color:rgb(252 165 165 / var(--tw-border-opacity, 1))}.border-red-900\/60{border-color:#7f1d1d99}.border-sky-200{--tw-border-opacity: 1;border-color:rgb(186 230 253 / var(--tw-border-opacity, 1))}.border-zinc-800{--tw-border-opacity: 1;border-color:rgb(39 39 42 / var(--tw-border-opacity, 1))}.bg-\[\#e1e2e7\]{--tw-bg-opacity: 1;background-color:rgb(225 226 231 / var(--tw-bg-opacity, 1))}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-200{--tw-bg-opacity: 1;background-color:rgb(253 230 138 / var(--tw-bg-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.bg-black\/40{background-color:#0006}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-200{--tw-bg-opacity: 1;background-color:rgb(191 219 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-emerald-100{--tw-bg-opacity: 1;background-color:rgb(209 250 229 / var(--tw-bg-opacity, 1))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-400{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-300{--tw-bg-opacity: 1;background-color:rgb(134 239 172 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-indigo-100{--tw-bg-opacity: 1;background-color:rgb(224 231 255 / var(--tw-bg-opacity, 1))}.bg-orange-100{--tw-bg-opacity: 1;background-color:rgb(255 237 213 / var(--tw-bg-opacity, 1))}.bg-orange-200{--tw-bg-opacity: 1;background-color:rgb(254 215 170 / var(--tw-bg-opacity, 1))}.bg-purple-200{--tw-bg-opacity: 1;background-color:rgb(233 213 255 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-200{--tw-bg-opacity: 1;background-color:rgb(254 202 202 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-950\/40{background-color:#450a0a66}.bg-sky-100{--tw-bg-opacity: 1;background-color:rgb(224 242 254 / var(--tw-bg-opacity, 1))}.bg-sky-50{--tw-bg-opacity: 1;background-color:rgb(240 249 255 / var(--tw-bg-opacity, 1))}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-zinc-900{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.p-3{padding:.75rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pr-4{padding-right:1rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.text-\[11px\]{font-size:11px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.italic{font-style:italic}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-current{color:currentColor}.text-emerald-800{--tw-text-opacity: 1;color:rgb(6 95 70 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-green-900{--tw-text-opacity: 1;color:rgb(20 83 45 / var(--tw-text-opacity, 1))}.text-indigo-700{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.text-indigo-800{--tw-text-opacity: 1;color:rgb(55 48 163 / var(--tw-text-opacity, 1))}.text-orange-800{--tw-text-opacity: 1;color:rgb(154 52 18 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-purple-800{--tw-text-opacity: 1;color:rgb(107 33 168 / var(--tw-text-opacity, 1))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-red-800{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.text-red-900{--tw-text-opacity: 1;color:rgb(127 29 29 / var(--tw-text-opacity, 1))}.text-sky-800{--tw-text-opacity: 1;color:rgb(7 89 133 / var(--tw-text-opacity, 1))}.text-sky-900{--tw-text-opacity: 1;color:rgb(12 74 110 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-zinc-200{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.opacity-50{opacity:.5}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.hover\:bg-amber-700:hover{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-50:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-green-100:hover{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.hover\:bg-purple-50:hover{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:text-black:hover{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-300:disabled{--tw-bg-opacity: 1;background-color:rgb(209 213 219 / var(--tw-bg-opacity, 1))}.disabled\:bg-gray-50:disabled{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.disabled\:no-underline:disabled{text-decoration-line:none}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media(min-width:640px){.sm\:table-cell{display:table-cell}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.sm\:p-6{padding:1.5rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-2xl{font-size:1.5rem;line-height:2rem}}@media(min-width:768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(min-width:1280px){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.fixed{position:fixed}.inset-0{top:0;right:0;bottom:0;left:0}.right-4{right:1rem}.top-4{top:1rem}.z-50{z-index:50}.z-\[60\]{z-index:60}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-auto{margin-left:auto}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-2{height:.5rem}.h-8{height:2rem}.h-80{height:20rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-28{max-height:7rem}.max-h-\[90vh\]{max-height:90vh}.min-h-0{min-height:0px}.min-h-screen{min-height:100vh}.w-2{width:.5rem}.w-80{width:20rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-none{flex:none}.shrink-0{flex-shrink:0}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-1{row-gap:.25rem}.gap-y-2{row-gap:.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.self-center{align-self:center}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l-4{border-left-width:4px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-500{--tw-border-opacity: 1;border-color:rgb(245 158 11 / var(--tw-border-opacity, 1))}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-blue-300{--tw-border-opacity: 1;border-color:rgb(147 197 253 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-green-300{--tw-border-opacity: 1;border-color:rgb(134 239 172 / var(--tw-border-opacity, 1))}.border-purple-300{--tw-border-opacity: 1;border-color:rgb(216 180 254 / var(--tw-border-opacity, 1))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-red-300{--tw-border-opacity: 1;border-color:rgb(252 165 165 / var(--tw-border-opacity, 1))}.border-red-900\/60{border-color:#7f1d1d99}.border-sky-200{--tw-border-opacity: 1;border-color:rgb(186 230 253 / var(--tw-border-opacity, 1))}.border-zinc-800{--tw-border-opacity: 1;border-color:rgb(39 39 42 / var(--tw-border-opacity, 1))}.bg-\[\#e1e2e7\]{--tw-bg-opacity: 1;background-color:rgb(225 226 231 / var(--tw-bg-opacity, 1))}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-200{--tw-bg-opacity: 1;background-color:rgb(253 230 138 / var(--tw-bg-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.bg-black\/40{background-color:#0006}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-200{--tw-bg-opacity: 1;background-color:rgb(191 219 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-emerald-100{--tw-bg-opacity: 1;background-color:rgb(209 250 229 / var(--tw-bg-opacity, 1))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-400{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-green-100{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.bg-green-300{--tw-bg-opacity: 1;background-color:rgb(134 239 172 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-indigo-100{--tw-bg-opacity: 1;background-color:rgb(224 231 255 / var(--tw-bg-opacity, 1))}.bg-orange-100{--tw-bg-opacity: 1;background-color:rgb(255 237 213 / var(--tw-bg-opacity, 1))}.bg-orange-200{--tw-bg-opacity: 1;background-color:rgb(254 215 170 / var(--tw-bg-opacity, 1))}.bg-purple-200{--tw-bg-opacity: 1;background-color:rgb(233 213 255 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-200{--tw-bg-opacity: 1;background-color:rgb(254 202 202 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-950\/40{background-color:#450a0a66}.bg-sky-100{--tw-bg-opacity: 1;background-color:rgb(224 242 254 / var(--tw-bg-opacity, 1))}.bg-sky-50{--tw-bg-opacity: 1;background-color:rgb(240 249 255 / var(--tw-bg-opacity, 1))}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-zinc-900{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.p-3{padding:.75rem}.p-4{padding:1rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pr-4{padding-right:1rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.text-\[11px\]{font-size:11px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.italic{font-style:italic}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-current{color:currentColor}.text-emerald-800{--tw-text-opacity: 1;color:rgb(6 95 70 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-800{--tw-text-opacity: 1;color:rgb(22 101 52 / var(--tw-text-opacity, 1))}.text-green-900{--tw-text-opacity: 1;color:rgb(20 83 45 / var(--tw-text-opacity, 1))}.text-indigo-700{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.text-indigo-800{--tw-text-opacity: 1;color:rgb(55 48 163 / var(--tw-text-opacity, 1))}.text-orange-800{--tw-text-opacity: 1;color:rgb(154 52 18 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-purple-800{--tw-text-opacity: 1;color:rgb(107 33 168 / var(--tw-text-opacity, 1))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-red-800{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.text-red-900{--tw-text-opacity: 1;color:rgb(127 29 29 / var(--tw-text-opacity, 1))}.text-sky-800{--tw-text-opacity: 1;color:rgb(7 89 133 / var(--tw-text-opacity, 1))}.text-sky-900{--tw-text-opacity: 1;color:rgb(12 74 110 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-zinc-200{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.opacity-50{opacity:.5}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.hover\:bg-amber-700:hover{--tw-bg-opacity: 1;background-color:rgb(180 83 9 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-50:hover{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-green-100:hover{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.hover\:bg-purple-50:hover{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.hover\:bg-red-100:hover{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:text-black:hover{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-blue-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-gray-300:disabled{--tw-bg-opacity: 1;background-color:rgb(209 213 219 / var(--tw-bg-opacity, 1))}.disabled\:bg-gray-50:disabled{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.disabled\:no-underline:disabled{text-decoration-line:none}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media(min-width:640px){.sm\:table-cell{display:table-cell}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.sm\:p-6{padding:1.5rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-2xl{font-size:1.5rem;line-height:2rem}}@media(min-width:768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:1024px){.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(min-width:1280px){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
package/dist/web/index.html
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>baxian</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-53CBbz4w.js"></script>
|
|
8
8
|
<link rel="modulepreload" crossorigin href="/assets/react-BG4Iuztk.js">
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/xterm-D5X2JljJ.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/router-B_Nv0oRz.js">
|
|
11
11
|
<link rel="stylesheet" crossorigin href="/assets/xterm-CFbL2ovg.css">
|
|
12
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
12
|
+
<link rel="stylesheet" crossorigin href="/assets/index-B9D6BV08.css">
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
var Je=Object.defineProperty;var Ve=(s,t,n)=>t in s?Je(s,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):s[t]=n;var _=(s,t,n)=>Ve(s,typeof t!="symbol"?t+"":t,n);import{r as a,j as e,c as Ke}from"./react-BG4Iuztk.js";import{x as Ye,a as Ze}from"./xterm-D5X2JljJ.js";import{L as ee,u as ve,a as Se,B as Xe,R as et,b as ae}from"./router-B_Nv0oRz.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const i of r)if(i.type==="childList")for(const c of i.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&o(c)}).observe(document,{childList:!0,subtree:!0});function n(r){const i={};return r.integrity&&(i.integrity=r.integrity),r.referrerPolicy&&(i.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?i.credentials="include":r.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(r){if(r.ep)return;r.ep=!0;const i=n(r);fetch(r.href,i)}})();const me="/api",ke="baxian.token",ye="baxian:unauthorized";function Ne(){try{return typeof localStorage<"u"?localStorage.getItem(ke):null}catch{return null}}function tt(s){try{localStorage.setItem(ke,s)}catch(t){console.error("Failed to save auth token to localStorage",t)}}function st(){try{localStorage.removeItem(ke)}catch(s){console.error("Failed to clear auth token from localStorage",s)}}function ie(s){const t=Ne();return{...s??{},...t?{Authorization:`Bearer ${t}`}:{}}}class de extends Error{constructor(t,n,o){super(n),this.status=t,this.details=o,this.name="ApiError"}}async function oe(s){const t=await s.text();let n=t||`HTTP ${s.status}`,o;try{const r=JSON.parse(t);typeof r.error=="string"&&(n=r.error),Array.isArray(r.details)&&(o=r.details)}catch{}throw s.status===401&&typeof window<"u"&&window.dispatchEvent(new CustomEvent(ye)),new de(s.status,n,o)}async function te(s){const t=await fetch(`${me}${s}`,{headers:ie()});return t.ok||await oe(t),t.json()}async function rt(){const s=await fetch("/health");return s.ok||await oe(s),s.json()}async function X(s,t,n){const o=t!==void 0,r=await fetch(`${me}${s}`,{method:"POST",headers:o?ie({"Content-Type":"application/json"}):ie(),body:o?JSON.stringify(t):void 0,signal:n==null?void 0:n.signal});return r.ok||await oe(r),r.json()}async function nt(s,t,n){const o=await fetch(`${me}${s}`,{method:"PATCH",headers:ie({"Content-Type":"application/json"}),body:t?JSON.stringify(t):void 0,signal:n==null?void 0:n.signal});if(o.ok||await oe(o),o.status===204)return;const r=await o.text();if(r)return JSON.parse(r)}async function Te(s){const t=await fetch(`${me}${s}`,{method:"DELETE",headers:ie()});if(t.ok||await oe(t),t.status===204)return;const n=await t.text();if(n)return JSON.parse(n)}const W=encodeURIComponent,O={agents:{list:()=>te("/agents"),get:s=>te(`/agents/${W(s)}`),stop:s=>Te(`/agents/${W(s)}/session`),probe:(s,t,n)=>X("/agents/probe",{mode:s,host:t},n)},tasks:{list:s=>te(`/tasks${s?`?projectId=${W(s)}`:""}`),get:s=>te(`/tasks/${W(s)}`),create:s=>X("/tasks",s),update:(s,t)=>nt(`/tasks/${W(s)}`,t),retry:s=>X(`/tasks/${W(s)}/retry`),review:s=>X(`/tasks/${W(s)}/review`)},projects:{list:()=>te("/projects"),get:s=>te(`/projects/${W(s)}`),create:s=>X("/projects",s),addAgent:(s,t)=>X(`/projects/${W(s)}/agents`,t),deleteAgent:(s,t)=>Te(`/projects/${W(s)}/agents/${W(t)}`),resumeAgent:(s,t)=>X(`/projects/${W(s)}/agents/${W(t)}/resume`)},config:{get:()=>te("/config")},health:{get:rt},server:{restart:()=>X("/restart")}},Fe=a.createContext(null),at={success:"bg-green-50 border-green-200 text-green-900",warn:"bg-amber-50 border-amber-200 text-amber-900",error:"bg-red-50 border-red-200 text-red-900"},it={success:"✅",warn:"⚠️",error:"❌"};let ot=1;function lt({children:s}){const[t,n]=a.useState([]),o=a.useCallback(i=>{n(c=>c.filter(m=>m.id!==i))},[]),r=a.useCallback(i=>{const c=ot++,m=i.durationMs??3e3;n(p=>[...p,{...i,id:c}]),setTimeout(()=>o(c),m)},[o]);return e.jsxs(Fe.Provider,{value:{show:r},children:[s,e.jsx("div",{className:"fixed top-4 right-4 z-[60] flex flex-col gap-2 pointer-events-none",children:t.map(i=>e.jsx("div",{className:`pointer-events-auto px-4 py-3 rounded shadow-lg border w-80 ${at[i.kind]}`,role:"status",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{"aria-hidden":!0,children:it[i.kind]}),e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"font-semibold",children:i.title}),i.body&&e.jsx("div",{className:"text-sm mt-1 whitespace-pre-line",children:i.body})]}),e.jsx("button",{type:"button",onClick:()=>o(i.id),className:"text-current opacity-50 hover:opacity-100","aria-label":"Dismiss",children:"✕"})]})},i.id))})]})}function le(){const s=a.useContext(Fe);if(!s)throw new Error("useToast must be inside <ToastProvider>");return s}const ue="baxian.pendingRestart",ct=500,dt=3e4,ze=a.createContext(null);function ut(){try{const s=localStorage.getItem(ue);if(!s)return{count:0,baselineStartedAt:null};const t=JSON.parse(s);return{count:typeof t.count=="number"?t.count:0,baselineStartedAt:typeof t.baselineStartedAt=="string"?t.baselineStartedAt:null}}catch{return{count:0,baselineStartedAt:null}}}function ht(s){try{s.count<=0?localStorage.removeItem(ue):localStorage.setItem(ue,JSON.stringify(s))}catch{}}function mt({children:s}){const t=ut(),[n,o]=a.useState(t.count),[r,i]=a.useState(t.baselineStartedAt),[c,m]=a.useState(t.count>0?"pending":"idle"),[p,b]=a.useState(),u=a.useRef(t.count),h=a.useRef(t.count>0?"pending":"idle"),f=a.useRef(0),x=a.useCallback(v=>{u.current=v,o(v)},[]),d=a.useCallback(v=>{o(A=>{const g=v(A);return u.current=g,g})},[]),j=a.useCallback(v=>{h.current=v,m(v)},[]);a.useEffect(()=>{ht({count:n,baselineStartedAt:r})},[n,r]),a.useEffect(()=>{let v=!1;(async()=>{try{const g=await O.health.get();if(v)return;i(S=>S!==null&&g.startedAt!==S?(x(0),j("idle"),null):S)}catch{}})();const A=g=>{if(g.key===ue){if(g.newValue===null){if(h.current==="restarting"&&f.current>0){x(f.current),i(null);return}x(0),i(null),h.current!=="restarting"&&j("idle");return}try{const S=JSON.parse(g.newValue);typeof S.count=="number"&&(h.current==="restarting"&&S.count>u.current&&(f.current+=S.count-u.current),x(S.count),h.current!=="restarting"&&j(S.count>0?"pending":"idle")),typeof S.baselineStartedAt=="string"?i(S.baselineStartedAt):S.baselineStartedAt===null&&i(null)}catch{}}};return window.addEventListener("storage",A),()=>{v=!0,window.removeEventListener("storage",A)}},[x,j]);const l=a.useRef(!1),T=a.useCallback(()=>{d(v=>v+1),h.current==="restarting"?f.current+=1:j("pending"),i(v=>(v!==null||l.current||(l.current=!0,(async()=>{try{const A=await O.health.get();i(g=>g??A.startedAt)}catch{}finally{l.current=!1}})()),v))},[j,d]),$=a.useCallback(async()=>{f.current=0,b(void 0),j("restarting");let v;try{v=(await O.health.get()).startedAt}catch(g){j("failed"),b(`获取重启前 startedAt 失败: ${g instanceof Error?g.message:String(g)}`);return}try{await O.server.restart()}catch(g){if(!(g instanceof de&&g.status===409)){j("failed"),b(`触发重启失败: ${g instanceof Error?g.message:String(g)}`);return}}const A=Date.now();for(;Date.now()-A<dt;){await new Promise(g=>setTimeout(g,ct));try{const g=await O.health.get();if(g.startedAt!==v){const S=f.current;f.current=0,i(S>0?g.startedAt:null),x(S),j(S>0?"pending":"idle");return}}catch{}}j("failed"),b("重启超时(30s 未恢复)。请检查日志或手动 baxian start -c <path>")},[x,j]);return e.jsx(ze.Provider,{value:{phase:c,count:n,error:p,flagDirty:T,triggerRestart:$},children:s})}function xe(){const s=a.useContext(ze);if(!s)throw new Error("usePendingRestart must be used inside PendingRestartProvider");return s}const xt=[500,1e3,2e3,4e3,8e3,15e3,3e4];class Me{constructor(t){_(this,"attempts",0);_(this,"timer",null);_(this,"delaysMs");this.opts=t,this.delaysMs=t.delaysMs??xt}schedule(){if(this.timer||!this.shouldReconnect())return;const t=this.delaysMs[Math.min(this.attempts,this.delaysMs.length-1)];this.attempts+=1,this.timer=setTimeout(()=>{this.timer=null,this.shouldReconnect()&&this.opts.reconnect()},t)}cancel(){this.timer&&(clearTimeout(this.timer),this.timer=null)}reset(){this.attempts=0}shouldReconnect(){return this.opts.shouldReconnect?this.opts.shouldReconnect():!0}}let Ie=0;function ft(){Ie++;const s=Math.random().toString(36).slice(2,8);return`sub-${Date.now().toString(36)}-${Ie}-${s}`}function bt(s){return Array.from(new TextEncoder().encode(s)).map(t=>t.toString(16).padStart(2,"0")).join("")}function pt(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/stream`}const gt=(s,t)=>t&&t.length>0?new WebSocket(s,t):new WebSocket(s);class yt{constructor(t={}){_(this,"wsUrl");_(this,"wsFactory");_(this,"tokenProvider");_(this,"ws",null);_(this,"subs",new Map);_(this,"snapshotPending",new Set);_(this,"preSubscribeQueue",new Map);_(this,"outbox",[]);_(this,"reconnectScheduler");_(this,"explicitlyClosed",!1);this.wsUrl=t.wsUrl??pt(),this.wsFactory=t.wsFactory??gt,this.tokenProvider=t.tokenProvider??Ne,this.reconnectScheduler=new Me({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.subs.size>0})}subscribe(t){const n=ft(),o={subscriberId:n,agentId:t.agentId,mode:t.mode,onSnapshot:t.onSnapshot,onData:t.onData,onError:t.onError,onSessionGone:t.onSessionGone};return this.subs.set(n,o),this.snapshotPending.add(n),this.preSubscribeQueue.set(n,[]),this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",subscriberId:n,agentId:t.agentId,mode:t.mode}),{subscriberId:n,unsubscribe:()=>this.unsubscribe(n)}}send(t,n){if(this.subs.has(t)){if(this.snapshotPending.has(t)){this.outbox.push({op:"input",subscriberId:t,data:n});return}this.wsSendOrQueue({op:"input",subscriberId:t,data:n})}}resize(t,n,o){const r=this.subs.get(t);r&&(r.lastSize={cols:n,rows:o},!this.snapshotPending.has(t)&&this.wsSendOrQueue({op:"resize",subscriberId:t,cols:n,rows:o}))}ping(){this.wsSendOrQueue({op:"ping"})}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.subs.clear(),this.snapshotPending.clear(),this.preSubscribeQueue.clear(),this.outbox=[]}unsubscribe(t){this.subs.has(t)&&(this.subs.delete(t),this.snapshotPending.delete(t),this.preSubscribeQueue.delete(t),this.wsSendOrQueue({op:"unsubscribe",subscriberId:t}),this.subs.size===0&&this.teardownSocket())}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const t=this.tokenProvider(),n=t?[`baxian.token.${bt(t)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,n)}catch(r){console.warn("[pane-stream] WebSocket constructor threw:",r),this.scheduleReconnect();return}this.ws=o,o.onopen=()=>{if(o!==this.ws)return;this.reconnectScheduler.reset();for(const i of this.subs.values()){this.snapshotPending.add(i.subscriberId),this.preSubscribeQueue.set(i.subscriberId,[]),i.snapshotSeq=void 0;try{o.send(JSON.stringify({op:"subscribe",subscriberId:i.subscriberId,agentId:i.agentId,mode:i.mode}))}catch(c){console.warn("[pane-stream] resubscribe send failed:",c)}}const r=this.outbox;this.outbox=[];for(const i of r)if(i.op!=="subscribe"){if("subscriberId"in i&&i.subscriberId){if(!this.subs.has(i.subscriberId))continue;if(this.snapshotPending.has(i.subscriberId)&&i.op!=="unsubscribe"){this.outbox.push(i);continue}}try{o.send(JSON.stringify(i))}catch(c){console.warn("[pane-stream] outbox flush failed:",c)}}},o.onmessage=r=>{if(o!==this.ws)return;let i;try{const c=typeof r.data=="string"?r.data:String(r.data);i=JSON.parse(c)}catch{return}this.handleMessage(i)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&this.subs.size!==0&&this.scheduleReconnect())},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}wsSendOrQueue(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(t));return}catch(n){console.warn("[pane-stream] send failed, will queue:",n)}this.outbox.push(t)}handleMessage(t){var n,o;switch(t.type){case"snapshot":this.handleSnapshot(t);break;case"subscribed":this.handleSubscribed(t);break;case"data":this.dispatch(t);break;case"session_gone":for(const r of[...this.subs.values()])r.agentId===t.agentId&&((n=r.onSessionGone)==null||n.call(r));break;case"error":{if(t.subscriberId){const r=this.subs.get(t.subscriberId);(o=r==null?void 0:r.onError)==null||o.call(r,{code:t.code,message:t.message})}else console.warn("[pane-stream] connection-level error:",t.code,t.message);break}}}handleSnapshot(t){const n=this.subs.get(t.subscriberId);n&&n.onSnapshot({cols:t.cols,rows:t.rows,data:t.data})}handleSubscribed(t){const n=this.subs.get(t.subscriberId);if(!n)return;n.snapshotSeq=t.snapshotSeq,n.lastSize||(n.lastSize={cols:t.cols,rows:t.rows}),this.snapshotPending.delete(t.subscriberId);const o=this.preSubscribeQueue.get(t.subscriberId);if(this.preSubscribeQueue.delete(t.subscriberId),o)for(const r of o)r.seq>t.snapshotSeq&&n.onData(r.data);n.mode==="full"&&n.lastSize&&this.wsSendOrQueue({op:"resize",subscriberId:n.subscriberId,cols:n.lastSize.cols,rows:n.lastSize.rows}),this.flushOutboxForSub(t.subscriberId)}flushOutboxForSub(t){if(this.outbox.length===0||!this.ws||this.ws.readyState!==WebSocket.OPEN)return;const n=[];for(const o of this.outbox)if("subscriberId"in o&&o.subscriberId===t&&o.op!=="subscribe")try{this.ws.send(JSON.stringify(o))}catch(r){console.warn("[pane-stream] flushOutboxForSub send failed:",r)}else n.push(o);this.outbox=n}dispatch(t){for(const n of this.subs.values())if(n.agentId===t.agentId)if(this.snapshotPending.has(n.subscriberId)){const o=this.preSubscribeQueue.get(n.subscriberId);o&&o.push({seq:t.seq,data:t.data})}else n.onData(t.data)}}let be=null;function pe(){return be||(be=new yt),be}function jt(s){const{agentId:t,mode:n}=s,o=a.useRef(null),r=a.useRef({onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone});r.current={onSnapshot:s.onSnapshot,onData:s.onData,onError:s.onError,onSessionGone:s.onSessionGone},a.useEffect(()=>{const p=pe().subscribe({agentId:t,mode:n,onSnapshot:b=>r.current.onSnapshot(b),onData:b=>r.current.onData(b),onError:b=>{var u,h;return(h=(u=r.current).onError)==null?void 0:h.call(u,b)},onSessionGone:()=>{var b,u;return(u=(b=r.current).onSessionGone)==null?void 0:u.call(b)}});return o.current=p.subscriberId,()=>{o.current=null,p.unsubscribe()}},[t,n]);const i=a.useCallback(m=>{const p=o.current;p&&pe().send(p,m)},[]),c=a.useCallback((m,p)=>{const b=o.current;b&&pe().resize(b,m,p)},[]);return{send:i,resize:c}}const wt=18,vt=250,St=256*1024,he="#e1e2e7",kt={background:he,foreground:"#3760bf",cursor:"#3760bf",cursorAccent:he,selectionBackground:"#b7c1e3",selectionForeground:"#3760bf",black:"#b4b5b9",red:"#f52a65",green:"#587539",yellow:"#8c6c3e",blue:"#2e7de9",magenta:"#9854f1",cyan:"#007197",white:"#6172b0",brightBlack:"#a1a6c5",brightRed:"#ff4774",brightGreen:"#5c8524",brightYellow:"#a27629",brightBlue:"#358aff",brightMagenta:"#a463ff",brightCyan:"#007ea8",brightWhite:"#3760bf"},Nt=/\x1b\[(?:\?[\d;]*c|>[\d;]*c|\??\d+;\d+R|\d+n)/g;function Et(s){return s.replace(Nt,"")}function je({agentId:s,mode:t,interactive:n=!1,maxLines:o,className:r,autoFocus:i=!0,deferFullUntilFocus:c=!1}){const m=a.useRef(null),p=a.useRef(null),b=a.useRef(null),u=a.useRef(!1),h=a.useRef(""),f=a.useRef([]),x=a.useRef(0),d=a.useRef(null),j=a.useRef(null),l=a.useRef(Promise.resolve()),T=a.useRef(0),[$,v]=a.useState(null),[A,g]=a.useState(!1),S=`${s}\0${t}\0${c?"1":"0"}`,[k,P]=a.useState({key:S,active:!1}),R=k.key===S&&k.active,D=t==="full"&&c,L=D&&!R?"preview":t,I=n&&L==="full",F=(y,N)=>N.length===0?Promise.resolve():new Promise(C=>{try{y.write(N,()=>C())}catch(w){console.warn("[pane-terminal] write failed:",w),C()}}),Q=(y,N)=>{l.current=l.current.then(async()=>{const C=p.current;if(!(!C||N!==T.current))try{await y(C)}catch(w){console.warn("[pane-terminal] terminal task failed:",w)}}).catch(C=>{console.warn("[pane-terminal] write chain failed:",C)})},q=(y,N)=>{Q(C=>F(C,y),N)},K=()=>{d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),j.current!==null&&(clearTimeout(j.current),j.current=null)},Y=()=>{K(),f.current=[],x.current=0},B=()=>{K();const y=f.current;y.length!==0&&(f.current=[],x.current=0,q(y.join(""),T.current))},H=y=>{if(y.length!==0){if(f.current.push(y),x.current+=y.length,x.current>=St){B();return}d.current===null&&(d.current=requestAnimationFrame(B)),j.current===null&&(j.current=setTimeout(B,vt))}},{send:J,resize:Z}=jt({agentId:s,mode:L,onSnapshot:({cols:y,rows:N,data:C})=>{if(p.current)try{const M=T.current+1;T.current=M,Y(),Q(async V=>{V.reset(),y>0&&N>0&&V.resize(y,N),await F(V,C)},M)}catch(M){console.warn("[pane-terminal] snapshot write failed:",M)}},onData:y=>{H(y)},onError:y=>v(`${y.code}: ${y.message}`),onSessionGone:()=>g(!0)});a.useEffect(()=>{v(null),g(!1)},[s,L]),a.useEffect(()=>{h.current=""},[S]),a.useEffect(()=>{if(L!=="full")return;const y=h.current;y.length!==0&&(h.current="",J(y))},[J,L]);const G=a.useCallback(()=>{!n||!D||R||(u.current=!0,P({key:S,active:!0}))},[S,R,n,D]);a.useEffect(()=>{const y=m.current;if(!y)return;let N=!1;const C=new Ye.Terminal({cursorBlink:n,disableStdin:!n,theme:kt,scrollback:L==="full"?5e3:1e3}),w=new Ze.FitAddon;if(C.loadAddon(w),C.open(y),p.current=C,b.current=w,n&&(i||u.current)){u.current=!1;try{C.focus()}catch{}}n&&C.onData(re=>{const ne=Et(re);if(ne.length!==0){if(D&&!R){h.current+=ne,G();return}J(ne)}});const M=()=>y.clientWidth>0&&y.clientHeight>0,V=(re=!1)=>{if(!M())return!1;const ne=C.cols,He=C.rows;try{w.fit()}catch{return!1}return C.cols>0&&C.rows>0&&(re||C.cols!==ne||C.rows!==He)&&Z(C.cols,C.rows),!0};let U=null,se=null,ce=null,Be=0;const Ae=()=>{U||(U=new ResizeObserver(()=>{se&&clearTimeout(se),se=setTimeout(()=>{se=null,V()},100)}),U.observe(y))},Ce=()=>{ce=requestAnimationFrame(()=>{if(ce=null,!(N||!I)){if(V(!0)){Ae();return}if(Be++<5){Ce();return}Ae()}})};return Ce(),()=>{N=!0,ce!==null&&cancelAnimationFrame(ce),d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),j.current!==null&&(clearTimeout(j.current),j.current=null),T.current++,f.current=[],x.current=0,l.current=Promise.resolve(),se&&clearTimeout(se),U==null||U.disconnect(),p.current=null,b.current=null;try{C.dispose()}catch(re){console.warn("[pane-terminal] dispose failed:",re)}}},[G,s,i,I,R,n,J,D,L,Z]);const E=()=>{var y;if(n){G();try{(y=p.current)==null||y.focus()}catch{}}},z=o&&o>0?{maxHeight:`${o*wt}px`}:void 0;return e.jsxs("div",{className:r??"flex flex-col h-full w-full min-h-0 bg-[#e1e2e7]",children:[($||A)&&e.jsx("div",{className:"px-3 py-1 text-[11px] font-mono text-red-300 bg-red-950/40 border-b border-red-900/60",children:A?"session ended":$}),e.jsx("div",{ref:m,className:"flex-1 min-h-0 overflow-hidden px-2 py-1.5",style:z,onMouseDown:E})]})}const Rt={unknown:{label:"Unknown",cls:"bg-slate-100 text-slate-700"},idle:{label:"Idle",cls:"bg-gray-100 text-gray-700"},pending:{label:"Pending user",cls:"bg-amber-200 text-amber-900"},working:{label:"Working",cls:"bg-green-100 text-green-800"},waiting:{label:"Waiting",cls:"bg-blue-100 text-blue-800"},error:{label:"Error",cls:"bg-red-100 text-red-800"}},At={present:{label:"Session present",cls:"bg-emerald-100 text-emerald-800"},absent:{label:"No session",cls:"bg-gray-100 text-gray-700"},unreachable:{label:"Host unreachable",cls:"bg-amber-100 text-amber-800"},unknown:{label:"Session unknown",cls:"bg-slate-100 text-slate-600"}};function Ct({agent:s,projectId:t,role:n,onDeleted:o,pendingRestart:r=!1,terminalLoading:i=!1,showTaskBinding:c=!0,terminalMode:m="activity-preview"}){var H,J,Z,G,E,z,y;const[p,b]=a.useState(!1),[u,h]=a.useState(null),{show:f}=le(),{flagDirty:x}=xe(),[d,j]=a.useState(!1),[l,T]=a.useState(null),[$,v]=a.useState(!1),[A,g]=a.useState(!1),S=(H=s.binding)==null?void 0:H.taskId,k=((J=s.binding)==null?void 0:J.status)==="awaiting_human",P=!!((Z=s.binding)!=null&&Z.creationToken)&&!((G=s.binding)!=null&&G.paneId)&&!k&&s.reason!=="PENDING_HUMAN",R=P?{label:"Starting",cls:"bg-sky-100 text-sky-800"}:Rt[s.runtimeStatus],D=P?{label:"Starting session",cls:"bg-sky-100 text-sky-800"}:At[s.tmuxSessionStatus],L=m==="activity-preview"&&!P&&(s.runtimeStatus==="working"||s.runtimeStatus==="pending"),I=m==="embedded-full",F=i||r||P,Q=i?"Agent 状态加载中":r?"重启 baxian server 后可用":"Agent 正在启动",q=async()=>{b(!0),h(null);try{await O.agents.stop(s.id)}catch(N){h(N instanceof Error?N.message:String(N))}finally{b(!1)}},K=async()=>{if(S&&window.confirm(`请 QA 对 task ${S} 重审?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`)){v(!0);try{const N=await O.tasks.review(S);f({kind:"success",title:`已派 QA 重审 (round ${N.reviewRound})`})}catch(N){f({kind:"error",title:"Review 派发失败",body:N instanceof Error?N.message:String(N)})}finally{v(!1)}}},Y=async()=>{if(window.confirm(`确认 Resume Agent ${s.id}?baxian 会清除 awaiting_human 状态,agent 重新可派遣。`)){g(!0);try{const N=await O.projects.resumeAgent(t,s.id);f({kind:"success",title:`Agent ${s.id} 已 Resume`,body:N.releasedBinding?"原任务已释放,agent 可接新任务。":"保留绑定(原任务仍 active)。"})}catch(N){f({kind:"error",title:"Resume 失败",body:N instanceof Error?N.message:String(N)})}finally{g(!1)}}},B=async()=>{if(window.confirm(`确认删除 Agent ${s.id}?此操作不可撤销`)){j(!0),T(null);try{const N=await O.projects.deleteAgent(t,s.id);N!=null&&N.restartRequired&&x();const C=(N==null?void 0:N.removed)??[s.id];if(C.length>1){const w=C.filter(M=>M!==s.id).join(", ");f({kind:"warn",title:`已删除 Agent ${s.id}`,body:`配对的 QA Agent ${w} 也被一并移除。`})}else f({kind:"success",title:`Agent ${s.id} 已删除`});o==null||o()}catch(N){T(N instanceof Error?N.message:String(N))}finally{j(!1)}}};return e.jsxs("div",{className:"bg-white rounded-lg border p-4 min-w-0 h-full flex flex-col",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2 mb-2",children:[e.jsx("span",{className:"font-mono font-bold",children:s.id}),e.jsxs("div",{className:"flex flex-wrap justify-end gap-1",children:[k&&e.jsx("span",{className:"px-2 py-0.5 rounded text-xs font-medium bg-amber-200 text-amber-900",title:((E=s.binding)==null?void 0:E.awaitingReason)??"需人工处理",children:"Held"}),e.jsx("span",{className:`px-2 py-0.5 rounded text-xs font-medium ${R.cls}`,children:R.label}),e.jsx("span",{className:`px-2 py-0.5 rounded text-xs font-medium ${D.cls}`,children:D.label}),s.stale&&e.jsx("span",{className:"px-2 py-0.5 rounded text-xs font-medium bg-orange-100 text-orange-800",title:s.observedAt?`Last observed at ${s.observedAt}`:void 0,children:"Stale"})]})]}),P&&e.jsx("div",{className:"text-xs text-sky-900 mb-2 bg-sky-50 border border-sky-200 px-2 py-2 rounded",children:"Agent 正在启动,终端可用后会自动刷新。"}),k&&e.jsxs("div",{className:"text-xs text-amber-900 mb-2 bg-amber-50 border border-amber-200 px-2 py-2 rounded",children:[e.jsx("span",{className:"font-mono",children:(z=s.binding)==null?void 0:z.awaitingPhase}),((y=s.binding)==null?void 0:y.awaitingReason)&&e.jsxs("span",{children:[" · ",s.binding.awaitingReason]})]}),!P&&s.runtimeStatus==="pending"&&e.jsxs("div",{className:"text-xs text-amber-900 mb-2 bg-amber-50 border border-amber-200 px-2 py-2 rounded space-y-1",children:[e.jsx("div",{className:"font-medium",children:"等待人工介入"}),e.jsxs("div",{children:["Agent 正在等待人工输入。请打开 ",e.jsx(ee,{to:`/terminal/${s.id}`,className:"text-blue-700 underline",children:"Terminal"})," 处理; 处理完后状态会随下一次观测刷新。"]})]}),s.latestError&&e.jsxs("div",{className:"text-xs text-red-700 mb-2 bg-red-50 border border-red-200 px-2 py-2 rounded space-y-1",children:[e.jsx("div",{className:"font-medium break-words",children:s.latestError.message}),e.jsxs("div",{className:"text-[11px] text-red-600",children:[s.latestError.reason," · ",s.latestError.occurredAt]})]}),c&&S&&e.jsxs("div",{className:"text-sm text-gray-500 mb-2",children:["Task: ",S]}),L&&e.jsx("div",{className:"mb-2 border border-zinc-800",style:{backgroundColor:he},children:e.jsx(je,{agentId:s.id,mode:"preview",maxLines:6,interactive:!1})}),I&&e.jsx("div",{className:"mt-3 mb-2 h-80 min-h-0 overflow-hidden border border-zinc-800",style:{backgroundColor:he},children:F?e.jsx("div",{className:"flex h-full items-center justify-center px-3 text-sm text-gray-600",children:Q}):e.jsx(je,{agentId:s.id,mode:"full",interactive:!0,autoFocus:!1,deferFullUntilFocus:!0})}),r&&e.jsx("div",{className:"text-xs text-amber-700 mb-2 bg-amber-50 px-2 py-1 rounded",children:"⚠️ 重启 baxian server 后生效"}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-x-3 gap-y-2 items-center",children:[F?e.jsx("span",{className:"text-sm text-gray-400 cursor-not-allowed",title:Q,children:"Terminal"}):e.jsx(ee,{to:`/terminal/${s.id}`,className:"text-sm text-blue-600 hover:underline",children:"Terminal"}),!r&&s.runtimeStatus==="working"&&e.jsx("button",{onClick:q,disabled:p,className:"text-sm text-red-600 hover:underline disabled:opacity-50",children:p?"Stopping…":"Stop"}),u&&e.jsx("span",{className:"text-xs text-red-500",children:u}),k&&e.jsx("button",{type:"button",onClick:Y,disabled:A,title:"清除 awaiting_human 状态,让 agent 重新可派遣",className:"text-sm text-amber-700 hover:underline disabled:opacity-50",children:A?"Resuming…":"Resume"}),!r&&S&&n==="dev"&&e.jsx("button",{type:"button",onClick:K,disabled:$,title:`让 QA 立即对 task ${S} 跑一轮 review(需要该 task 已有 PR)`,className:"text-sm text-purple-700 hover:underline disabled:opacity-50",children:$?"Dispatching…":"Request QA review"}),e.jsx("button",{type:"button",onClick:B,disabled:d,className:"text-sm text-red-600 hover:underline disabled:opacity-50 ml-auto","aria-label":`Delete agent ${s.id}`,children:d?"删除中…":"🗑"}),l&&e.jsx("span",{className:"text-xs text-red-500",children:l})]})]})}const Tt=new Set(["in_progress","review","fixing","approved"]);function Qe({group:s,projectId:t,agentsById:n,agentsLoaded:o,agentsError:r=!1,tasks:i,onDeleted:c,terminalMode:m="activity-preview"}){const p=s.find(x=>x.role==="dev")??s[0],b=s.find(x=>x.role==="qa"),u=i.filter(x=>It(x,p==null?void 0:p.id,b==null?void 0:b.id)),h=`Agent group ${s.map(x=>x.id).join(" / ")}`,f=m==="embedded-full"?s.length<=1?"lg:grid-cols-1":s.length===2?"lg:grid-cols-2":s.length===3?"lg:grid-cols-3":"lg:grid-cols-4":"sm:grid-cols-2";return e.jsxs("div",{role:"group","aria-label":h,className:"min-w-0",children:[u.length>0?e.jsx("div",{className:"mb-2 max-h-28 overflow-y-auto rounded border bg-white divide-y",children:u.map(x=>{const d=x.phase==="spec"?x.specReviewRound??0:x.reviewRound;return e.jsxs(ee,{to:`/task/${x.id}`,className:"flex items-center gap-3 px-3 py-2 text-sm hover:bg-gray-50",children:[e.jsxs("div",{className:"min-w-0 flex-1 flex items-center gap-2",children:[e.jsx("span",{className:"font-mono text-xs text-blue-700 shrink-0",children:x.id}),e.jsx("span",{className:"truncate font-medium text-gray-900",children:x.title})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("span",{className:"text-xs px-2 py-0.5 rounded bg-gray-100 text-gray-700",children:x.status}),e.jsxs("span",{"aria-label":`Round ${d}`,className:"text-xs font-semibold px-2 py-0.5 rounded bg-blue-100 text-blue-700",children:["Round ",d]})]})]},x.id)})}):e.jsx("div",{className:"mb-2 rounded border border-dashed bg-white px-3 py-2 text-sm text-gray-400","aria-label":`${h} no active task`,children:"暂无任务"}),e.jsx("div",{className:`grid grid-cols-1 ${f} gap-4`,children:s.map(x=>{const d=n.get(x.id),j=d??{id:x.id,projectId:t,runtimeStatus:"unknown",tmuxSessionStatus:"unknown",stale:!0};return e.jsx(Ct,{agent:j,projectId:t,role:x.role,pendingRestart:o&&!d,terminalLoading:!o&&!d&&!r,onDeleted:c,showTaskBinding:!1,terminalMode:m},x.id)})})]})}function It(s,t,n){return!(!t||!Tt.has(s.status)||!(s.agentId===t||s.preferredAgentId===t)||n&&s.qaAgentId&&s.qaAgentId!==n)}const Pt={sm:"max-w-md",md:"max-w-lg",lg:"max-w-2xl"},Pe='input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [href], [tabindex]:not([tabindex="-1"])';function fe({open:s,onClose:t,title:n,children:o,size:r="md"}){const i=a.useRef(null),c=a.useRef(null),m=a.useRef(t);return a.useEffect(()=>{m.current=t},[t]),a.useEffect(()=>{if(!s)return;c.current=document.activeElement;const p=h=>{if(h.key==="Escape"){m.current();return}if(h.key!=="Tab")return;const f=i.current;if(!f)return;const x=Array.from(f.querySelectorAll(Pe)).filter(T=>T.offsetParent!==null||T===document.activeElement);if(x.length===0){h.preventDefault();return}const d=x[0],j=x[x.length-1],l=document.activeElement;h.shiftKey&&(l===d||!f.contains(l))?(h.preventDefault(),j.focus()):!h.shiftKey&&(l===j||!f.contains(l))&&(h.preventDefault(),d.focus())};document.addEventListener("keydown",p);const b=document.body.style.overflow;document.body.style.overflow="hidden";const u=i.current;if(u){const h=u.querySelector(Pe);h==null||h.focus()}return()=>{var h,f;document.removeEventListener("keydown",p),document.body.style.overflow=b,(f=(h=c.current)==null?void 0:h.focus)==null||f.call(h)}},[s]),s?e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-3 sm:px-4",onClick:()=>m.current(),role:"presentation",children:e.jsxs("div",{ref:i,className:`bg-white rounded-lg shadow-xl w-full ${Pt[r]} max-h-[90vh] overflow-auto`,onClick:p=>p.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":n,children:[e.jsxs("div",{className:"flex items-center justify-between px-6 py-4 border-b",children:[e.jsx("h2",{className:"text-lg font-semibold",children:n}),e.jsx("button",{type:"button",onClick:()=>m.current(),className:"text-gray-400 hover:text-gray-600","aria-label":"Close",children:"✕"})]}),e.jsx("div",{className:"px-6 py-4",children:o})]})}):null}const $t=/^[a-z][a-z0-9-]{1,31}$/,Dt=/^[A-Za-z0-9_-][A-Za-z0-9._-]*\/[A-Za-z0-9_-][A-Za-z0-9._-]*$/;function Ot({open:s,onClose:t,onCreated:n}){const[o,r]=a.useState(""),[i,c]=a.useState(""),[m,p]=a.useState(null),[b,u]=a.useState(!1),[h,f]=a.useState(null),[x,d]=a.useState({}),[j,l]=a.useState(new Set),T=a.useRef(0),{show:$}=le(),{flagDirty:v}=xe();a.useEffect(()=>{if(!s)return;T.current+=1;const k=T.current;r(""),c(""),p(null),f(null),d({}),l(new Set),O.config.get().then(P=>{k===T.current&&l(new Set(P.project.map(R=>R.id)))}).catch(()=>{})},[s]);const A=()=>{b||t()},g=()=>{const k={};return o?$t.test(o)?j.has(o)&&(k.id="该 id 已被占用"):k.id="小写字母开头,只含 a-z 0-9 -,长度 2-32":k.id="必填",i?Dt.test(i)||(k.repo="需为 owner/repo 形式"):k.repo="必填",d(k),Object.keys(k).length===0},S=async k=>{if(k.preventDefault(),!!g()){u(!0),f(null);try{const P=await O.projects.create({id:o,repo:i,merge:m});P.restartRequired&&v(),$({kind:"success",title:`项目 ${P.project.id} 已创建`}),n(P.project.id)}catch(P){f(P instanceof Error?P.message:String(P))}finally{u(!1)}}};return e.jsx(fe,{open:s,onClose:A,title:"新建项目",size:"md",children:e.jsxs("form",{onSubmit:S,className:"space-y-4",children:[h&&e.jsx("div",{className:"bg-red-50 border border-red-200 text-red-800 px-3 py-2 rounded text-sm",children:h}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"proj-id",children:"项目 ID"}),e.jsx("input",{id:"proj-id",type:"text",value:o,onChange:k=>r(k.target.value),className:"w-full border rounded px-3 py-2",placeholder:"kongkong",disabled:b}),x.id&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:x.id})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"proj-repo",children:"GitHub 仓库"}),e.jsx("input",{id:"proj-repo",type:"text",value:i,onChange:k=>c(k.target.value),className:"w-full border rounded px-3 py-2",placeholder:"rockdai/baxian",disabled:b}),x.repo&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:x.repo})]}),e.jsxs("div",{children:[e.jsx("span",{className:"block text-sm font-medium mb-1",children:"合并策略"}),e.jsxs("label",{className:"flex items-center gap-2 mb-1",children:[e.jsx("input",{type:"radio",name:"merge",checked:m===null,onChange:()=>p(null),disabled:b}),e.jsx("span",{className:"text-sm",children:"人类合并(默认)"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"merge",checked:m==="auto",onChange:()=>p("auto"),disabled:b}),e.jsx("span",{className:"text-sm",children:"QA Approve 后自动合并"})]})]}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4 border-t",children:[e.jsx("button",{type:"button",onClick:A,disabled:b,className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50",children:"取消"}),e.jsx("button",{type:"submit",disabled:b,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50",children:b?"创建中…":"创建"})]})]})})}const $e=/^[a-z][a-z0-9-]{1,31}$/,_t=500,De={id:"",role:"dev",pairWith:"",mode:"local",hostname:"",user:"",runtime:"",workdir:"",yolo:!0,model:"",addDirs:""};function Ue({open:s,onClose:t,projectId:n,onCreated:o}){var G;const[r,i]=a.useState(De),[c,m]=a.useState(null),[p,b]=a.useState(new Set),[u,h]=a.useState(null),[f,x]=a.useState(!1),[d,j]=a.useState(!1),[l,T]=a.useState(null),$=a.useRef(null),v=a.useRef(null),A=a.useRef(0),{show:g}=le(),{flagDirty:S}=xe();a.useEffect(()=>{if(!s)return;A.current+=1;const E=A.current;i(De),m(null),b(new Set),h(null),x(!1),T(null),O.config.get().then(z=>{if(E!==A.current)return;const y=z.project.find(C=>C.id===n)??null;m(y);const N=new Set;z.project.forEach(C=>C.agent.forEach(w=>w.forEach(M=>N.add(M.id)))),b(N)}).catch(()=>{})},[s,n]);const k=()=>{d||t()},P=a.useCallback(()=>{$.current&&$.current.abort();const E=new AbortController;$.current=E,x(!0),T(null);const z=r.mode==="remote"?{hostname:r.hostname,user:r.user||void 0}:void 0;O.agents.probe(r.mode,z,{signal:E.signal}).then(y=>{E.signal.aborted||(h(y),T(null))}).catch(y=>{E.signal.aborted||(h(null),T(y instanceof Error?y.message:String(y)))}).finally(()=>{$.current===E&&x(!1)})},[r.mode,r.hostname,r.user]);a.useEffect(()=>{if(s&&(h(null),$.current&&$.current.abort(),!(r.mode==="remote"&&!r.hostname)))return v.current&&clearTimeout(v.current),v.current=setTimeout(P,_t),()=>{v.current&&clearTimeout(v.current)}},[s,r.mode,r.hostname,r.user,P]),a.useEffect(()=>{s||$.current&&$.current.abort()},[s]),a.useEffect(()=>()=>{$.current&&$.current.abort(),v.current&&clearTimeout(v.current)},[]);const R=(c==null?void 0:c.agent.filter(E=>E.length===1&&E[0].role==="dev").map(E=>E[0]))??[],D=R.length>0,L=$e.test(r.id)&&!p.has(r.id),I=r.mode==="local"||r.mode==="remote"&&r.hostname.length>0,F=r.runtime!==""&&(r.runtime==="claude-code"?!!(u!=null&&u.runtimes["claude-code"].ok):!!(u!=null&&u.runtimes.codex.ok)),Q=!!(u!=null&&u.tmux.ok),q=r.mode==="local"||!!((G=u==null?void 0:u.ssh)!=null&&G.ok),K=r.role==="dev"||r.role==="qa"&&r.pairWith!=="",Y=!d&&L&&I&&K&&F&&Q&&q,B=async E=>{if(E.preventDefault(),!!Y){j(!0),T(null);try{const z=r.addDirs.split(`
|
|
2
|
-
`).map(C=>C.trim()).filter(C=>C.length>0),y={id:r.id,role:r.role,runtime:r.runtime,mode:r.mode,...r.mode==="remote"?{host:{hostname:r.hostname,...r.user?{user:r.user}:{}}}:{},...r.workdir?{workdir:r.workdir}:{},yolo:r.yolo,...r.model.trim()?{model:r.model.trim()}:{},...z.length>0?{addDirs:z}:{},...r.role==="qa"?{pairWith:r.pairWith}:{}},N=await O.projects.addAgent(n,y);N.restartRequired&&S(),g({kind:"success",title:`Agent ${N.agent.id} 已添加到 ${n}`}),o(),t()}catch(z){T(z instanceof Error?z.message:String(z))}finally{j(!1)}}},H=({rt:E})=>{if(r.mode==="remote"&&!r.hostname)return e.jsx("span",{className:"text-xs text-gray-400 ml-2",children:"(请先填写 hostname)"});if(f)return e.jsx("span",{className:"text-xs text-gray-400 ml-2",children:"…探测中"});if(!u)return e.jsx("span",{className:"text-xs text-gray-400 ml-2",children:"?"});const y=u.runtimes[E];return y.ok?e.jsxs("span",{className:"text-xs text-green-600 ml-2",children:["✓ ",y.path??""]}):e.jsxs("span",{className:"text-xs text-red-500 ml-2",title:y.message,children:["⨯ ",y.message]})},J=()=>r.mode==="remote"&&!r.hostname?null:f?e.jsx("div",{className:"text-xs text-gray-400",children:"tmux: …探测中"}):u?u.tmux.ok?e.jsxs("div",{className:"text-xs text-green-600",children:["tmux: ✓ ",u.tmux.path??""]}):e.jsxs("div",{className:"text-xs text-red-500",children:["tmux: ⨯ ",u.tmux.message]}):null,Z=()=>r.mode!=="remote"||!r.hostname||!(u!=null&&u.ssh)?null:u.ssh.ok?e.jsxs("div",{className:"text-xs text-green-600",children:["SSH: ✓ ",u.ssh.message]}):e.jsxs("div",{className:"text-xs text-red-500",children:["SSH: ⨯ ",u.ssh.message]});return e.jsx(fe,{open:s,onClose:k,title:`添加 Agent 到 ${n}`,size:"lg",children:e.jsxs("form",{onSubmit:B,className:"space-y-4",children:[l&&e.jsx("div",{className:"bg-red-50 border border-red-200 text-red-800 px-3 py-2 rounded text-sm",children:l}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"agent-id",children:"Agent ID"}),e.jsx("input",{id:"agent-id",type:"text",value:r.id,onChange:E=>i({...r,id:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"kk-cc",disabled:d}),r.id&&!$e.test(r.id)&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:"小写字母开头,只含 a-z 0-9 -,长度 2-32"}),r.id&&p.has(r.id)&&e.jsx("div",{className:"text-xs text-red-600 mt-1",children:"该 id 已被占用(全局唯一)"})]}),e.jsxs("div",{children:[e.jsx("span",{className:"block text-sm font-medium mb-1",children:"角色"}),e.jsxs("label",{className:"inline-flex items-center gap-2 mr-4",children:[e.jsx("input",{type:"radio",name:"role",checked:r.role==="dev",onChange:()=>i({...r,role:"dev",pairWith:""}),disabled:d}),e.jsx("span",{className:"text-sm",children:"Dev"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",title:D?"":"请先创建一个 Dev Agent",children:[e.jsx("input",{type:"radio",name:"role",checked:r.role==="qa",onChange:()=>i({...r,role:"qa"}),disabled:d||!D}),e.jsx("span",{className:`text-sm ${D?"":"text-gray-400"}`,children:"QA"})]})]}),r.role==="qa"&&e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"pair-with",children:"配对 Dev Agent"}),e.jsxs("select",{id:"pair-with",value:r.pairWith,onChange:E=>i({...r,pairWith:E.target.value}),className:"w-full border rounded px-3 py-2",disabled:d,children:[e.jsx("option",{value:"",children:"请选择"}),R.map(E=>e.jsxs("option",{value:E.id,children:[E.id," (dev, ",E.mode,")"]},E.id))]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"block text-sm font-medium mb-1",children:"运行模式"}),e.jsxs("label",{className:"inline-flex items-center gap-2 mr-4",children:[e.jsx("input",{type:"radio",name:"mode",checked:r.mode==="local",onChange:()=>i({...r,mode:"local",hostname:"",user:""}),disabled:d}),e.jsx("span",{className:"text-sm",children:"本机"})]}),e.jsxs("label",{className:"inline-flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"mode",checked:r.mode==="remote",onChange:()=>i({...r,mode:"remote"}),disabled:d}),e.jsx("span",{className:"text-sm",children:"远程 (SSH)"})]})]}),r.mode==="remote"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"hostname",children:"Hostname"}),e.jsx("input",{id:"hostname",type:"text",value:r.hostname,onChange:E=>i({...r,hostname:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"macmini-2026",disabled:d}),e.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"端口/私钥/跳板机请配 ~/.ssh/config"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"user",children:"User(可选)"}),e.jsx("input",{id:"user",type:"text",value:r.user,onChange:E=>i({...r,user:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"留空则读 ~/.ssh/config 的 User",disabled:d})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("span",{className:"block text-sm font-medium",children:"运行时"}),e.jsx("button",{type:"button",onClick:P,className:"text-xs text-blue-600 hover:underline disabled:opacity-50 disabled:no-underline disabled:cursor-not-allowed",disabled:d||f||r.mode==="remote"&&!r.hostname,children:"↻ 重新探测"})]}),e.jsxs("label",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"radio",name:"runtime",checked:r.runtime==="claude-code",onChange:()=>i({...r,runtime:"claude-code"}),disabled:d||(u?!u.runtimes["claude-code"].ok:!1)}),e.jsx("span",{className:"text-sm",children:"Claude Code"}),e.jsx(H,{rt:"claude-code"})]}),e.jsxs("label",{className:"flex items-center gap-2 mt-1",children:[e.jsx("input",{type:"radio",name:"runtime",checked:r.runtime==="codex",onChange:()=>i({...r,runtime:"codex"}),disabled:d||(u?!u.runtimes.codex.ok:!1)}),e.jsx("span",{className:"text-sm",children:"Codex"}),e.jsx(H,{rt:"codex"})]}),e.jsx("div",{className:"mt-2",children:e.jsx(J,{})}),e.jsx("div",{children:e.jsx(Z,{})})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"workdir",children:"Workdir(可选)"}),e.jsx("input",{id:"workdir",type:"text",value:r.workdir,onChange:E=>i({...r,workdir:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:"留空时自动 clone 到 ~/.baxian/repos/<owner>/<repo>",disabled:d})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"model",children:"Model(可选)"}),e.jsx("input",{id:"model",type:"text",value:r.model,onChange:E=>i({...r,model:E.target.value}),className:"w-full border rounded px-3 py-2",placeholder:r.runtime==="codex"?"例: o3 / gpt-4o(留空走 default)":"例: sonnet / opus / claude-sonnet-4-6(留空走 default)",disabled:d}),e.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"透传到 launch 命令的 --model 参数;留空跟随 CLI 默认。"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"addDirs",children:"Additional Dirs(可选)"}),e.jsx("textarea",{id:"addDirs",value:r.addDirs,onChange:E=>i({...r,addDirs:E.target.value}),className:"w-full border rounded px-3 py-2 font-mono text-xs",rows:3,placeholder:`每行一个绝对路径,例:
|
|
3
|
-
/Users/me/shared-libs
|
|
4
|
-
/Users/me/extra-repo`,disabled:d}),e.jsx("div",{className:"text-xs text-gray-500 mt-1",children:"透传到 --add-dir。当前 YOLO 模式下不影响权限拦截,主要用于让 CLI 把额外目录纳入工作根。"})]}),e.jsx("div",{className:"bg-amber-50 border border-amber-200 px-3 py-2 rounded",children:e.jsxs("label",{className:"flex items-start gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",className:"mt-1",checked:r.yolo,onChange:E=>i({...r,yolo:E.target.checked}),disabled:d}),e.jsxs("div",{className:"text-sm",children:[e.jsx("div",{className:"font-medium",children:"YOLO 模式(推荐开启)"}),e.jsxs("div",{className:"text-xs text-amber-900 mt-1",children:["Agent 自主执行所有命令、文件改动,无需逐条确认。开启后体验更顺滑, 但",e.jsx("strong",{children:"请确认在受控环境(容器、隔离 worktree)中运行"}),"。"]})]})]})}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4 border-t",children:[e.jsx("button",{type:"button",onClick:k,disabled:d,className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50",children:"取消"}),e.jsx("button",{type:"submit",disabled:!Y,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50",children:d?"添加中…":"添加 Agent"})]})]})})}const Oe=200,_e=16e3;function Ee(s){const t=s.mode==="edit",n=ve(),{show:o}=le(),r=t?s.task.projectId:s.projectId,i=t?s.task.title:"",c=t?s.task.description:"",m=t?s.task.preferredAgentId:"",[p,b]=a.useState([]),[u,h]=a.useState([]),[f,x]=a.useState(r??""),[d,j]=a.useState(m),[l,T]=a.useState(i),[$,v]=a.useState(c),[A,g]=a.useState(!1),[S,k]=a.useState(null),P=a.useRef(0);a.useEffect(()=>{if(!s.open)return;P.current+=1;const w=P.current;b([]),h([]),x(r??""),j(m),T(i),v(c),k(null),g(!1),Promise.all([O.projects.list(),O.agents.list()]).then(([M,V])=>{w===P.current&&(b(M),h(V))}).catch(M=>{w===P.current&&k(M instanceof Error?M.message:String(M))})},[s.open,r,i,c,m]);const R=a.useMemo(()=>p.find(w=>w.id===f)??null,[p,f]),D=a.useMemo(()=>R?R.agent.flat().filter(w=>w.role==="dev"):[],[R]),L=a.useMemo(()=>new Set(u.map(w=>w.id)),[u]),I=a.useMemo(()=>D.filter(w=>L.has(w.id)),[D,L]),F=a.useMemo(()=>D.filter(w=>!L.has(w.id)),[D,L]);a.useEffect(()=>{if(!t){if(I.length===0){d!==""&&j("");return}I.find(w=>w.id===d)||j(I[0].id)}},[I,d,t]);const Q=!t||I.find(w=>w.id===d),q=t&&!Q&&!!d,K=q&&F.some(w=>w.id===d),Y=K?`当前 dev "${d}" 在 baxian.json 中存在但 runtime 未加载,可能是手动编辑过配置文件;重启 server 可拉起`:q?`当前 dev "${d}" 不在 runtime(可能已从 project 配置移除);保存可能失败,请确认或选择新 dev`:!f||I.length>0?null:F.length>0?"baxian.json 里有 dev agent 但 runtime 未加载(可能是手动编辑过配置);重启 server 后生效":"请先为项目添加 dev agent",B=l.trim(),H=$.trim(),J=I.length>0||q,G=!!f&&J&&!!d&&B.length>0&&H.length>0&&!A,E=()=>{A||s.onClose()},z=async w=>{var M,V;if(w.preventDefault(),!!G){g(!0),k(null);try{if(s.mode==="edit"){const U=await O.tasks.update(s.task.id,{title:B,description:H,preferredAgentId:d});o({kind:"success",title:"任务已更新"}),(M=s.onUpdated)==null||M.call(s,U),s.onClose()}else{const U=await O.tasks.create({projectId:f,title:B,description:H,preferredAgentId:d});o({kind:"success",title:"任务已创建"}),(V=s.onCreated)==null||V.call(s,U),s.onClose(),n(`/task/${U.id}`)}}catch(U){k(U instanceof Error?U.message:String(U))}finally{g(!1)}}},y=t?"编辑 Task":"新建 Task",N=t?A?"保存中…":"保存":A?"创建中…":"创建",C=!t&&!r;return e.jsx(fe,{open:s.open,onClose:E,title:y,size:"md",children:e.jsxs("form",{onSubmit:z,className:"space-y-4",children:[S&&e.jsx("div",{className:"bg-red-50 border border-red-200 text-red-800 px-3 py-2 rounded text-sm",children:S}),C&&e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-project",children:"Project"}),e.jsxs("select",{id:"task-project",value:f,onChange:w=>x(w.target.value),className:"w-full border rounded px-3 py-2 disabled:bg-gray-50",disabled:A,required:!0,children:[e.jsx("option",{value:"",disabled:!0,children:"选择项目"}),p.map(w=>e.jsx("option",{value:w.id,children:w.id},w.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-dev",children:"Dev Agent"}),e.jsxs("select",{id:"task-dev",value:d,onChange:w=>j(w.target.value),className:"w-full border rounded px-3 py-2 disabled:bg-gray-50",disabled:A||I.length===0&&!q||I.length===1&&I[0].id===d&&!q,required:!0,children:[I.length===0&&!q&&e.jsx("option",{value:"",disabled:!0,children:"无可用 dev"}),q&&e.jsxs("option",{value:d,children:[d," ",K?"(待重启)":"(不在 runtime)"]}),I.map(w=>e.jsx("option",{value:w.id,children:w.id},w.id))]}),Y&&e.jsx("div",{className:"text-xs text-amber-700 mt-1",children:Y})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-title",children:"Title"}),e.jsx("input",{id:"task-title",type:"text",value:l,onChange:w=>T(w.target.value),maxLength:Oe,className:"w-full border rounded px-3 py-2",placeholder:"一句话描述要做什么",disabled:A,required:!0}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1 text-right",children:[l.length," / ",Oe]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1",htmlFor:"task-description",children:"Description"}),e.jsx("textarea",{id:"task-description",value:$,onChange:w=>v(w.target.value),maxLength:_e,rows:8,className:"w-full border rounded px-3 py-2 font-mono text-sm",placeholder:"详细描述任务,支持 markdown",disabled:A,required:!0}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1 text-right",children:[$.length," / ",_e]})]}),e.jsxs("div",{className:"flex justify-end gap-2 pt-4 border-t",children:[e.jsx("button",{type:"button",onClick:E,disabled:A,className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50",children:"取消"}),e.jsx("button",{type:"submit",disabled:!G,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:opacity-50",children:N})]})]})})}function Lt(s){return Array.from(new TextEncoder().encode(s)).map(t=>t.toString(16).padStart(2,"0")).join("")}function Ft(){return`${location.protocol==="https:"?"wss":"ws"}://${location.host}/api/realtime`}const zt=(s,t)=>t&&t.length>0?new WebSocket(s,t):new WebSocket(s);class Mt{constructor(t={}){_(this,"wsUrl");_(this,"wsFactory");_(this,"tokenProvider");_(this,"ws",null);_(this,"topics",new Map);_(this,"cache",new Map);_(this,"outbox",[]);_(this,"reconnectScheduler");_(this,"explicitlyClosed",!1);this.wsUrl=t.wsUrl??Ft(),this.wsFactory=t.wsFactory??zt,this.tokenProvider=t.tokenProvider??Ne,this.reconnectScheduler=new Me({reconnect:()=>this.openSocket(),shouldReconnect:()=>!this.explicitlyClosed&&this.topics.size>0})}subscribe(t,n,o){let r=this.topics.get(t);const i=!r;return r||(r={data:new Set,error:new Set},this.topics.set(t,r)),r.data.add(n),o&&r.error.add(o),i?(this.ensureSocket(),this.wsSendOrQueue({op:"subscribe",topic:t})):this.cache.has(t)&&queueMicrotask(()=>{var c;(c=this.topics.get(t))!=null&&c.data.has(n)&&this.cache.has(t)&&n(this.cache.get(t))}),()=>this.unsubscribe(t,n,o)}close(){if(this.explicitlyClosed=!0,this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.ws){try{this.ws.close()}catch{}this.ws=null}this.topics.clear(),this.cache.clear(),this.outbox=[]}unsubscribe(t,n,o){const r=this.topics.get(t);r&&(r.data.delete(n),o&&r.error.delete(o),r.data.size===0&&r.error.size===0&&(this.topics.delete(t),this.cache.delete(t),this.wsSendOrQueue({op:"unsubscribe",topic:t}),this.topics.size===0&&this.teardownSocket()))}teardownSocket(){if(this.reconnectScheduler.cancel(),this.reconnectScheduler.reset(),this.outbox=[],this.ws){try{this.ws.close()}catch{}this.ws=null}}ensureSocket(){this.explicitlyClosed||this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING)||this.openSocket()}openSocket(){if(this.explicitlyClosed)return;this.reconnectScheduler.cancel();const t=this.tokenProvider(),n=t?[`baxian.token.${Lt(t)}`]:void 0;let o;try{o=this.wsFactory(this.wsUrl,n)}catch(i){console.warn("[events-client] WebSocket constructor threw:",i),this.broadcastConnectionError({code:"connection_failed",message:i instanceof Error?i.message:"WebSocket constructor threw"}),this.scheduleReconnect();return}this.ws=o;let r=!1;o.onopen=()=>{if(o!==this.ws)return;r=!0,this.reconnectScheduler.reset();for(const c of this.topics.keys())try{o.send(JSON.stringify({op:"subscribe",topic:c}))}catch(m){console.warn("[events-client] resubscribe send failed:",m)}const i=this.outbox;this.outbox=[];for(const c of i)if(!(c.op==="subscribe"||c.op==="unsubscribe"))try{o.send(JSON.stringify(c))}catch(m){console.warn("[events-client] outbox flush failed:",m)}},o.onmessage=i=>{if(o!==this.ws)return;let c;try{const m=typeof i.data=="string"?i.data:String(i.data);c=JSON.parse(m)}catch{return}this.handleMessage(c)},o.onclose=()=>{o===this.ws&&(this.ws=null,!this.explicitlyClosed&&(r||this.broadcastConnectionError({code:"connection_failed",message:"WebSocket failed to connect (auth, network, or proxy issue)"}),this.topics.size!==0&&this.scheduleReconnect()))},o.onerror=()=>{}}scheduleReconnect(){this.reconnectScheduler.schedule()}broadcastConnectionError(t){for(const n of this.topics.values())for(const o of[...n.error])try{o(t)}catch(r){console.error("[events-client] error handler threw on connection error:",r)}}wsSendOrQueue(t){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(t));return}catch(n){console.warn("[events-client] send failed, will queue:",n)}this.outbox.push(t)}handleMessage(t){switch(t.type){case"data":{const n=this.topics.get(t.topic);if(this.cache.set(t.topic,t.data),!n)return;for(const o of[...n.data])try{o(t.data)}catch(r){console.error(`[events-client] handler threw on ${t.topic}:`,r)}break}case"error":{const n={code:t.code,message:t.message};if(t.topic){const o=this.topics.get(t.topic);if(o)for(const r of[...o.error])try{r(n)}catch(i){console.error(`[events-client] error handler threw on ${t.topic}:`,i)}}else console.warn("[events-client] connection-level error:",t.code,t.message);break}}}}let ge=null;function Re(){return ge||(ge=new Mt),ge}function qe(){const[s,t]=a.useState(null),[n,o]=a.useState(!1),[r,i]=a.useState(null);return a.useEffect(()=>Re().subscribe("agents",m=>{i(null),t(m),o(!0)},m=>i(m)),[]),{data:s,loaded:n,error:r}}function Qt(s){const[t,n]=a.useState(null),[o,r]=a.useState(!1),[i,c]=a.useState(null);return a.useEffect(()=>(n(null),r(!1),c(null),Re().subscribe(`task:${s}`,p=>{c(null),n(p),r(!0)},p=>c(p))),[s]),{data:t,loaded:o,error:i}}function Ut(s){const[t,n]=a.useState(null),[o,r]=a.useState(!1),[i,c]=a.useState(null);return a.useEffect(()=>{if(!s){n(null),r(!1),c(null);return}n(null),r(!1),c(null);let m=!1,p=!1,b=!1;const u=Re().subscribe(`project-tasks:${s}`,h=>{m||(p=!0,c(null),n(h),r(!0))},h=>{m||(c(h),!(p||b)&&(b=!0,O.tasks.list(s).then(f=>{m||p||(n(f),r(!0))},f=>{console.warn(`[useProjectTasks] REST fallback failed for ${s}:`,f)})))});return()=>{m=!0,u()}},[s]),{data:t,loaded:o,error:i}}function qt(){const[s,t]=a.useState([]),[n,o]=a.useState([]),[r,i]=a.useState(!1),[c,m]=a.useState(null),[p,b]=a.useState(null),[u,h]=a.useState(!1),[f,x]=a.useState(!1),[d,j]=a.useState({kind:"closed"}),l=a.useRef(0),{data:T,loaded:$,error:v}=qe(),A=(v==null?void 0:v.message)??null,g=new Map((T??[]).map(R=>[R.id,R])),S=c??A??p,k=async()=>{const R=++l.current;try{const D=await O.projects.list();if(R!==l.current)return;t(D),m(null)}catch(D){if(R!==l.current)return;m(D instanceof Error?D.message:String(D))}finally{R===l.current&&i(!0)}},P=async()=>{try{const R=await O.tasks.list();o(R),b(null)}catch(R){b(R instanceof Error?R.message:String(R))}};return a.useEffect(()=>{k(),P()},[]),e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 mb-6",children:[e.jsx("h1",{className:"text-xl sm:text-2xl font-bold",children:"Dashboard"}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{onClick:()=>h(!0),className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"+ 新建项目"}),e.jsx("button",{onClick:()=>x(!0),disabled:s.length===0,"aria-describedby":s.length===0?"create-task-hint":void 0,className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 disabled:bg-gray-300 disabled:cursor-not-allowed",children:"+ 新建 Task"}),s.length===0&&e.jsx("span",{id:"create-task-hint",className:"text-xs text-gray-500 self-center",children:"请先创建项目"})]})]}),S&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",S]}),r&&s.length===0&&!c&&e.jsx("div",{className:"text-gray-500 text-sm py-12 text-center border-2 border-dashed rounded",children:'还没有项目。点击右上角"+ 新建项目"开始。'}),s.map(R=>e.jsxs("div",{className:"mb-8",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 mb-4",children:[e.jsx("h2",{className:"text-lg font-semibold",children:R.id}),e.jsx("span",{className:"text-sm text-gray-500 break-words min-w-0",children:R.repo}),e.jsx(ee,{to:`/project/${R.id}`,className:"text-sm text-blue-600 hover:underline ml-auto",children:"Details"})]}),R.agent.flat().length===0?e.jsx("div",{className:"text-gray-400 text-sm py-6 text-center border border-dashed rounded",children:"还没有 Agent。进入 Details 添加。"}):e.jsx("div",{className:"grid grid-cols-1 xl:grid-cols-2 gap-4",children:R.agent.map((D,L)=>e.jsx(Qe,{group:D,projectId:R.id,agentsById:g,agentsLoaded:$,agentsError:!!v,tasks:n.filter(I=>I.projectId===R.id),onDeleted:()=>{k(),P()}},D.map(I=>I.id).join(":")||L))})]},R.id)),e.jsx(Ot,{open:u,onClose:()=>h(!1),onCreated:R=>{h(!1),k(),j({kind:"asking",projectId:R})}}),e.jsx(fe,{open:d.kind==="asking",onClose:()=>j({kind:"closed"}),title:"项目已创建",size:"sm",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("p",{className:"text-sm",children:"现在添加第一个 Agent,还是稍后再加?"}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:()=>j({kind:"closed"}),className:"px-4 py-2 border rounded text-sm hover:bg-gray-50",children:"稍后再加"}),e.jsx("button",{type:"button",onClick:()=>{d.kind==="asking"&&j({kind:"addingAgent",projectId:d.projectId})},className:"px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"继续添加 Agent"})]})]})}),d.kind==="addingAgent"&&e.jsx(Ue,{open:!0,projectId:d.projectId,onClose:()=>j({kind:"closed"}),onCreated:()=>{k()}}),e.jsx(Ee,{open:f,onClose:()=>x(!1),onCreated:()=>{P()}})]})}function We({tasks:s}){const t=ve();return s.length===0?e.jsx("div",{className:"text-gray-400 text-sm",children:"No tasks"}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left border-b text-xs text-gray-500",children:[e.jsx("th",{className:"py-2 pr-4 font-medium",children:"ID"}),e.jsx("th",{className:"py-2 pr-4 font-medium",children:"Title"}),e.jsx("th",{className:"py-2 pr-4 font-medium hidden sm:table-cell",children:"Agent"}),e.jsx("th",{className:"py-2 pr-4 font-medium",children:"Status"}),e.jsx("th",{className:"py-2 font-medium hidden sm:table-cell",children:"Round"})]})}),e.jsx("tbody",{children:s.map(n=>e.jsxs("tr",{className:"border-b hover:bg-gray-50 cursor-pointer",onClick:()=>t(`/task/${n.id}`),children:[e.jsx("td",{className:"py-2 pr-4 font-mono whitespace-nowrap",children:e.jsx(ee,{to:`/task/${n.id}`,className:"text-blue-600 hover:underline",onClick:o=>o.stopPropagation(),children:n.id})}),e.jsx("td",{className:"py-2 pr-4 break-words",children:n.title}),e.jsx("td",{className:"py-2 pr-4 font-mono text-xs hidden sm:table-cell",children:n.agentId?n.agentId:n.preferredAgentId?e.jsx("span",{className:"italic text-gray-500",children:n.preferredAgentId}):"-"}),e.jsxs("td",{className:"py-2 pr-4 whitespace-nowrap",children:[e.jsx("span",{className:"text-xs px-2 py-0.5 rounded bg-gray-100",children:n.status}),n.phase==="spec"&&e.jsx("span",{className:"ml-1 text-xs px-2 py-0.5 rounded bg-indigo-100 text-indigo-800",children:"spec"})]}),e.jsx("td",{className:"py-2 text-xs text-gray-500 hidden sm:table-cell",children:n.phase==="spec"?n.specReviewRound??0:n.reviewRound})]},n.id))})]})})}function Wt(){const{id:s}=Se(),[t,n]=a.useState(null),[o,r]=a.useState(null),[i,c]=a.useState(!1),[m,p]=a.useState(!1),b=a.useRef(0),{data:u,loaded:h,error:f}=qe(),{data:x,error:d}=Ut(s),j=(f==null?void 0:f.message)??null,l=(d==null?void 0:d.message)??null,T=x??[],$=new Map((u??[]).map(g=>[g.id,g])),v=o??j??l,A=a.useCallback(async g=>{const S=++b.current;try{const k=await O.projects.get(g);if(S!==b.current)return;n(k),r(null)}catch(k){if(S!==b.current)return;r(k instanceof Error?k.message:String(k))}},[]);return a.useEffect(()=>{s&&(n(null),r(null),A(s))},[s,A]),t?e.jsxs("div",{children:[v&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",v]}),e.jsx("h1",{className:"text-xl sm:text-2xl font-bold mb-2 break-words",children:t.id}),e.jsx("p",{className:"text-gray-500 mb-6 break-words",children:t.repo}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Agents"}),e.jsx("button",{onClick:()=>c(!0),className:"px-3 py-1.5 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"+ 添加 Agent"})]}),t.agent.flat().length===0?e.jsx("div",{className:"text-gray-400 text-sm py-6 text-center border border-dashed rounded mb-8",children:"还没有 Agent,点击右上角添加。"}):e.jsx("div",{className:"space-y-5 mb-8",children:t.agent.map((g,S)=>e.jsx(Qe,{group:g,projectId:t.id,agentsById:$,agentsLoaded:h,agentsError:!!f,tasks:T,onDeleted:()=>{A(t.id)},terminalMode:"embedded-full"},g.map(k=>k.id).join(":")||S))}),e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 mb-3",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Tasks"}),e.jsx("button",{onClick:()=>p(!0),className:"px-3 py-1.5 bg-blue-600 text-white rounded text-sm hover:bg-blue-700",children:"+ 新建 Task"})]}),e.jsx(We,{tasks:T}),e.jsx(Ue,{open:i,projectId:t.id,onClose:()=>c(!1),onCreated:()=>{A(t.id)}}),e.jsx(Ee,{open:m,projectId:t.id,onClose:()=>p(!1)})]}):o?e.jsxs("div",{className:"text-red-600",children:["Error: ",o]}):e.jsx("div",{children:"Loading..."})}function Gt(){const{agentId:s}=Se();return s?e.jsxs("div",{className:"flex-1 min-h-0 flex flex-col border border-zinc-800 bg-[#e1e2e7] shadow-sm",children:[e.jsx("div",{className:"flex items-center gap-3 h-8 px-3 bg-zinc-900 border-b border-zinc-800 text-[11px] font-mono select-none",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"h-2 w-2 rounded-full bg-emerald-500","aria-hidden":!0}),e.jsx("span",{className:"text-zinc-200",children:s})]})}),e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(je,{agentId:s,mode:"full",interactive:!0})})]}):e.jsx("div",{children:"No agent specified"})}function Bt(){const[s,t]=a.useState([]),[n,o]=a.useState(null);return a.useEffect(()=>{let r=!1;return(async()=>{try{const i=await O.tasks.list();r||t(i)}catch(i){r||o(i instanceof Error?i.message:String(i))}})(),()=>{r=!0}},[]),e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl sm:text-2xl font-bold mb-6",children:"Tasks"}),n&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",n]}),e.jsx(We,{tasks:s})]})}const Ge=new Set(["merged","failed","max_rounds","cancelled"]),Le=Ge,Ht={pending:"bg-gray-200 text-gray-800",in_progress:"bg-blue-200 text-blue-800",review:"bg-purple-200 text-purple-800",fixing:"bg-orange-200 text-orange-800",approved:"bg-green-100 text-green-800",merged:"bg-green-300 text-green-900",failed:"bg-red-200 text-red-800",max_rounds:"bg-red-200 text-red-800",cancelled:"bg-gray-400 text-gray-100"};function Jt(){const{id:s}=Se(),t=ve(),{show:n}=le(),[o,r]=a.useState(!1),[i,c]=a.useState(!1),[m,p]=a.useState(!1),[b,u]=a.useState(!1),[h,f]=a.useState(null),{data:x,loaded:d,error:j}=Qt(s??""),l=h??x,T=(j==null?void 0:j.message)??null;a.useEffect(()=>{f(null)},[s]),a.useEffect(()=>{h&&x&&x.updatedAt>=h.updatedAt&&f(null)},[h,x]);const $=I=>{f(I)};if(!s)return e.jsx("div",{className:"text-red-600",children:"Task ID required"});if(T&&!l)return e.jsxs("div",{className:"text-red-600",children:["Error: ",T]});if(d&&!l)return e.jsxs("div",{className:"text-red-600",children:["Task not found: ",s]});if(!l)return e.jsx("div",{children:"Loading..."});const v=l.status==="pending",A=l.status==="pending"||l.status==="in_progress",g=Le.has(l.status)&&!!l.preferredAgentId,S=!!l.prNumber,k=l.preferredAgentId==="",P=l.status==="approved"&&l.prNumber!==void 0,R=async()=>{if(confirm(`确定取消 task ${l.id}?`)){c(!0);try{const I=await O.tasks.update(l.id,{status:"cancelled"});$(I),n({kind:"success",title:"任务已取消"})}catch(I){n({kind:"error",title:"取消失败",body:I instanceof Error?I.message:String(I)})}finally{c(!1)}}},D=async()=>{const F=Ge.has(l.status)?`task ${l.id} 已是 ${l.status} 状态。手动请 QA 重审会再跑一轮 review,但状态机不会把 QA 结果带回主流程。继续?`:`请 QA 重审 task ${l.id}?这会让 QA agent 立即开始新一轮 review(reviewRound +1)。`;if(confirm(F)){u(!0);try{const Q=await O.tasks.review(l.id);$(Q),n({kind:"success",title:`已派 QA 重审 (round ${Q.reviewRound})`})}catch(Q){n({kind:"error",title:"Review 派发失败",body:Q instanceof Error?Q.message:String(Q)})}finally{u(!1)}}},L=async()=>{const I=l.status==="merged"?`task ${l.id} 已 merged。Retry 会用同样的标题/描述新建一个 task 从头跑,确定继续?`:`Retry task ${l.id}?这会新建一个 task 从头开始,旧 task 保留为历史。`;if(confirm(I)){p(!0);try{const F=await O.tasks.retry(l.id);n({kind:"success",title:`已新建 task ${F.id}`}),t(`/task/${F.id}`)}catch(F){n({kind:"error",title:"Retry 失败",body:F instanceof Error?F.message:String(F)})}finally{p(!1)}}};return e.jsxs("div",{className:"max-w-4xl mx-auto",children:[T&&e.jsxs("div",{className:"mb-4 text-sm text-red-600",children:["Error: ",T]}),k&&e.jsx("div",{className:"mb-4 p-3 bg-amber-100 border-l-4 border-amber-500 text-amber-800 text-sm",children:l.status==="pending"?e.jsxs(e.Fragment,{children:["This task has no preferred dev (legacy). Click ",e.jsx("b",{children:"Edit"})," to assign one."]}):e.jsxs(e.Fragment,{children:["This is a legacy task with no preferred dev (read-only in status ",e.jsx("b",{children:l.status}),")."]})}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 mb-2",children:[e.jsx("span",{className:"font-mono text-sm font-bold",children:l.id}),e.jsx("span",{className:`px-2 py-1 rounded text-xs font-medium ${Ht[l.status]}`,children:l.status}),l.phase==="spec"&&e.jsx("span",{className:"px-2 py-1 rounded text-xs font-medium bg-indigo-100 text-indigo-800",children:"spec phase"}),e.jsxs("span",{className:"text-xs text-gray-500",children:["created ",l.createdAt]}),e.jsxs("span",{className:"text-xs text-gray-500",children:["updated ",l.updatedAt]})]}),e.jsx("h1",{className:"text-xl sm:text-2xl font-bold mb-4 break-words",children:l.title}),P&&e.jsxs("div",{className:"mb-4 rounded border border-green-200 bg-green-50 p-4 text-sm text-green-900",children:[e.jsx("div",{className:"font-semibold",children:"QA approved · awaiting PR merge"}),e.jsx("div",{className:"mt-1",children:"Dev keeps the task reserved while it checks whether all human or agent feedback has been handled."}),l.prUrl&&e.jsxs("a",{href:l.prUrl,target:"_blank",rel:"noopener noreferrer",className:"mt-3 inline-flex rounded border border-green-300 bg-white px-3 py-1.5 text-sm font-medium text-green-800 hover:bg-green-100",children:["Open PR #",l.prNumber]})]}),e.jsx("pre",{className:"whitespace-pre-wrap font-sans bg-gray-50 border rounded p-4 mb-6 text-sm",children:l.description}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-2 text-sm mb-6",children:[e.jsxs("div",{children:["Project: ",e.jsx("span",{className:"font-mono",children:l.projectId})]}),e.jsxs("div",{children:["Dev: ",e.jsx("span",{className:"font-mono",children:l.agentId||"-"})]}),e.jsxs("div",{children:["Preferred: ",e.jsx("span",{className:"font-mono",children:l.preferredAgentId||"-"})]}),e.jsxs("div",{children:["QA: ",e.jsx("span",{className:"font-mono",children:l.qaAgentId||"-"})]}),e.jsxs("div",{children:["PR:"," ",l.prNumber?l.prUrl?e.jsxs("a",{href:l.prUrl,target:"_blank",rel:"noopener noreferrer",className:"text-blue-600 hover:underline",children:["#",l.prNumber]}):e.jsxs("span",{children:["#",l.prNumber]}):e.jsx("span",{children:"-"})]}),e.jsxs("div",{children:["Branch: ",e.jsx("span",{className:"font-mono",children:l.branch||"-"})]}),e.jsxs("div",{children:["Round: ",l.reviewRound,l.specReviewRound!==void 0&&l.specReviewRound>0&&e.jsxs("span",{className:"ml-2 text-xs text-indigo-700",children:["spec: ",l.specReviewRound]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",disabled:!v,onClick:()=>r(!0),className:"px-4 py-2 border rounded text-sm hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed",children:"Edit"}),e.jsx("button",{type:"button",disabled:!A||i,onClick:R,className:"px-4 py-2 border border-red-300 text-red-700 rounded text-sm hover:bg-red-50 disabled:opacity-50 disabled:cursor-not-allowed",children:i?"Cancelling...":"Cancel"}),e.jsx("button",{type:"button",disabled:!g||m,onClick:L,title:Le.has(l.status)?k?"Legacy task has no preferred dev to retry against":"新建一个 task 从头跑,丢弃当前 worktree/branch":`Cannot retry in status ${l.status}`,className:"px-4 py-2 border border-blue-300 text-blue-700 rounded text-sm hover:bg-blue-50 disabled:opacity-50 disabled:cursor-not-allowed",children:m?"Retrying...":"Retry"}),e.jsx("button",{type:"button",disabled:!S||b,onClick:D,title:l.prNumber?"让 QA agent 立即开始新一轮 review(reviewRound +1)":"该 task 还没有 PR,无法派 review",className:"px-4 py-2 border border-purple-300 text-purple-700 rounded text-sm hover:bg-purple-50 disabled:opacity-50 disabled:cursor-not-allowed",children:b?"Dispatching...":"Request QA review"})]}),e.jsx(Ee,{mode:"edit",open:o,onClose:()=>r(!1),task:l,onUpdated:$})]})}function Vt(){const{phase:s,count:t,error:n,triggerRestart:o}=xe();return s==="idle"?null:s==="failed"?e.jsxs("div",{className:"bg-red-50 border-b border-red-200 px-4 py-2 flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm text-red-800",children:["❌ 重启失败:",n]}),e.jsx("button",{onClick:()=>{o()},className:"text-sm text-red-700 hover:underline font-medium",children:"重试"})]}):s==="restarting"?e.jsx("div",{className:"bg-blue-50 border-b border-blue-200 px-4 py-2 text-sm text-blue-800",children:"🔄 重启中…"}):e.jsxs("div",{className:"bg-amber-50 border-b border-amber-200 px-4 py-2 flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm text-amber-900",children:["⚠️ 有 ",t," 项配置变更待重启 baxian server 才生效"]}),e.jsx("button",{onClick:()=>{o()},className:"px-3 py-1 bg-amber-600 text-white text-sm rounded hover:bg-amber-700",children:"现在重启"})]})}function Kt(){return e.jsx(Xe,{children:e.jsxs("div",{className:"h-screen flex flex-col bg-gray-50",children:[e.jsxs("nav",{className:"bg-white border-b px-4 py-3 sm:px-6 flex flex-wrap items-center gap-x-4 gap-y-2 sm:gap-x-6 flex-none",children:[e.jsx(ee,{to:"/",className:"font-bold text-lg",children:"baxian"}),e.jsx(ee,{to:"/",className:"text-gray-600 hover:text-black",children:"Dashboard"}),e.jsx(ee,{to:"/tasks",className:"text-gray-600 hover:text-black",children:"Tasks"})]}),e.jsx(Vt,{}),e.jsx("main",{className:"flex-1 min-h-0 overflow-y-auto flex flex-col p-3 sm:p-6",children:e.jsxs(et,{children:[e.jsx(ae,{path:"/",element:e.jsx(qt,{})}),e.jsx(ae,{path:"/project/:id",element:e.jsx(Wt,{})}),e.jsx(ae,{path:"/terminal/:agentId",element:e.jsx(Gt,{})}),e.jsx(ae,{path:"/tasks",element:e.jsx(Bt,{})}),e.jsx(ae,{path:"/task/:id",element:e.jsx(Jt,{})})]})})]})})}function Yt({children:s}){const[t,n]=a.useState({kind:"probing"}),o=a.useRef(t);a.useEffect(()=>{o.current=t},[t]);const r=a.useCallback(async()=>{n({kind:"probing"});try{await O.config.get(),n({kind:"authorized"})}catch(i){if(i instanceof de&&i.status===401){n({kind:"unauthorized"});return}const c=i instanceof Error?i.message:"无法连接服务器";n({kind:"error",message:c})}},[]);return a.useEffect(()=>{r()},[r]),a.useEffect(()=>{const i=()=>{o.current.kind!=="probing"&&n({kind:"unauthorized",message:"登录已失效,请重新输入令牌"})};return window.addEventListener(ye,i),()=>window.removeEventListener(ye,i)},[]),t.kind==="authorized"?e.jsx(e.Fragment,{children:s}):t.kind==="error"?e.jsxs(we,{title:"无法连接服务器",children:[e.jsx("p",{className:"text-sm text-gray-600",children:t.message}),e.jsx("button",{type:"button",onClick:()=>{r()},className:"mt-4 w-full px-3 py-2 bg-blue-600 text-white text-sm font-medium rounded hover:bg-blue-700",children:"重试"})]}):t.kind==="probing"?e.jsx(we,{title:"加载中",children:e.jsx("p",{className:"text-sm text-gray-500",children:"正在检查登录状态…"})}):e.jsx(Zt,{message:t.message,onSubmit:async i=>{tt(i);try{await O.config.get(),n({kind:"authorized"})}catch(c){if(st(),c instanceof de&&c.status===401){n({kind:"unauthorized",message:"令牌无效,请重试"});return}const m=c instanceof Error?c.message:"登录失败";n({kind:"error",message:m})}}})}function we({title:s,children:t}){return e.jsx("div",{className:"min-h-screen flex items-center justify-center bg-gray-50 px-4",children:e.jsxs("div",{className:"w-full max-w-sm bg-white border rounded-lg shadow-sm px-6 py-6",children:[e.jsx("h1",{className:"text-lg font-semibold mb-3",children:s}),t]})})}function Zt({message:s,onSubmit:t}){const[n,o]=a.useState(""),[r,i]=a.useState(!1),[c,m]=a.useState(void 0),p=async u=>{u.preventDefault();const h=n.trim();if(!h){m("请输入访问令牌");return}m(void 0),i(!0);try{await t(h)}finally{i(!1)}},b=c??s;return e.jsxs(we,{title:"登录 baxian",children:[e.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"服务器开启了访问鉴权,请输入访问令牌继续。"}),e.jsxs("form",{onSubmit:u=>{p(u)},children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-1",htmlFor:"baxian-token",children:"访问令牌"}),e.jsx("input",{id:"baxian-token",type:"password",autoComplete:"current-password",autoFocus:!0,value:n,onChange:u=>o(u.target.value),className:"w-full px-3 py-2 border rounded text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"请输入服务器配置的 token",disabled:r}),b&&e.jsx("p",{role:"alert",className:"mt-2 text-sm text-red-600",children:b}),e.jsx("button",{type:"submit",disabled:r,className:"mt-4 w-full px-3 py-2 bg-blue-600 text-white text-sm font-medium rounded hover:bg-blue-700 disabled:opacity-60 disabled:cursor-not-allowed",children:r?"登录中…":"登录"})]})]})}Ke.createRoot(document.getElementById("root")).render(e.jsx(a.StrictMode,{children:e.jsx(mt,{children:e.jsx(lt,{children:e.jsx(Yt,{children:e.jsx(Kt,{})})})})}));
|