@coralai/sps-cli 0.51.0 → 0.51.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
|
|
2
|
+
Theme: GitHub
|
|
3
|
+
Description: Light theme as seen on github.com
|
|
4
|
+
Author: github.com
|
|
5
|
+
Maintainer: @Hirse
|
|
6
|
+
Updated: 2021-05-15
|
|
7
|
+
|
|
8
|
+
Outdated base version: https://github.com/primer/github-syntax-light
|
|
9
|
+
Current colors taken from GitHub's CSS
|
|
10
|
+
*/.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}/*! tailwindcss v4.2.4 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:"JetBrains Mono", "SF Mono", Monaco, Consolas, monospace;--color-black:#000;--spacing:.25rem;--container-md:28rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--font-weight-normal:400;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-normal:0em;--tracking-wider:.05em;--tracking-widest:.1em;--radius-md:12px;--radius-lg:16px;--radius-xl:20px;--radius-2xl:1rem;--shadow-sm:0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a;--shadow-lg:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bg:#fff;--color-bg-cream:#fff9f5;--color-text:#2d3748;--color-text-muted:#475569;--color-text-subtle:#64748b;--color-border-light:#e2e8f0;--color-primary:#fdbcb4;--color-secondary:#add8e6;--color-accent-mint:#98ff98;--color-accent-purple:#e6e6fa;--color-accent-yellow:#fff3b0;--color-accent-pink:#ffd1dc;--color-running:#166534;--color-running-bg:#d4f5e4;--color-stuck:#92400e;--color-stuck-bg:#ffe8cf;--color-crashed:#991b1b;--color-crashed-bg:#ffe4e6;--color-idle:#475569;--color-idle-bg:#f1f5f9;--color-cta:#22c55e;--font-heading:"Fredoka", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-body:"DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}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;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:before,:after{box-sizing:border-box}html{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{font-family:var(--font-body);color:var(--color-text);background:var(--color-bg-cream);min-height:100vh;font-size:15px;line-height:1.5}h1,h2,h3,h4,h5{font-family:var(--font-heading);color:var(--color-text);letter-spacing:-.01em;margin:0;font-weight:700}:focus-visible{outline:3px solid var(--color-text);outline-offset:2px}@media(prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important}}}@layer components{.nb-card{background:var(--color-bg);border:3px solid var(--color-text);box-shadow:5px 5px 0 var(--color-text);border-radius:16px;padding:16px}.nb-card-interactive{cursor:pointer;transition:transform .18s ease-out,box-shadow .18s ease-out}.nb-card-interactive:hover{box-shadow:7px 7px 0 var(--color-text);transform:translate(-2px,-2px)}.nb-card-interactive:active{box-shadow:3px 3px 0 var(--color-text);transform:translate(1px,1px)}.nb-btn{border:3px solid var(--color-text);font-family:var(--font-body);color:var(--color-text);background:var(--color-bg);box-shadow:3px 3px 0 var(--color-text);-webkit-user-select:none;user-select:none;cursor:pointer;border-radius:12px;align-items:center;gap:8px;padding:10px 18px;font-size:14px;font-weight:700;line-height:20px;transition:transform .12s ease-out,box-shadow .12s ease-out;display:inline-flex}.nb-btn:hover{box-shadow:4px 4px 0 var(--color-text);transform:translate(-1px,-1px)}.nb-btn:active{box-shadow:1px 1px 0 var(--color-text);transform:translate(2px,2px)}.nb-btn:disabled{opacity:.45;cursor:not-allowed;box-shadow:2px 2px 0 var(--color-text);transform:none}.nb-btn:disabled:hover{box-shadow:2px 2px 0 var(--color-text);transform:none}.nb-btn-primary{background:var(--color-cta)}.nb-btn-mint{background:var(--color-accent-mint)}.nb-btn-peach{background:var(--color-primary)}.nb-btn-blue{background:var(--color-secondary)}.nb-btn-yellow{background:var(--color-accent-yellow)}.nb-btn-purple{background:var(--color-accent-purple)}.nb-btn-danger{background:var(--color-crashed);color:#fff}.nb-input{border:3px solid var(--color-text);background:var(--color-bg);color:var(--color-text);font-family:var(--font-body);box-shadow:3px 3px 0 var(--color-text);border-radius:12px;padding:10px 16px;font-size:14px;font-weight:500;line-height:20px;transition:transform .12s,box-shadow .12s}.nb-input:focus{box-shadow:4px 4px 0 var(--color-text);outline:none;transform:translate(-1px,-1px)}.nb-badge{border:2px solid var(--color-text);font-family:var(--font-body);color:var(--color-text);background:var(--color-bg);border-radius:9999px;align-items:center;gap:4px;padding:4px 10px;font-size:12px;font-weight:700;line-height:16px;display:inline-flex}.nb-status{border:2px solid var(--color-text);font-family:var(--font-body);color:var(--color-text);border-radius:9999px;align-items:center;gap:5px;padding:4px 10px 4px 9px;font-size:11px;font-weight:700;line-height:16px;display:inline-flex}.nb-status:before{content:"";border:1.5px solid var(--color-text);background:currentColor;border-radius:50%;width:8px;height:8px}.prose-chat{color:var(--color-text);line-height:1.6}.prose-chat>:first-child{margin-top:0}.prose-chat>:last-child{margin-bottom:0}.prose-chat h1{font-family:var(--font-heading);margin:1em 0 .5em;font-size:1.5rem;font-weight:700}.prose-chat h2{font-family:var(--font-heading);margin:1em 0 .5em;font-size:1.25rem;font-weight:700}.prose-chat h3{font-family:var(--font-heading);margin:.8em 0 .4em;font-size:1.1rem;font-weight:700}.prose-chat h4,.prose-chat h5,.prose-chat h6{font-family:var(--font-heading);margin:.8em 0 .3em;font-weight:700}.prose-chat p{margin:.6em 0}.prose-chat ul,.prose-chat ol{margin:.6em 0;padding-left:1.6em}.prose-chat ul{list-style:outside}.prose-chat ol{list-style:decimal}.prose-chat li,.prose-chat li>ul,.prose-chat li>ol{margin:.2em 0}.prose-chat code{font-family:var(--font-mono);background:var(--color-bg-cream);border:1.5px solid var(--color-text);border-radius:4px;padding:0 4px;font-size:.9em}.prose-chat pre{background:var(--color-bg-cream);border:2px solid var(--color-text);font-family:var(--font-mono);border-radius:8px;margin:.8em 0;padding:12px;font-size:.85em;line-height:1.45;overflow-x:auto}.prose-chat pre code{font-size:inherit;background:0 0;border:0;padding:0}.prose-chat blockquote{border-left:3px solid var(--color-text);color:var(--color-text-muted);margin:.8em 0;padding-left:1em}.prose-chat table{border-collapse:collapse;border:2px solid var(--color-text);border-radius:8px;margin:.8em 0;overflow:hidden}.prose-chat th,.prose-chat td{border:1px solid var(--color-text);text-align:left;padding:6px 10px}.prose-chat th{background:var(--color-bg-cream);font-weight:700}.prose-chat a{color:var(--color-running);text-underline-offset:2px;text-decoration:underline}.prose-chat a:hover{color:var(--color-text)}.prose-chat hr{border:0;border-top:2px dashed var(--color-text);margin:1em 0}}@layer utilities{.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing) * 0)}.end{inset-inline-end:var(--spacing)}.top-1\/2{top:50%}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-3{right:calc(var(--spacing) * 3)}.left-0{left:calc(var(--spacing) * 0)}.left-3{left:calc(var(--spacing) * 3)}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.col-span-2{grid-column:span 2/span 2}.row-span-1{grid-row:span 1/span 1}.row-start-1{grid-row-start:1}.row-start-2{grid-row-start:2}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-12{margin-top:calc(var(--spacing) * 12)}.-mr-1{margin-right:calc(var(--spacing) * -1)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-10{height:calc(var(--spacing) * 10)}.h-20{height:calc(var(--spacing) * 20)}.h-\[calc\(100vh-140px\)\]{height:calc(100vh - 140px)}.h-full{height:100%}.h-screen{height:100vh}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[70vh\]{max-height:70vh}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-\[280px\]{min-height:280px}.w-2{width:calc(var(--spacing) * 2)}.w-2\/3{width:66.6667%}.w-3{width:calc(var(--spacing) * 3)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-32{width:calc(var(--spacing) * 32)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[130px\]{min-width:130px}.min-w-\[200px\]{min-width:200px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.list-disc{list-style-type:disc}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-\[100px_1fr\]{grid-template-columns:100px 1fr}.grid-cols-\[100px_60px_1fr\]{grid-template-columns:100px 60px 1fr}.grid-cols-\[100px_90px_60px_1fr\]{grid-template-columns:100px 90px 60px 1fr}.grid-cols-\[160px_1fr\]{grid-template-columns:160px 1fr}.grid-cols-\[220px_1fr\]{grid-template-columns:220px 1fr}.grid-cols-\[240px_1fr\]{grid-template-columns:240px 1fr}.grid-cols-\[260px_1fr\]{grid-template-columns:260px 1fr}.grid-cols-\[repeat\(auto-fill\,minmax\(280px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}.grid-rows-\[1fr_40px\]{grid-template-rows:1fr 40px}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}.gap-y-1{row-gap:calc(var(--spacing) * 1)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.gap-y-3{row-gap:calc(var(--spacing) * 3)}.self-end{align-self:flex-end}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-\[2px\]{border-style:var(--tw-border-style);border-width:2px}.border-\[3px\]{border-style:var(--tw-border-style);border-width:3px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-t-\[1\.5px\]{border-top-style:var(--tw-border-style);border-top-width:1.5px}.border-t-\[3px\]{border-top-style:var(--tw-border-style);border-top-width:3px}.border-r-\[3px\]{border-right-style:var(--tw-border-style);border-right-width:3px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[var\(--color-border-light\)\]{border-color:var(--color-border-light)}.border-\[var\(--color-cta\)\]{border-color:var(--color-cta)}.border-\[var\(--color-running\)\]{border-color:var(--color-running)}.border-\[var\(--color-stuck\)\]{border-color:var(--color-stuck)}.border-\[var\(--color-text\)\]{border-color:var(--color-text)}.border-transparent{border-color:#0000}.bg-\[var\(--color-accent-mint\)\]{background-color:var(--color-accent-mint)}.bg-\[var\(--color-accent-purple\)\]{background-color:var(--color-accent-purple)}.bg-\[var\(--color-accent-yellow\)\]{background-color:var(--color-accent-yellow)}.bg-\[var\(--color-bg\)\]{background-color:var(--color-bg)}.bg-\[var\(--color-bg-cream\)\]{background-color:var(--color-bg-cream)}.bg-\[var\(--color-border-light\)\]{background-color:var(--color-border-light)}.bg-\[var\(--color-crashed\)\]{background-color:var(--color-crashed)}.bg-\[var\(--color-crashed-bg\)\]{background-color:var(--color-crashed-bg)}.bg-\[var\(--color-cta\)\]{background-color:var(--color-cta)}.bg-\[var\(--color-primary\)\]{background-color:var(--color-primary)}.bg-\[var\(--color-running-bg\)\]{background-color:var(--color-running-bg)}.bg-\[var\(--color-secondary\)\]{background-color:var(--color-secondary)}.bg-\[var\(--color-stuck\)\]{background-color:var(--color-stuck)}.bg-\[var\(--color-stuck-bg\)\]{background-color:var(--color-stuck-bg)}.bg-\[var\(--color-text\)\]{background-color:var(--color-text)}.bg-\[var\(--color-text-subtle\)\]{background-color:var(--color-text-subtle)}.bg-black\/30{background-color:#0000004d}@supports (color:color-mix(in lab,red,red)){.bg-black\/30{background-color:color-mix(in oklab,var(--color-black) 30%,transparent)}}.p-0{padding:calc(var(--spacing) * 0)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-9{padding-right:calc(var(--spacing) * 9)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-9{padding-left:calc(var(--spacing) * 9)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.align-text-bottom{vertical-align:text-bottom}.font-\[family-name\:var\(--font-body\)\]{font-family:var(--font-body)}.font-\[family-name\:var\(--font-heading\)\]{font-family:var(--font-heading)}.font-\[family-name\:var\(--font-mono\)\],.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-\[22px\]{--tw-leading:22px;line-height:22px}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[var\(--color-bg\)\]{color:var(--color-bg)}.text-\[var\(--color-crashed\)\]{color:var(--color-crashed)}.text-\[var\(--color-running\)\]{color:var(--color-running)}.text-\[var\(--color-stuck\)\]{color:var(--color-stuck)}.text-\[var\(--color-text\)\]{color:var(--color-text)}.text-\[var\(--color-text-muted\)\]{color:var(--color-text-muted)}.text-\[var\(--color-text-subtle\)\]{color:var(--color-text-subtle)}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.decoration-2{text-decoration-thickness:2px}.accent-\[var\(--color-cta\)\]{accent-color:var(--color-cta)}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-80{opacity:.8}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[1px_1px_0_var\(--color-text\)\]{--tw-shadow:1px 1px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[2px_2px_0_var\(--color-text\)\]{--tw-shadow:2px 2px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[3px_3px_0_var\(--color-text\)\]{--tw-shadow:3px 3px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[4px_4px_0_var\(--color-cta\)\]{--tw-shadow:4px 4px 0 var(--tw-shadow-color,var(--color-cta));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[5px_5px_0_var\(--color-text\)\]{--tw-shadow:5px 5px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-nb{--tw-shadow:5px 5px 0 var(--tw-shadow-color,#2d3748);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-4{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-\[var\(--color-text\)\]{--tw-ring-color:var(--color-text)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);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,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[transform\,box-shadow\]{transition-property:transform,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-\[180ms\]{--tw-duration:.18s;transition-duration:.18s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}@media(hover:hover){.hover\:-translate-x-0\.5:hover{--tw-translate-x:calc(var(--spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:-translate-x-px:hover{--tw-translate-x:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:-translate-y-0\.5:hover{--tw-translate-y:calc(var(--spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:-translate-y-px:hover{--tw-translate-y:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:border-\[var\(--color-text\)\]:hover{border-color:var(--color-text)}.hover\:bg-\[var\(--color-accent-yellow\)\]:hover{background-color:var(--color-accent-yellow)}.hover\:bg-\[var\(--color-bg-cream\)\]:hover{background-color:var(--color-bg-cream)}.hover\:text-\[var\(--color-crashed\)\]:hover{color:var(--color-crashed)}.hover\:text-\[var\(--color-text\)\]:hover{color:var(--color-text)}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-\[3px_3px_0_var\(--color-text\)\]:hover{--tw-shadow:3px 3px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-\[4px_4px_0_var\(--color-text\)\]:hover{--tw-shadow:4px 4px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-\[5px_5px_0_var\(--color-text\)\]:hover{--tw-shadow:5px 5px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-\[var\(--color-text\)\]:focus-visible{--tw-ring-color:var(--color-text)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.active\:cursor-grabbing:active{cursor:grabbing}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:64rem){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:80rem){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|
|
@@ -332,7 +332,7 @@ Please change the parent <Route path="${_}"> to <Route path="${_==="/"?"*":`${_}
|
|
|
332
332
|
*
|
|
333
333
|
* This source code is licensed under the ISC license.
|
|
334
334
|
* See the LICENSE file in the root directory of this source tree.
|
|
335
|
-
*/const IA=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],zA=Me("zap",IA),BA=[{to:"/chat",label:"对话",icon:lA},{to:"/projects",label:"项目",icon:tA},{to:"/board",label:"看板",icon:JC},{to:"/workers",label:"Workers",icon:n1},{to:"/logs",label:"Logs",icon:qp},{to:"/skills",label:"Skills",icon:VC},{to:"/system",label:"系统",icon:JE}];function UA(){return m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"font-[family-name:var(--font-heading)] font-bold text-lg px-3 pt-2 pb-4 flex items-center gap-3 text-[var(--color-text)]",children:[m.jsx("span",{className:"w-5 h-5 rounded-md bg-[var(--color-accent-mint)] border-2 border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)]"}),"SPS Console"]}),m.jsx("nav",{className:"flex flex-col gap-1.5 mt-2","aria-label":"主导航",children:BA.map(e=>{const t=e.icon;return m.jsxs(KE,{to:e.to,className:({isActive:n})=>["flex items-center gap-3 px-3 py-2.5 rounded-xl font-semibold text-sm cursor-pointer transition-transform duration-150","border-2 border-transparent",n?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[3px_3px_0_var(--color-text)] font-bold":"text-[var(--color-text)] hover:bg-[var(--color-bg-cream)] hover:border-[var(--color-text)] hover:shadow-[3px_3px_0_var(--color-text)] hover:-translate-x-px hover:-translate-y-px"].join(" "),children:[m.jsx(t,{size:18,strokeWidth:2.5}),e.label]},e.to)})})]})}class FA extends Error{constructor(t,n,a){super(n),this.status=t,this.detail=a,this.name="ApiError"}}async function Ht(e){const t=await fetch(e,{headers:{Accept:"application/json"}});if(!t.ok){let n;try{n=await t.json()}catch{n=await t.text()}throw new FA(t.status,`${t.status} ${t.statusText}`,n)}return await t.json()}function r1(){return Ht("/api/system/info")}function $A(){return Ht("/api/system/env")}function PA(){return Ht("/api/system/env/raw")}async function qA(e,t){const n=await fetch("/api/system/env",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:e,etag:t})});if(!n.ok){const a=await n.text(),s=new Error(`${n.status}: ${a}`);throw s.status=n.status,s}return n.json()}function HA(){return Ht("/api/system/latest-version")}async function KA(){const e=await fetch("/api/system/upgrade",{method:"POST"});if(!e.ok&&e.status!==409)throw new Error(`${e.status}: ${await e.text()}`);return e.json()}async function GA(e,t=!1){const n=t?"?fix=1":"",a=await fetch(`/api/system/doctor/${encodeURIComponent(e)}${n}`,{method:"POST"});if(!a.ok)throw new Error(`${a.status}: ${await a.text()}`);return a.json()}function _r(){return Ht("/api/projects")}function QA(e){return Ht(`/api/projects/${encodeURIComponent(e)}`)}async function YA(e){const t=await fetch("/api/projects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok){const n=await t.text();throw new Error(`${t.status}: ${n}`)}return t.json()}function VA(e){return Ht(`/api/projects/${encodeURIComponent(e)}/conf`)}async function XA(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/conf`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:t,etag:n})});if(!a.ok){const s=await a.text(),o=new Error(`${a.status}: ${s}`);throw o.status=a.status,o}return a.json()}async function ZA(e,t={}){const n=await fetch(`/api/projects/${encodeURIComponent(e)}`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}return n.json()}function WA(e){return Ht(`/api/projects/${encodeURIComponent(e)}/pipelines`)}async function JA(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/pipeline`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({pipeline:t})});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}return n.json()}function e2(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`)}async function t2(e,t,n,a){const s=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:n,etag:a})});if(!s.ok){const o=await s.text(),c=new Error(`${s.status}: ${o}`);throw c.status=s.status,c}return s.json()}async function n2(e,t,n="blank"){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:t,template:n})});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}return a.json()}async function i2(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`,{method:"DELETE"});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}}function a2(){var f;const e=lt({queryKey:["system-info"],queryFn:r1,refetchInterval:3e4}),t=lt({queryKey:["projects"],queryFn:_r,refetchInterval:1e4}),n=s2(),a=!e.isError,s=((f=t.data)==null?void 0:f.data)??[],o=s.filter(d=>d.pipelineStatus==="running").length,c=s.reduce((d,h)=>d+h.workers.active,0);return m.jsxs("div",{className:"h-10 flex items-center gap-3 px-6 font-[family-name:var(--font-mono)] text-[11px] text-[var(--color-text-muted)]",children:[m.jsx("span",{className:"nb-status",style:{background:a?"var(--color-running-bg)":"var(--color-crashed-bg)",color:a?"var(--color-running)":"var(--color-crashed)",padding:"2px 8px 2px 7px"},children:a?"server":"offline"}),m.jsx(r2,{state:n}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{className:"flex items-center gap-1",title:"活跃 pipeline 数",children:[m.jsx(jf,{size:10,strokeWidth:2.5}),m.jsx("span",{className:"font-bold text-[var(--color-text)]",children:o})," pipeline"]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{className:"flex items-center gap-1",title:"活跃 worker 数",children:[m.jsx(ZE,{size:10,strokeWidth:2.5}),m.jsx("span",{className:"font-bold text-[var(--color-text)]",children:c})," worker"]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["localhost:",window.location.port]}),e.data&&m.jsxs(m.Fragment,{children:[m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["v",e.data.version]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["node ",e.data.nodeVersion]})]})]})}function r2({state:e}){return e==="open"?m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)",padding:"2px 8px 2px 7px"},children:"SSE"}):e==="connecting"?m.jsx("span",{className:"nb-status",style:{background:"var(--color-stuck-bg)",color:"var(--color-stuck)",padding:"2px 8px 2px 7px"},children:"SSE·connect"}):m.jsxs("span",{className:"nb-status",style:{background:"var(--color-crashed-bg)",color:"var(--color-crashed)",padding:"2px 8px 2px 7px"},children:[m.jsx(rc,{size:9,strokeWidth:2.5}),"SSE·down"]})}function s2(){const[e,t]=M.useState("connecting");return M.useEffect(()=>{let n=null,a=null,s=!1;const o=()=>{s||(n=new EventSource("/stream/heartbeat"),n.addEventListener("server.heartbeat",()=>t("open")),n.addEventListener("open",()=>t("open")),n.addEventListener("error",()=>{(n==null?void 0:n.readyState)===EventSource.CLOSED?(t("closed"),a==null&&(a=setTimeout(()=>{a=null,n==null||n.close(),o()},1e4))):t("connecting")}))};return o(),()=>{s=!0,a!=null&&clearTimeout(a),n==null||n.close()}},[]),e}function l2(){return m.jsxs("div",{className:"grid grid-cols-[240px_1fr] grid-rows-[1fr_40px] min-h-screen",children:[m.jsx("aside",{className:"row-span-1 row-start-1 border-r-[3px] border-[var(--color-text)] bg-[var(--color-bg)] p-4 flex flex-col",children:m.jsx(UA,{})}),m.jsx("main",{className:"row-start-1 overflow-auto p-6 flex flex-col gap-4",children:m.jsx(RT,{})}),m.jsx("footer",{className:"col-span-2 row-start-2 border-t-[3px] border-[var(--color-text)] bg-[var(--color-bg)]",children:m.jsx(a2,{})})]})}function rp(e,t){try{const n=JSON.stringify({message:(e instanceof Error?e.message:String(e)).slice(0,1e3),stack:(e instanceof Error?e.stack??"":"").slice(0,4e3),url:typeof window<"u"?window.location.href:"",ua:typeof navigator<"u"?navigator.userAgent:"",ts:new Date().toISOString(),context:t==null?void 0:t.slice(0,200)});fetch("/api/system/client-errors",{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0}).catch(()=>{})}catch{}}function o2(){typeof window>"u"||(window.addEventListener("error",e=>{rp(e.error??e.message??"unknown error","window.error")}),window.addEventListener("unhandledrejection",e=>{const t=e.reason;rp(t instanceof Error?t:String(t),"unhandledrejection")}))}class c2 extends M.Component{constructor(){super(...arguments);uv(this,"state",{error:null})}static getDerivedStateFromError(n){return{error:n}}componentDidCatch(n,a){var s;rp(n,`ErrorBoundary: ${((s=a.componentStack)==null?void 0:s.slice(0,200))??""}`),console.error("[ErrorBoundary]",n,a)}render(){return this.state.error?m.jsx("div",{className:"p-6",children:m.jsxs("div",{className:"nb-card max-w-2xl bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold mb-2",children:"💥 UI 崩了"}),m.jsx("p",{className:"text-sm mb-3 text-[var(--color-text-muted)]",children:this.state.error.message}),m.jsxs("details",{className:"text-xs mb-4",children:[m.jsx("summary",{className:"cursor-pointer font-semibold",children:"stack"}),m.jsx("pre",{className:"mt-2 font-[family-name:var(--font-mono)] overflow-auto max-h-60 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-md p-3",children:this.state.error.stack??"(no stack)"})]}),m.jsx("button",{className:"nb-btn nb-btn-mint",type:"button",onClick:()=>{this.setState({error:null}),window.location.reload()},children:"刷新页面"})]})}):this.props.children}}function u2(){const e=wr(),{data:t,isLoading:n,isError:a,error:s,refetch:o}=lt({queryKey:["projects"],queryFn:_r});return m.jsxs("div",{className:"flex flex-col gap-6 max-w-6xl",children:[m.jsxs("header",{className:"flex items-center justify-between",children:[m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"项目 🎯"}),m.jsx("p",{className:"text-[var(--color-text-muted)] text-sm mt-1",children:t?`${t.data.length} 个本机项目`:n?"加载中…":"点击刷新重试"})]}),m.jsxs("div",{className:"flex items-center gap-3",children:[m.jsxs("button",{className:"nb-btn nb-btn-yellow",onClick:()=>o(),type:"button",children:[m.jsx(jf,{size:16,strokeWidth:2.5}),"刷新"]}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:()=>e("/projects/new"),"aria-label":"新建项目",children:[m.jsx(Xi,{size:16,strokeWidth:3}),"新建项目"]})]})]}),n&&m.jsx(h2,{}),a&&m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:"加载失败"}),m.jsx("p",{className:"text-sm text-[var(--color-text)]",children:s instanceof Error?s.message:String(s)}),m.jsx("button",{className:"nb-btn mt-4",onClick:()=>o(),type:"button",children:"重试"})]}),t&&t.data.length===0&&m.jsx(m2,{}),t&&t.data.length>0&&m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:t.data.map(c=>m.jsx(f2,{project:c},c.name))})]})}function f2({project:e}){const t=e.pipelineStatus==="running";return m.jsxs(ds,{to:`/projects/${encodeURIComponent(e.name)}`,className:"nb-card nb-card-interactive block no-underline text-[var(--color-text)]",children:[m.jsxs("div",{className:"flex items-center justify-between mb-3",children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] font-bold text-xl truncate",children:e.name}),m.jsx(d2,{status:e.pipelineStatus})]}),e.repoDir&&m.jsx("p",{className:"text-xs font-[family-name:var(--font-mono)] text-[var(--color-text-muted)] truncate mb-3",children:e.repoDir}),m.jsxs("div",{className:"grid grid-cols-3 gap-2 text-sm mt-4 pt-3 border-t-[1.5px] border-dashed border-[var(--color-border-light)]",children:[m.jsx(fm,{label:"cards",value:e.cards.total,accent:"purple"}),m.jsx(fm,{label:"inprogress",value:e.cards.inprogress,accent:e.cards.inprogress>0?"yellow":"idle"}),m.jsx(fm,{label:"workers",value:`${e.workers.active}/${e.workers.total}`,accent:t?"mint":"idle"})]})]})}function fm({label:e,value:t,accent:n}){const a={purple:"var(--color-accent-purple)",yellow:"var(--color-accent-yellow)",mint:"var(--color-accent-mint)",idle:"var(--color-bg-cream)"};return m.jsxs("div",{className:"flex flex-col items-center justify-center py-2 rounded-lg border-2 border-[var(--color-text)]",style:{background:a[n]},children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold text-lg",children:t}),m.jsx("span",{className:"text-[10px] uppercase tracking-wider text-[var(--color-text-muted)] font-semibold",children:e})]})}function d2({status:e}){const t={running:{bg:"var(--color-running-bg)",label:"running"},idle:{bg:"var(--color-idle-bg)",label:"idle"},stopping:{bg:"var(--color-stuck-bg)",label:"stopping"},error:{bg:"var(--color-crashed-bg)",label:"error"}},{bg:n,label:a}=t[e],s=e==="running"?"var(--color-running)":e==="error"?"var(--color-crashed)":e==="stopping"?"var(--color-stuck)":"var(--color-idle)";return m.jsx("span",{className:"nb-status",style:{background:n,color:s},children:a})}function h2(){return m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:[0,1,2].map(e=>m.jsxs("div",{className:"nb-card opacity-60 animate-pulse",children:[m.jsx("div",{className:"h-6 w-32 bg-[var(--color-border-light)] rounded-md mb-3"}),m.jsx("div",{className:"h-3 w-full bg-[var(--color-border-light)] rounded-md mb-2"}),m.jsx("div",{className:"h-3 w-2/3 bg-[var(--color-border-light)] rounded-md"})]},e))})}function m2(){return m.jsxs("div",{className:"nb-card bg-[var(--color-accent-yellow)] flex items-center gap-6 p-8",children:[m.jsx("div",{className:"w-20 h-20 rounded-2xl bg-[var(--color-accent-mint)] border-[3px] border-[var(--color-text)] shadow-[3px_3px_0_var(--color-text)] flex items-center justify-center",children:m.jsx(n1,{size:32,strokeWidth:2.5})}),m.jsxs("div",{className:"flex-1",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold mb-2",children:"还没有项目 ✨"}),m.jsxs("p",{className:"text-sm text-[var(--color-text)] mb-4",children:["运行 ",m.jsx("code",{className:"bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-2 py-0.5 rounded-md font-[family-name:var(--font-mono)]",children:"sps project init <name>"})," 创建第一个项目。"]}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",children:[m.jsx(Xi,{size:16,strokeWidth:3}),"新建项目"]})]})]})}function p2({title:e,body:t,confirm:n,onConfirm:a,onCancel:s,danger:o}){return M.useEffect(()=>{const c=f=>{f.key==="Escape"&&s()};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[s]),m.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"confirm-title",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{id:"confirm-title",className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-5",children:t}),m.jsxs("div",{className:"flex gap-3 justify-end",children:[m.jsx("button",{className:"nb-btn",onClick:s,type:"button",children:"取消"}),m.jsx("button",{className:o?"nb-btn nb-btn-danger":"nb-btn nb-btn-yellow",onClick:async()=>{await a()},type:"button",children:n})]})]})})}const s1=M.createContext(null);function g2({children:e}){const[t,n]=M.useState(null),a=M.useCallback(c=>new Promise(f=>{n({kind:"confirm",opts:c,resolve:d=>{n(null),f(d)}})}),[]),s=M.useCallback(c=>new Promise(f=>{n({kind:"alert",opts:c,resolve:()=>{n(null),f()}})}),[]),o=M.useCallback(c=>new Promise(f=>{n({kind:"prompt",opts:c,resolve:d=>{n(null),f(d)}})}),[]);return m.jsxs(s1.Provider,{value:{confirm:a,alert:s,prompt:o},children:[e,(t==null?void 0:t.kind)==="confirm"&&m.jsx(p2,{title:t.opts.title,body:t.opts.body,confirm:t.opts.confirm??"确定",danger:t.opts.danger,onConfirm:()=>t.resolve(!0),onCancel:()=>t.resolve(!1)}),(t==null?void 0:t.kind)==="alert"&&m.jsx(b2,{title:t.opts.title,body:t.opts.body,confirm:t.opts.confirm??"知道了",onClose:()=>t.resolve()}),(t==null?void 0:t.kind)==="prompt"&&m.jsx(y2,{title:t.opts.title,body:t.opts.body,placeholder:t.opts.placeholder,defaultValue:t.opts.defaultValue,confirm:t.opts.confirm??"确定",cancel:t.opts.cancel??"取消",onConfirm:c=>t.resolve(c),onCancel:()=>t.resolve(null)})]})}function si(){const e=M.useContext(s1);if(!e)throw new Error("useDialog must be used inside <DialogProvider>");return e}function b2({title:e,body:t,confirm:n,onClose:a}){return M.useEffect(()=>{const s=o=>{(o.key==="Escape"||o.key==="Enter")&&a()};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[a]),m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-5 whitespace-pre-wrap break-words",children:t}),m.jsx("div",{className:"flex gap-3 justify-end",children:m.jsx("button",{className:"nb-btn nb-btn-primary",onClick:a,type:"button",autoFocus:!0,children:n})})]})})}function y2({title:e,body:t,placeholder:n,defaultValue:a,confirm:s,cancel:o,onConfirm:c,onCancel:f}){const[d,h]=M.useState(a??""),y=M.useRef(null);M.useEffect(()=>{var v,S;(v=y.current)==null||v.focus(),(S=y.current)==null||S.select();const x=w=>{w.key==="Escape"&&f()};return window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)},[f]);const g=()=>{const x=d.trim();x&&c(x)};return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),t&&m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-3 whitespace-pre-wrap break-words",children:t}),m.jsx("input",{ref:y,type:"text",className:"nb-input w-full mb-5",placeholder:n,value:d,onChange:x=>h(x.target.value),onKeyDown:x=>{x.key==="Enter"&&!x.nativeEvent.isComposing&&(x.preventDefault(),g())}}),m.jsxs("div",{className:"flex gap-3 justify-end",children:[m.jsx("button",{className:"nb-btn",onClick:f,type:"button",children:o}),m.jsx("button",{className:"nb-btn nb-btn-primary",onClick:g,type:"button",disabled:!d.trim(),children:s})]})]})})}function x2(){const e=wr(),t=qn(),{alert:n}=si(),[a,s]=M.useState({name:"",projectDir:"",enableGit:!0,mergeBranch:"main",maxWorkers:"1",ackTimeoutMin:"5"}),o=Pn({mutationFn:d=>YA(d),onSuccess:d=>{t.invalidateQueries({queryKey:["projects"]}),e(`/projects/${encodeURIComponent(d.name)}`)},onError:d=>{n({title:"创建失败",body:d instanceof Error?d.message:String(d)})}}),c=/^[a-zA-Z0-9_-]+$/.test(a.name),f=c&&a.projectDir.trim()!==""&&!o.isPending;return m.jsxs("div",{className:"flex flex-col gap-5 max-w-2xl",children:[m.jsxs("header",{className:"flex items-center gap-3",children:[m.jsxs("button",{type:"button",onClick:()=>e("/projects"),className:"nb-btn",style:{padding:"6px 12px"},"aria-label":"返回项目列表",children:[m.jsx(VE,{size:14,strokeWidth:3}),"返回"]}),m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-3xl font-bold",children:"新建项目"})]}),m.jsx("div",{className:"nb-card",children:m.jsxs("form",{onSubmit:d=>{d.preventDefault(),f&&o.mutate(a)},className:"flex flex-col gap-5",children:[m.jsxs(rr,{label:"项目名",hint:"只能用字母、数字、下划线、连字符。例如 acme-web",children:[m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"例如: acme-web",value:a.name,onChange:d=>s({...a,name:d.target.value}),autoFocus:!0,required:!0}),a.name&&!c&&m.jsx("p",{className:"text-xs text-[var(--color-crashed)] mt-1",children:"名称只能包含 a-z A-Z 0-9 _ -"})]}),m.jsx(rr,{label:"项目目录",hint:"本机绝对路径(代码或文档都可)。和是否启用 git 无关。",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"/home/coral/code/acme",value:a.projectDir,onChange:d=>s({...a,projectDir:d.target.value}),required:!0})}),m.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[m.jsx(rr,{label:"最大 Worker 数",children:m.jsx("input",{type:"number",min:"1",max:"8",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.maxWorkers,onChange:d=>s({...a,maxWorkers:d.target.value})})}),m.jsx(rr,{label:"ACK 超时(分钟)",hint:"Worker 启动后多久没 ACK 视为失败",children:m.jsx("input",{type:"number",min:"1",max:"30",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.ackTimeoutMin??"5",onChange:d=>s({...a,ackTimeoutMin:d.target.value})})})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsxs("label",{className:"flex items-center gap-3 mb-3 cursor-pointer select-none",children:[m.jsx("input",{type:"checkbox",checked:a.enableGit??!0,onChange:d=>s({...a,enableGit:d.target.checked}),className:"w-4 h-4 cursor-pointer"}),m.jsx("span",{className:"text-sm font-bold",children:"启用 Git(Worker 自动 commit + push)"})]}),m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] mb-3",children:"关闭后 Worker 只做任务、不做版本控制;适合文档/数据处理等非代码项目。"}),a.enableGit!==!1&&m.jsxs("div",{className:"flex flex-col gap-4 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4",children:[m.jsx(rr,{label:"合并分支",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.mergeBranch??"main",onChange:d=>s({...a,mergeBranch:d.target.value})})}),m.jsx(rr,{label:"Git 远程项目路径",hint:"如 user/repo,空则跳过远程 API(只本地 commit/push)",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"user/repo",value:a.gitlabProject??"",onChange:d=>s({...a,gitlabProject:d.target.value})})}),a.gitlabProject&&m.jsx(rr,{label:"GitLab 项目 ID",hint:"数字;GitHub 用户留空",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"42",value:a.gitlabProjectId??"",onChange:d=>s({...a,gitlabProjectId:d.target.value})})})]})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsxs("label",{className:"flex items-center gap-3 mb-3 cursor-pointer select-none",children:[m.jsx("input",{type:"checkbox",checked:a.enableWiki===!0,onChange:d=>s({...a,enableWiki:d.target.checked}),className:"w-4 h-4 cursor-pointer"}),m.jsx("span",{className:"text-sm font-bold",children:"启用 Wiki 知识库(per-project,doc-28)"})]}),m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)]",children:["开启后自动 scaffold ",m.jsx("code",{className:"font-mono",children:"wiki/"})," 目录,并向 Worker prompt 注入 5 层检索上下文与 wiki-update 提示。可后续 ",m.jsx("code",{className:"font-mono",children:"sps wiki init"})," 补办。"]})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-3 text-[var(--color-text-muted)]",children:"通知"}),m.jsx(rr,{label:"Matrix 房间 ID",hint:"空则使用全局配置;不填 = 不通知",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"!abc:matrix.example.com",value:a.matrixRoomId??"",onChange:d=>s({...a,matrixRoomId:d.target.value})})})]}),m.jsxs("div",{className:"flex gap-3 justify-end pt-3",children:[m.jsx("button",{type:"button",className:"nb-btn",onClick:()=>e("/projects"),disabled:o.isPending,children:"取消"}),m.jsx("button",{type:"submit",className:"nb-btn nb-btn-primary",disabled:!f,"aria-label":"创建项目",children:o.isPending?m.jsxs(m.Fragment,{children:[m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}),"创建中…"]}):m.jsxs(m.Fragment,{children:[m.jsx(Xi,{size:14,strokeWidth:3}),"创建"]})})]})]})})]})}function rr({label:e,hint:t,children:n}){return m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:e}),n,t&&m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:t})]})}const Gp=Symbol.for("yaml.alias"),sp=Symbol.for("yaml.document"),vr=Symbol.for("yaml.map"),l1=Symbol.for("yaml.pair"),Vi=Symbol.for("yaml.scalar"),zl=Symbol.for("yaml.seq"),Si=Symbol.for("yaml.node.type"),kr=e=>!!e&&typeof e=="object"&&e[Si]===Gp,hs=e=>!!e&&typeof e=="object"&&e[Si]===sp,Bl=e=>!!e&&typeof e=="object"&&e[Si]===vr,At=e=>!!e&&typeof e=="object"&&e[Si]===l1,vt=e=>!!e&&typeof e=="object"&&e[Si]===Vi,Ul=e=>!!e&&typeof e=="object"&&e[Si]===zl;function Mt(e){if(e&&typeof e=="object")switch(e[Si]){case vr:case zl:return!0}return!1}function jt(e){if(e&&typeof e=="object")switch(e[Si]){case Gp:case vr:case Vi:case zl:return!0}return!1}const o1=e=>(vt(e)||Mt(e))&&!!e.anchor,$n=Symbol("break visit"),c1=Symbol("skip children"),Yi=Symbol("remove node");function ms(e,t){const n=u1(t);hs(e)?cl(null,e.contents,n,Object.freeze([e]))===Yi&&(e.contents=null):cl(null,e,n,Object.freeze([]))}ms.BREAK=$n;ms.SKIP=c1;ms.REMOVE=Yi;function cl(e,t,n,a){const s=f1(e,t,n,a);if(jt(s)||At(s))return d1(e,a,s),cl(e,s,n,a);if(typeof s!="symbol"){if(Mt(t)){a=Object.freeze(a.concat(t));for(let o=0;o<t.items.length;++o){const c=cl(o,t.items[o],n,a);if(typeof c=="number")o=c-1;else{if(c===$n)return $n;c===Yi&&(t.items.splice(o,1),o-=1)}}}else if(At(t)){a=Object.freeze(a.concat(t));const o=cl("key",t.key,n,a);if(o===$n)return $n;o===Yi&&(t.key=null);const c=cl("value",t.value,n,a);if(c===$n)return $n;c===Yi&&(t.value=null)}}return s}async function Lf(e,t){const n=u1(t);hs(e)?await ul(null,e.contents,n,Object.freeze([e]))===Yi&&(e.contents=null):await ul(null,e,n,Object.freeze([]))}Lf.BREAK=$n;Lf.SKIP=c1;Lf.REMOVE=Yi;async function ul(e,t,n,a){const s=await f1(e,t,n,a);if(jt(s)||At(s))return d1(e,a,s),ul(e,s,n,a);if(typeof s!="symbol"){if(Mt(t)){a=Object.freeze(a.concat(t));for(let o=0;o<t.items.length;++o){const c=await ul(o,t.items[o],n,a);if(typeof c=="number")o=c-1;else{if(c===$n)return $n;c===Yi&&(t.items.splice(o,1),o-=1)}}}else if(At(t)){a=Object.freeze(a.concat(t));const o=await ul("key",t.key,n,a);if(o===$n)return $n;o===Yi&&(t.key=null);const c=await ul("value",t.value,n,a);if(c===$n)return $n;c===Yi&&(t.value=null)}}return s}function u1(e){return typeof e=="object"&&(e.Collection||e.Node||e.Value)?Object.assign({Alias:e.Node,Map:e.Node,Scalar:e.Node,Seq:e.Node},e.Value&&{Map:e.Value,Scalar:e.Value,Seq:e.Value},e.Collection&&{Map:e.Collection,Seq:e.Collection},e):e}function f1(e,t,n,a){var s,o,c,f,d;if(typeof n=="function")return n(e,t,a);if(Bl(t))return(s=n.Map)==null?void 0:s.call(n,e,t,a);if(Ul(t))return(o=n.Seq)==null?void 0:o.call(n,e,t,a);if(At(t))return(c=n.Pair)==null?void 0:c.call(n,e,t,a);if(vt(t))return(f=n.Scalar)==null?void 0:f.call(n,e,t,a);if(kr(t))return(d=n.Alias)==null?void 0:d.call(n,e,t,a)}function d1(e,t,n){const a=t[t.length-1];if(Mt(a))a.items[e]=n;else if(At(a))e==="key"?a.key=n:a.value=n;else if(hs(a))a.contents=n;else{const s=kr(a)?"alias":"scalar";throw new Error(`Cannot replace node with ${s} parent`)}}const v2={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},E2=e=>e.replace(/[!,[\]{}]/g,t=>v2[t]);class Nn{constructor(t,n){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},Nn.defaultYaml,t),this.tags=Object.assign({},Nn.defaultTags,n)}clone(){const t=new Nn(this.yaml,this.tags);return t.docStart=this.docStart,t}atDocument(){const t=new Nn(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:Nn.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},Nn.defaultTags);break}return t}add(t,n){this.atNextDocument&&(this.yaml={explicit:Nn.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},Nn.defaultTags),this.atNextDocument=!1);const a=t.trim().split(/[ \t]+/),s=a.shift();switch(s){case"%TAG":{if(a.length!==2&&(n(0,"%TAG directive should contain exactly two parts"),a.length<2))return!1;const[o,c]=a;return this.tags[o]=c,!0}case"%YAML":{if(this.yaml.explicit=!0,a.length!==1)return n(0,"%YAML directive should contain exactly one part"),!1;const[o]=a;if(o==="1.1"||o==="1.2")return this.yaml.version=o,!0;{const c=/^\d+\.\d+$/.test(o);return n(6,`Unsupported YAML version ${o}`,c),!1}}default:return n(0,`Unknown directive ${s}`,!0),!1}}tagName(t,n){if(t==="!")return"!";if(t[0]!=="!")return n(`Not a valid tag: ${t}`),null;if(t[1]==="<"){const c=t.slice(2,-1);return c==="!"||c==="!!"?(n(`Verbatim tags aren't resolved, so ${t} is invalid.`),null):(t[t.length-1]!==">"&&n("Verbatim tags must end with a >"),c)}const[,a,s]=t.match(/^(.*!)([^!]*)$/s);s||n(`The ${t} tag has no suffix`);const o=this.tags[a];if(o)try{return o+decodeURIComponent(s)}catch(c){return n(String(c)),null}return a==="!"?t:(n(`Could not resolve tag: ${t}`),null)}tagString(t){for(const[n,a]of Object.entries(this.tags))if(t.startsWith(a))return n+E2(t.substring(a.length));return t[0]==="!"?t:`!<${t}>`}toString(t){const n=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],a=Object.entries(this.tags);let s;if(t&&a.length>0&&jt(t.contents)){const o={};ms(t.contents,(c,f)=>{jt(f)&&f.tag&&(o[f.tag]=!0)}),s=Object.keys(o)}else s=[];for(const[o,c]of a)o==="!!"&&c==="tag:yaml.org,2002:"||(!t||s.some(f=>f.startsWith(c)))&&n.push(`%TAG ${o} ${c}`);return n.join(`
|
|
335
|
+
*/const IA=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],zA=Me("zap",IA),BA=[{to:"/chat",label:"对话",icon:lA},{to:"/projects",label:"项目",icon:tA},{to:"/board",label:"看板",icon:JC},{to:"/workers",label:"Workers",icon:n1},{to:"/logs",label:"Logs",icon:qp},{to:"/skills",label:"Skills",icon:VC},{to:"/system",label:"系统",icon:JE}];function UA(){return m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"font-[family-name:var(--font-heading)] font-bold text-lg px-3 pt-2 pb-4 flex items-center gap-3 text-[var(--color-text)]",children:[m.jsx("span",{className:"w-5 h-5 rounded-md bg-[var(--color-accent-mint)] border-2 border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)]"}),"SPS Console"]}),m.jsx("nav",{className:"flex flex-col gap-1.5 mt-2","aria-label":"主导航",children:BA.map(e=>{const t=e.icon;return m.jsxs(KE,{to:e.to,className:({isActive:n})=>["flex items-center gap-3 px-3 py-2.5 rounded-xl font-semibold text-sm cursor-pointer transition-transform duration-150","border-2 border-transparent",n?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[3px_3px_0_var(--color-text)] font-bold":"text-[var(--color-text)] hover:bg-[var(--color-bg-cream)] hover:border-[var(--color-text)] hover:shadow-[3px_3px_0_var(--color-text)] hover:-translate-x-px hover:-translate-y-px"].join(" "),children:[m.jsx(t,{size:18,strokeWidth:2.5}),e.label]},e.to)})})]})}class FA extends Error{constructor(t,n,a){super(n),this.status=t,this.detail=a,this.name="ApiError"}}async function Ht(e){const t=await fetch(e,{headers:{Accept:"application/json"}});if(!t.ok){let n;try{n=await t.json()}catch{n=await t.text()}throw new FA(t.status,`${t.status} ${t.statusText}`,n)}return await t.json()}function r1(){return Ht("/api/system/info")}function $A(){return Ht("/api/system/env")}function PA(){return Ht("/api/system/env/raw")}async function qA(e,t){const n=await fetch("/api/system/env",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:e,etag:t})});if(!n.ok){const a=await n.text(),s=new Error(`${n.status}: ${a}`);throw s.status=n.status,s}return n.json()}function HA(){return Ht("/api/system/latest-version")}async function KA(){const e=await fetch("/api/system/upgrade",{method:"POST"});if(!e.ok&&e.status!==409)throw new Error(`${e.status}: ${await e.text()}`);return e.json()}async function GA(e,t=!1){const n=t?"?fix=1":"",a=await fetch(`/api/system/doctor/${encodeURIComponent(e)}${n}`,{method:"POST"});if(!a.ok)throw new Error(`${a.status}: ${await a.text()}`);return a.json()}function _r(){return Ht("/api/projects")}function QA(e){return Ht(`/api/projects/${encodeURIComponent(e)}`)}async function YA(e){const t=await fetch("/api/projects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok){const n=await t.text();throw new Error(`${t.status}: ${n}`)}return t.json()}function VA(e){return Ht(`/api/projects/${encodeURIComponent(e)}/conf`)}async function XA(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/conf`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:t,etag:n})});if(!a.ok){const s=await a.text(),o=new Error(`${a.status}: ${s}`);throw o.status=a.status,o}return a.json()}async function ZA(e,t={}){const n=await fetch(`/api/projects/${encodeURIComponent(e)}`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}return n.json()}function WA(e){return Ht(`/api/projects/${encodeURIComponent(e)}/pipelines`)}async function JA(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/pipeline`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({pipeline:t})});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}return n.json()}function e2(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`)}async function t2(e,t,n,a){const s=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:n,etag:a})});if(!s.ok){const o=await s.text(),c=new Error(`${s.status}: ${o}`);throw c.status=s.status,c}return s.json()}async function n2(e,t,n="blank"){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:t,template:n})});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}return a.json()}async function i2(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/pipelines/${encodeURIComponent(t)}`,{method:"DELETE"});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}}function a2(){var f;const e=lt({queryKey:["system-info"],queryFn:r1,refetchInterval:3e4}),t=lt({queryKey:["projects"],queryFn:_r,refetchInterval:1e4}),n=s2(),a=!e.isError,s=((f=t.data)==null?void 0:f.data)??[],o=s.filter(d=>d.pipelineStatus==="running").length,c=s.reduce((d,h)=>d+h.workers.active,0);return m.jsxs("div",{className:"h-10 flex items-center gap-3 px-6 font-[family-name:var(--font-mono)] text-[11px] text-[var(--color-text-muted)]",children:[m.jsx("span",{className:"nb-status",style:{background:a?"var(--color-running-bg)":"var(--color-crashed-bg)",color:a?"var(--color-running)":"var(--color-crashed)",padding:"2px 8px 2px 7px"},children:a?"server":"offline"}),m.jsx(r2,{state:n}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{className:"flex items-center gap-1",title:"活跃 pipeline 数",children:[m.jsx(jf,{size:10,strokeWidth:2.5}),m.jsx("span",{className:"font-bold text-[var(--color-text)]",children:o})," pipeline"]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{className:"flex items-center gap-1",title:"活跃 worker 数",children:[m.jsx(ZE,{size:10,strokeWidth:2.5}),m.jsx("span",{className:"font-bold text-[var(--color-text)]",children:c})," worker"]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["localhost:",window.location.port]}),e.data&&m.jsxs(m.Fragment,{children:[m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["v",e.data.version]}),m.jsx("span",{className:"text-[var(--color-text-subtle)]",children:"·"}),m.jsxs("span",{children:["node ",e.data.nodeVersion]})]})]})}function r2({state:e}){return e==="open"?m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)",padding:"2px 8px 2px 7px"},children:"SSE"}):e==="connecting"?m.jsx("span",{className:"nb-status",style:{background:"var(--color-stuck-bg)",color:"var(--color-stuck)",padding:"2px 8px 2px 7px"},children:"SSE·connect"}):m.jsxs("span",{className:"nb-status",style:{background:"var(--color-crashed-bg)",color:"var(--color-crashed)",padding:"2px 8px 2px 7px"},children:[m.jsx(rc,{size:9,strokeWidth:2.5}),"SSE·down"]})}function s2(){const[e,t]=M.useState("connecting");return M.useEffect(()=>{let n=null,a=null,s=!1;const o=()=>{s||(n=new EventSource("/stream/heartbeat"),n.addEventListener("server.heartbeat",()=>t("open")),n.addEventListener("open",()=>t("open")),n.addEventListener("error",()=>{(n==null?void 0:n.readyState)===EventSource.CLOSED?(t("closed"),a==null&&(a=setTimeout(()=>{a=null,n==null||n.close(),o()},1e4))):t("connecting")}))};return o(),()=>{s=!0,a!=null&&clearTimeout(a),n==null||n.close()}},[]),e}function l2(){return m.jsxs("div",{className:"grid grid-cols-[240px_1fr] grid-rows-[1fr_40px] h-screen",children:[m.jsx("aside",{className:"row-span-1 row-start-1 border-r-[3px] border-[var(--color-text)] bg-[var(--color-bg)] p-4 flex flex-col",children:m.jsx(UA,{})}),m.jsx("main",{className:"row-start-1 overflow-auto p-6 flex flex-col gap-4",children:m.jsx(RT,{})}),m.jsx("footer",{className:"col-span-2 row-start-2 border-t-[3px] border-[var(--color-text)] bg-[var(--color-bg)]",children:m.jsx(a2,{})})]})}function rp(e,t){try{const n=JSON.stringify({message:(e instanceof Error?e.message:String(e)).slice(0,1e3),stack:(e instanceof Error?e.stack??"":"").slice(0,4e3),url:typeof window<"u"?window.location.href:"",ua:typeof navigator<"u"?navigator.userAgent:"",ts:new Date().toISOString(),context:t==null?void 0:t.slice(0,200)});fetch("/api/system/client-errors",{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0}).catch(()=>{})}catch{}}function o2(){typeof window>"u"||(window.addEventListener("error",e=>{rp(e.error??e.message??"unknown error","window.error")}),window.addEventListener("unhandledrejection",e=>{const t=e.reason;rp(t instanceof Error?t:String(t),"unhandledrejection")}))}class c2 extends M.Component{constructor(){super(...arguments);uv(this,"state",{error:null})}static getDerivedStateFromError(n){return{error:n}}componentDidCatch(n,a){var s;rp(n,`ErrorBoundary: ${((s=a.componentStack)==null?void 0:s.slice(0,200))??""}`),console.error("[ErrorBoundary]",n,a)}render(){return this.state.error?m.jsx("div",{className:"p-6",children:m.jsxs("div",{className:"nb-card max-w-2xl bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold mb-2",children:"💥 UI 崩了"}),m.jsx("p",{className:"text-sm mb-3 text-[var(--color-text-muted)]",children:this.state.error.message}),m.jsxs("details",{className:"text-xs mb-4",children:[m.jsx("summary",{className:"cursor-pointer font-semibold",children:"stack"}),m.jsx("pre",{className:"mt-2 font-[family-name:var(--font-mono)] overflow-auto max-h-60 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-md p-3",children:this.state.error.stack??"(no stack)"})]}),m.jsx("button",{className:"nb-btn nb-btn-mint",type:"button",onClick:()=>{this.setState({error:null}),window.location.reload()},children:"刷新页面"})]})}):this.props.children}}function u2(){const e=wr(),{data:t,isLoading:n,isError:a,error:s,refetch:o}=lt({queryKey:["projects"],queryFn:_r});return m.jsxs("div",{className:"flex flex-col gap-6 max-w-6xl",children:[m.jsxs("header",{className:"flex items-center justify-between",children:[m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"项目 🎯"}),m.jsx("p",{className:"text-[var(--color-text-muted)] text-sm mt-1",children:t?`${t.data.length} 个本机项目`:n?"加载中…":"点击刷新重试"})]}),m.jsxs("div",{className:"flex items-center gap-3",children:[m.jsxs("button",{className:"nb-btn nb-btn-yellow",onClick:()=>o(),type:"button",children:[m.jsx(jf,{size:16,strokeWidth:2.5}),"刷新"]}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:()=>e("/projects/new"),"aria-label":"新建项目",children:[m.jsx(Xi,{size:16,strokeWidth:3}),"新建项目"]})]})]}),n&&m.jsx(h2,{}),a&&m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:"加载失败"}),m.jsx("p",{className:"text-sm text-[var(--color-text)]",children:s instanceof Error?s.message:String(s)}),m.jsx("button",{className:"nb-btn mt-4",onClick:()=>o(),type:"button",children:"重试"})]}),t&&t.data.length===0&&m.jsx(m2,{}),t&&t.data.length>0&&m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:t.data.map(c=>m.jsx(f2,{project:c},c.name))})]})}function f2({project:e}){const t=e.pipelineStatus==="running";return m.jsxs(ds,{to:`/projects/${encodeURIComponent(e.name)}`,className:"nb-card nb-card-interactive block no-underline text-[var(--color-text)]",children:[m.jsxs("div",{className:"flex items-center justify-between mb-3",children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] font-bold text-xl truncate",children:e.name}),m.jsx(d2,{status:e.pipelineStatus})]}),e.repoDir&&m.jsx("p",{className:"text-xs font-[family-name:var(--font-mono)] text-[var(--color-text-muted)] truncate mb-3",children:e.repoDir}),m.jsxs("div",{className:"grid grid-cols-3 gap-2 text-sm mt-4 pt-3 border-t-[1.5px] border-dashed border-[var(--color-border-light)]",children:[m.jsx(fm,{label:"cards",value:e.cards.total,accent:"purple"}),m.jsx(fm,{label:"inprogress",value:e.cards.inprogress,accent:e.cards.inprogress>0?"yellow":"idle"}),m.jsx(fm,{label:"workers",value:`${e.workers.active}/${e.workers.total}`,accent:t?"mint":"idle"})]})]})}function fm({label:e,value:t,accent:n}){const a={purple:"var(--color-accent-purple)",yellow:"var(--color-accent-yellow)",mint:"var(--color-accent-mint)",idle:"var(--color-bg-cream)"};return m.jsxs("div",{className:"flex flex-col items-center justify-center py-2 rounded-lg border-2 border-[var(--color-text)]",style:{background:a[n]},children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold text-lg",children:t}),m.jsx("span",{className:"text-[10px] uppercase tracking-wider text-[var(--color-text-muted)] font-semibold",children:e})]})}function d2({status:e}){const t={running:{bg:"var(--color-running-bg)",label:"running"},idle:{bg:"var(--color-idle-bg)",label:"idle"},stopping:{bg:"var(--color-stuck-bg)",label:"stopping"},error:{bg:"var(--color-crashed-bg)",label:"error"}},{bg:n,label:a}=t[e],s=e==="running"?"var(--color-running)":e==="error"?"var(--color-crashed)":e==="stopping"?"var(--color-stuck)":"var(--color-idle)";return m.jsx("span",{className:"nb-status",style:{background:n,color:s},children:a})}function h2(){return m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:[0,1,2].map(e=>m.jsxs("div",{className:"nb-card opacity-60 animate-pulse",children:[m.jsx("div",{className:"h-6 w-32 bg-[var(--color-border-light)] rounded-md mb-3"}),m.jsx("div",{className:"h-3 w-full bg-[var(--color-border-light)] rounded-md mb-2"}),m.jsx("div",{className:"h-3 w-2/3 bg-[var(--color-border-light)] rounded-md"})]},e))})}function m2(){return m.jsxs("div",{className:"nb-card bg-[var(--color-accent-yellow)] flex items-center gap-6 p-8",children:[m.jsx("div",{className:"w-20 h-20 rounded-2xl bg-[var(--color-accent-mint)] border-[3px] border-[var(--color-text)] shadow-[3px_3px_0_var(--color-text)] flex items-center justify-center",children:m.jsx(n1,{size:32,strokeWidth:2.5})}),m.jsxs("div",{className:"flex-1",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold mb-2",children:"还没有项目 ✨"}),m.jsxs("p",{className:"text-sm text-[var(--color-text)] mb-4",children:["运行 ",m.jsx("code",{className:"bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-2 py-0.5 rounded-md font-[family-name:var(--font-mono)]",children:"sps project init <name>"})," 创建第一个项目。"]}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",children:[m.jsx(Xi,{size:16,strokeWidth:3}),"新建项目"]})]})]})}function p2({title:e,body:t,confirm:n,onConfirm:a,onCancel:s,danger:o}){return M.useEffect(()=>{const c=f=>{f.key==="Escape"&&s()};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[s]),m.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"confirm-title",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{id:"confirm-title",className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-5",children:t}),m.jsxs("div",{className:"flex gap-3 justify-end",children:[m.jsx("button",{className:"nb-btn",onClick:s,type:"button",children:"取消"}),m.jsx("button",{className:o?"nb-btn nb-btn-danger":"nb-btn nb-btn-yellow",onClick:async()=>{await a()},type:"button",children:n})]})]})})}const s1=M.createContext(null);function g2({children:e}){const[t,n]=M.useState(null),a=M.useCallback(c=>new Promise(f=>{n({kind:"confirm",opts:c,resolve:d=>{n(null),f(d)}})}),[]),s=M.useCallback(c=>new Promise(f=>{n({kind:"alert",opts:c,resolve:()=>{n(null),f()}})}),[]),o=M.useCallback(c=>new Promise(f=>{n({kind:"prompt",opts:c,resolve:d=>{n(null),f(d)}})}),[]);return m.jsxs(s1.Provider,{value:{confirm:a,alert:s,prompt:o},children:[e,(t==null?void 0:t.kind)==="confirm"&&m.jsx(p2,{title:t.opts.title,body:t.opts.body,confirm:t.opts.confirm??"确定",danger:t.opts.danger,onConfirm:()=>t.resolve(!0),onCancel:()=>t.resolve(!1)}),(t==null?void 0:t.kind)==="alert"&&m.jsx(b2,{title:t.opts.title,body:t.opts.body,confirm:t.opts.confirm??"知道了",onClose:()=>t.resolve()}),(t==null?void 0:t.kind)==="prompt"&&m.jsx(y2,{title:t.opts.title,body:t.opts.body,placeholder:t.opts.placeholder,defaultValue:t.opts.defaultValue,confirm:t.opts.confirm??"确定",cancel:t.opts.cancel??"取消",onConfirm:c=>t.resolve(c),onCancel:()=>t.resolve(null)})]})}function si(){const e=M.useContext(s1);if(!e)throw new Error("useDialog must be used inside <DialogProvider>");return e}function b2({title:e,body:t,confirm:n,onClose:a}){return M.useEffect(()=>{const s=o=>{(o.key==="Escape"||o.key==="Enter")&&a()};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[a]),m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-5 whitespace-pre-wrap break-words",children:t}),m.jsx("div",{className:"flex gap-3 justify-end",children:m.jsx("button",{className:"nb-btn nb-btn-primary",onClick:a,type:"button",autoFocus:!0,children:n})})]})})}function y2({title:e,body:t,placeholder:n,defaultValue:a,confirm:s,cancel:o,onConfirm:c,onCancel:f}){const[d,h]=M.useState(a??""),y=M.useRef(null);M.useEffect(()=>{var v,S;(v=y.current)==null||v.focus(),(S=y.current)==null||S.select();const x=w=>{w.key==="Escape"&&f()};return window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)},[f]);const g=()=>{const x=d.trim();x&&c(x)};return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-2",children:e}),t&&m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] mb-3 whitespace-pre-wrap break-words",children:t}),m.jsx("input",{ref:y,type:"text",className:"nb-input w-full mb-5",placeholder:n,value:d,onChange:x=>h(x.target.value),onKeyDown:x=>{x.key==="Enter"&&!x.nativeEvent.isComposing&&(x.preventDefault(),g())}}),m.jsxs("div",{className:"flex gap-3 justify-end",children:[m.jsx("button",{className:"nb-btn",onClick:f,type:"button",children:o}),m.jsx("button",{className:"nb-btn nb-btn-primary",onClick:g,type:"button",disabled:!d.trim(),children:s})]})]})})}function x2(){const e=wr(),t=qn(),{alert:n}=si(),[a,s]=M.useState({name:"",projectDir:"",enableGit:!0,mergeBranch:"main",maxWorkers:"1",ackTimeoutMin:"5"}),o=Pn({mutationFn:d=>YA(d),onSuccess:d=>{t.invalidateQueries({queryKey:["projects"]}),e(`/projects/${encodeURIComponent(d.name)}`)},onError:d=>{n({title:"创建失败",body:d instanceof Error?d.message:String(d)})}}),c=/^[a-zA-Z0-9_-]+$/.test(a.name),f=c&&a.projectDir.trim()!==""&&!o.isPending;return m.jsxs("div",{className:"flex flex-col gap-5 max-w-2xl",children:[m.jsxs("header",{className:"flex items-center gap-3",children:[m.jsxs("button",{type:"button",onClick:()=>e("/projects"),className:"nb-btn",style:{padding:"6px 12px"},"aria-label":"返回项目列表",children:[m.jsx(VE,{size:14,strokeWidth:3}),"返回"]}),m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-3xl font-bold",children:"新建项目"})]}),m.jsx("div",{className:"nb-card",children:m.jsxs("form",{onSubmit:d=>{d.preventDefault(),f&&o.mutate(a)},className:"flex flex-col gap-5",children:[m.jsxs(rr,{label:"项目名",hint:"只能用字母、数字、下划线、连字符。例如 acme-web",children:[m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"例如: acme-web",value:a.name,onChange:d=>s({...a,name:d.target.value}),autoFocus:!0,required:!0}),a.name&&!c&&m.jsx("p",{className:"text-xs text-[var(--color-crashed)] mt-1",children:"名称只能包含 a-z A-Z 0-9 _ -"})]}),m.jsx(rr,{label:"项目目录",hint:"本机绝对路径(代码或文档都可)。和是否启用 git 无关。",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"/home/coral/code/acme",value:a.projectDir,onChange:d=>s({...a,projectDir:d.target.value}),required:!0})}),m.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[m.jsx(rr,{label:"最大 Worker 数",children:m.jsx("input",{type:"number",min:"1",max:"8",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.maxWorkers,onChange:d=>s({...a,maxWorkers:d.target.value})})}),m.jsx(rr,{label:"ACK 超时(分钟)",hint:"Worker 启动后多久没 ACK 视为失败",children:m.jsx("input",{type:"number",min:"1",max:"30",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.ackTimeoutMin??"5",onChange:d=>s({...a,ackTimeoutMin:d.target.value})})})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsxs("label",{className:"flex items-center gap-3 mb-3 cursor-pointer select-none",children:[m.jsx("input",{type:"checkbox",checked:a.enableGit??!0,onChange:d=>s({...a,enableGit:d.target.checked}),className:"w-4 h-4 cursor-pointer"}),m.jsx("span",{className:"text-sm font-bold",children:"启用 Git(Worker 自动 commit + push)"})]}),m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] mb-3",children:"关闭后 Worker 只做任务、不做版本控制;适合文档/数据处理等非代码项目。"}),a.enableGit!==!1&&m.jsxs("div",{className:"flex flex-col gap-4 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4",children:[m.jsx(rr,{label:"合并分支",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:a.mergeBranch??"main",onChange:d=>s({...a,mergeBranch:d.target.value})})}),m.jsx(rr,{label:"Git 远程项目路径",hint:"如 user/repo,空则跳过远程 API(只本地 commit/push)",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"user/repo",value:a.gitlabProject??"",onChange:d=>s({...a,gitlabProject:d.target.value})})}),a.gitlabProject&&m.jsx(rr,{label:"GitLab 项目 ID",hint:"数字;GitHub 用户留空",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"42",value:a.gitlabProjectId??"",onChange:d=>s({...a,gitlabProjectId:d.target.value})})})]})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsxs("label",{className:"flex items-center gap-3 mb-3 cursor-pointer select-none",children:[m.jsx("input",{type:"checkbox",checked:a.enableWiki===!0,onChange:d=>s({...a,enableWiki:d.target.checked}),className:"w-4 h-4 cursor-pointer"}),m.jsx("span",{className:"text-sm font-bold",children:"启用 Wiki 知识库(per-project,doc-28)"})]}),m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)]",children:["开启后自动 scaffold ",m.jsx("code",{className:"font-mono",children:"wiki/"})," 目录,并向 Worker prompt 注入 5 层检索上下文与 wiki-update 提示。可后续 ",m.jsx("code",{className:"font-mono",children:"sps wiki init"})," 补办。"]})]}),m.jsxs("div",{className:"pt-3 border-t-2 border-[var(--color-text)] border-dashed",children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-3 text-[var(--color-text-muted)]",children:"通知"}),m.jsx(rr,{label:"Matrix 房间 ID",hint:"空则使用全局配置;不填 = 不通知",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"!abc:matrix.example.com",value:a.matrixRoomId??"",onChange:d=>s({...a,matrixRoomId:d.target.value})})})]}),m.jsxs("div",{className:"flex gap-3 justify-end pt-3",children:[m.jsx("button",{type:"button",className:"nb-btn",onClick:()=>e("/projects"),disabled:o.isPending,children:"取消"}),m.jsx("button",{type:"submit",className:"nb-btn nb-btn-primary",disabled:!f,"aria-label":"创建项目",children:o.isPending?m.jsxs(m.Fragment,{children:[m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}),"创建中…"]}):m.jsxs(m.Fragment,{children:[m.jsx(Xi,{size:14,strokeWidth:3}),"创建"]})})]})]})})]})}function rr({label:e,hint:t,children:n}){return m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:e}),n,t&&m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:t})]})}const Gp=Symbol.for("yaml.alias"),sp=Symbol.for("yaml.document"),vr=Symbol.for("yaml.map"),l1=Symbol.for("yaml.pair"),Vi=Symbol.for("yaml.scalar"),zl=Symbol.for("yaml.seq"),Si=Symbol.for("yaml.node.type"),kr=e=>!!e&&typeof e=="object"&&e[Si]===Gp,hs=e=>!!e&&typeof e=="object"&&e[Si]===sp,Bl=e=>!!e&&typeof e=="object"&&e[Si]===vr,At=e=>!!e&&typeof e=="object"&&e[Si]===l1,vt=e=>!!e&&typeof e=="object"&&e[Si]===Vi,Ul=e=>!!e&&typeof e=="object"&&e[Si]===zl;function Mt(e){if(e&&typeof e=="object")switch(e[Si]){case vr:case zl:return!0}return!1}function jt(e){if(e&&typeof e=="object")switch(e[Si]){case Gp:case vr:case Vi:case zl:return!0}return!1}const o1=e=>(vt(e)||Mt(e))&&!!e.anchor,$n=Symbol("break visit"),c1=Symbol("skip children"),Yi=Symbol("remove node");function ms(e,t){const n=u1(t);hs(e)?cl(null,e.contents,n,Object.freeze([e]))===Yi&&(e.contents=null):cl(null,e,n,Object.freeze([]))}ms.BREAK=$n;ms.SKIP=c1;ms.REMOVE=Yi;function cl(e,t,n,a){const s=f1(e,t,n,a);if(jt(s)||At(s))return d1(e,a,s),cl(e,s,n,a);if(typeof s!="symbol"){if(Mt(t)){a=Object.freeze(a.concat(t));for(let o=0;o<t.items.length;++o){const c=cl(o,t.items[o],n,a);if(typeof c=="number")o=c-1;else{if(c===$n)return $n;c===Yi&&(t.items.splice(o,1),o-=1)}}}else if(At(t)){a=Object.freeze(a.concat(t));const o=cl("key",t.key,n,a);if(o===$n)return $n;o===Yi&&(t.key=null);const c=cl("value",t.value,n,a);if(c===$n)return $n;c===Yi&&(t.value=null)}}return s}async function Lf(e,t){const n=u1(t);hs(e)?await ul(null,e.contents,n,Object.freeze([e]))===Yi&&(e.contents=null):await ul(null,e,n,Object.freeze([]))}Lf.BREAK=$n;Lf.SKIP=c1;Lf.REMOVE=Yi;async function ul(e,t,n,a){const s=await f1(e,t,n,a);if(jt(s)||At(s))return d1(e,a,s),ul(e,s,n,a);if(typeof s!="symbol"){if(Mt(t)){a=Object.freeze(a.concat(t));for(let o=0;o<t.items.length;++o){const c=await ul(o,t.items[o],n,a);if(typeof c=="number")o=c-1;else{if(c===$n)return $n;c===Yi&&(t.items.splice(o,1),o-=1)}}}else if(At(t)){a=Object.freeze(a.concat(t));const o=await ul("key",t.key,n,a);if(o===$n)return $n;o===Yi&&(t.key=null);const c=await ul("value",t.value,n,a);if(c===$n)return $n;c===Yi&&(t.value=null)}}return s}function u1(e){return typeof e=="object"&&(e.Collection||e.Node||e.Value)?Object.assign({Alias:e.Node,Map:e.Node,Scalar:e.Node,Seq:e.Node},e.Value&&{Map:e.Value,Scalar:e.Value,Seq:e.Value},e.Collection&&{Map:e.Collection,Seq:e.Collection},e):e}function f1(e,t,n,a){var s,o,c,f,d;if(typeof n=="function")return n(e,t,a);if(Bl(t))return(s=n.Map)==null?void 0:s.call(n,e,t,a);if(Ul(t))return(o=n.Seq)==null?void 0:o.call(n,e,t,a);if(At(t))return(c=n.Pair)==null?void 0:c.call(n,e,t,a);if(vt(t))return(f=n.Scalar)==null?void 0:f.call(n,e,t,a);if(kr(t))return(d=n.Alias)==null?void 0:d.call(n,e,t,a)}function d1(e,t,n){const a=t[t.length-1];if(Mt(a))a.items[e]=n;else if(At(a))e==="key"?a.key=n:a.value=n;else if(hs(a))a.contents=n;else{const s=kr(a)?"alias":"scalar";throw new Error(`Cannot replace node with ${s} parent`)}}const v2={"!":"%21",",":"%2C","[":"%5B","]":"%5D","{":"%7B","}":"%7D"},E2=e=>e.replace(/[!,[\]{}]/g,t=>v2[t]);class Nn{constructor(t,n){this.docStart=null,this.docEnd=!1,this.yaml=Object.assign({},Nn.defaultYaml,t),this.tags=Object.assign({},Nn.defaultTags,n)}clone(){const t=new Nn(this.yaml,this.tags);return t.docStart=this.docStart,t}atDocument(){const t=new Nn(this.yaml,this.tags);switch(this.yaml.version){case"1.1":this.atNextDocument=!0;break;case"1.2":this.atNextDocument=!1,this.yaml={explicit:Nn.defaultYaml.explicit,version:"1.2"},this.tags=Object.assign({},Nn.defaultTags);break}return t}add(t,n){this.atNextDocument&&(this.yaml={explicit:Nn.defaultYaml.explicit,version:"1.1"},this.tags=Object.assign({},Nn.defaultTags),this.atNextDocument=!1);const a=t.trim().split(/[ \t]+/),s=a.shift();switch(s){case"%TAG":{if(a.length!==2&&(n(0,"%TAG directive should contain exactly two parts"),a.length<2))return!1;const[o,c]=a;return this.tags[o]=c,!0}case"%YAML":{if(this.yaml.explicit=!0,a.length!==1)return n(0,"%YAML directive should contain exactly one part"),!1;const[o]=a;if(o==="1.1"||o==="1.2")return this.yaml.version=o,!0;{const c=/^\d+\.\d+$/.test(o);return n(6,`Unsupported YAML version ${o}`,c),!1}}default:return n(0,`Unknown directive ${s}`,!0),!1}}tagName(t,n){if(t==="!")return"!";if(t[0]!=="!")return n(`Not a valid tag: ${t}`),null;if(t[1]==="<"){const c=t.slice(2,-1);return c==="!"||c==="!!"?(n(`Verbatim tags aren't resolved, so ${t} is invalid.`),null):(t[t.length-1]!==">"&&n("Verbatim tags must end with a >"),c)}const[,a,s]=t.match(/^(.*!)([^!]*)$/s);s||n(`The ${t} tag has no suffix`);const o=this.tags[a];if(o)try{return o+decodeURIComponent(s)}catch(c){return n(String(c)),null}return a==="!"?t:(n(`Could not resolve tag: ${t}`),null)}tagString(t){for(const[n,a]of Object.entries(this.tags))if(t.startsWith(a))return n+E2(t.substring(a.length));return t[0]==="!"?t:`!<${t}>`}toString(t){const n=this.yaml.explicit?[`%YAML ${this.yaml.version||"1.2"}`]:[],a=Object.entries(this.tags);let s;if(t&&a.length>0&&jt(t.contents)){const o={};ms(t.contents,(c,f)=>{jt(f)&&f.tag&&(o[f.tag]=!0)}),s=Object.keys(o)}else s=[];for(const[o,c]of a)o==="!!"&&c==="tag:yaml.org,2002:"||(!t||s.some(f=>f.startsWith(c)))&&n.push(`%TAG ${o} ${c}`);return n.join(`
|
|
336
336
|
`)}}Nn.defaultYaml={explicit:!1,version:"1.2"};Nn.defaultTags={"!!":"tag:yaml.org,2002:"};function h1(e){if(/[\x00-\x19\s,[\]{}]/.test(e)){const n=`Anchor must not contain whitespace or control characters: ${JSON.stringify(e)}`;throw new Error(n)}return!0}function m1(e){const t=new Set;return ms(e,{Value(n,a){a.anchor&&t.add(a.anchor)}}),t}function p1(e,t){for(let n=1;;++n){const a=`${e}${n}`;if(!t.has(a))return a}}function S2(e,t){const n=[],a=new Map;let s=null;return{onAnchor:o=>{n.push(o),s??(s=m1(e));const c=p1(t,s);return s.add(c),c},setAnchors:()=>{for(const o of n){const c=a.get(o);if(typeof c=="object"&&c.anchor&&(vt(c.node)||Mt(c.node)))c.node.anchor=c.anchor;else{const f=new Error("Failed to resolve repeated object (this should not happen)");throw f.source=o,f}}},sourceObjects:a}}function fl(e,t,n,a){if(a&&typeof a=="object")if(Array.isArray(a))for(let s=0,o=a.length;s<o;++s){const c=a[s],f=fl(e,a,String(s),c);f===void 0?delete a[s]:f!==c&&(a[s]=f)}else if(a instanceof Map)for(const s of Array.from(a.keys())){const o=a.get(s),c=fl(e,a,s,o);c===void 0?a.delete(s):c!==o&&a.set(s,c)}else if(a instanceof Set)for(const s of Array.from(a)){const o=fl(e,a,s,s);o===void 0?a.delete(s):o!==s&&(a.delete(s),a.add(o))}else for(const[s,o]of Object.entries(a)){const c=fl(e,a,s,o);c===void 0?delete a[s]:c!==o&&(a[s]=c)}return e.call(t,n,a)}function vi(e,t,n){if(Array.isArray(e))return e.map((a,s)=>vi(a,String(s),n));if(e&&typeof e.toJSON=="function"){if(!n||!o1(e))return e.toJSON(t,n);const a={aliasCount:0,count:1,res:void 0};n.anchors.set(e,a),n.onCreate=o=>{a.res=o,delete n.onCreate};const s=e.toJSON(t,n);return n.onCreate&&n.onCreate(s),s}return typeof e=="bigint"&&!(n!=null&&n.keep)?Number(e):e}class Qp{constructor(t){Object.defineProperty(this,Si,{value:t})}clone(){const t=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return this.range&&(t.range=this.range.slice()),t}toJS(t,{mapAsMap:n,maxAliasCount:a,onAnchor:s,reviver:o}={}){if(!hs(t))throw new TypeError("A document argument is required");const c={anchors:new Map,doc:t,keep:!0,mapAsMap:n===!0,mapKeyWarned:!1,maxAliasCount:typeof a=="number"?a:100},f=vi(this,"",c);if(typeof s=="function")for(const{count:d,res:h}of c.anchors.values())s(h,d);return typeof o=="function"?fl(o,{"":f},"",f):f}}class If extends Qp{constructor(t){super(Gp),this.source=t,Object.defineProperty(this,"tag",{set(){throw new Error("Alias nodes cannot have tags")}})}resolve(t,n){let a;n!=null&&n.aliasResolveCache?a=n.aliasResolveCache:(a=[],ms(t,{Node:(o,c)=>{(kr(c)||o1(c))&&a.push(c)}}),n&&(n.aliasResolveCache=a));let s;for(const o of a){if(o===this)break;o.anchor===this.source&&(s=o)}return s}toJSON(t,n){if(!n)return{source:this.source};const{anchors:a,doc:s,maxAliasCount:o}=n,c=this.resolve(s,n);if(!c){const d=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new ReferenceError(d)}let f=a.get(c);if(f||(vi(c,null,n),f=a.get(c)),(f==null?void 0:f.res)===void 0){const d="This should not happen: Alias anchor was not resolved?";throw new ReferenceError(d)}if(o>=0&&(f.count+=1,f.aliasCount===0&&(f.aliasCount=uf(s,c,a)),f.count*f.aliasCount>o)){const d="Excessive alias count indicates a resource exhaustion attack";throw new ReferenceError(d)}return f.res}toString(t,n,a){const s=`*${this.source}`;if(t){if(h1(this.source),t.options.verifyAliasOrder&&!t.anchors.has(this.source)){const o=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw new Error(o)}if(t.implicitKey)return`${s} `}return s}}function uf(e,t,n){if(kr(t)){const a=t.resolve(e),s=n&&a&&n.get(a);return s?s.count*s.aliasCount:0}else if(Mt(t)){let a=0;for(const s of t.items){const o=uf(e,s,n);o>a&&(a=o)}return a}else if(At(t)){const a=uf(e,t.key,n),s=uf(e,t.value,n);return Math.max(a,s)}return 1}const g1=e=>!e||typeof e!="function"&&typeof e!="object";class ze extends Qp{constructor(t){super(Vi),this.value=t}toJSON(t,n){return n!=null&&n.keep?this.value:vi(this.value,t,n)}toString(){return String(this.value)}}ze.BLOCK_FOLDED="BLOCK_FOLDED";ze.BLOCK_LITERAL="BLOCK_LITERAL";ze.PLAIN="PLAIN";ze.QUOTE_DOUBLE="QUOTE_DOUBLE";ze.QUOTE_SINGLE="QUOTE_SINGLE";const w2="tag:yaml.org,2002:";function _2(e,t,n){if(t){const a=n.filter(o=>o.tag===t),s=a.find(o=>!o.format)??a[0];if(!s)throw new Error(`Tag ${t} not found`);return s}return n.find(a=>{var s;return((s=a.identify)==null?void 0:s.call(a,e))&&!a.format})}function sc(e,t,n){var g,x,v;if(hs(e)&&(e=e.contents),jt(e))return e;if(At(e)){const S=(x=(g=n.schema[vr]).createNode)==null?void 0:x.call(g,n.schema,null,n);return S.items.push(e),S}(e instanceof String||e instanceof Number||e instanceof Boolean||typeof BigInt<"u"&&e instanceof BigInt)&&(e=e.valueOf());const{aliasDuplicateObjects:a,onAnchor:s,onTagObj:o,schema:c,sourceObjects:f}=n;let d;if(a&&e&&typeof e=="object"){if(d=f.get(e),d)return d.anchor??(d.anchor=s(e)),new If(d.anchor);d={anchor:null,node:null},f.set(e,d)}t!=null&&t.startsWith("!!")&&(t=w2+t.slice(2));let h=_2(e,t,c.tags);if(!h){if(e&&typeof e.toJSON=="function"&&(e=e.toJSON()),!e||typeof e!="object"){const S=new ze(e);return d&&(d.node=S),S}h=e instanceof Map?c[vr]:Symbol.iterator in Object(e)?c[zl]:c[vr]}o&&(o(h),delete n.onTagObj);const y=h!=null&&h.createNode?h.createNode(n.schema,e,n):typeof((v=h==null?void 0:h.nodeClass)==null?void 0:v.from)=="function"?h.nodeClass.from(n.schema,e,n):new ze(e);return t?y.tag=t:h.default||(y.tag=h.tag),d&&(d.node=y),y}function vf(e,t,n){let a=n;for(let s=t.length-1;s>=0;--s){const o=t[s];if(typeof o=="number"&&Number.isInteger(o)&&o>=0){const c=[];c[o]=a,a=c}else a=new Map([[o,a]])}return sc(a,void 0,{aliasDuplicateObjects:!1,keepUndefined:!1,onAnchor:()=>{throw new Error("This should not happen, please report a bug.")},schema:e,sourceObjects:new Map})}const Zo=e=>e==null||typeof e=="object"&&!!e[Symbol.iterator]().next().done;class b1 extends Qp{constructor(t,n){super(t),Object.defineProperty(this,"schema",{value:n,configurable:!0,enumerable:!1,writable:!0})}clone(t){const n=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return t&&(n.schema=t),n.items=n.items.map(a=>jt(a)||At(a)?a.clone(t):a),this.range&&(n.range=this.range.slice()),n}addIn(t,n){if(Zo(t))this.add(n);else{const[a,...s]=t,o=this.get(a,!0);if(Mt(o))o.addIn(s,n);else if(o===void 0&&this.schema)this.set(a,vf(this.schema,s,n));else throw new Error(`Expected YAML collection at ${a}. Remaining path: ${s}`)}}deleteIn(t){const[n,...a]=t;if(a.length===0)return this.delete(n);const s=this.get(n,!0);if(Mt(s))return s.deleteIn(a);throw new Error(`Expected YAML collection at ${n}. Remaining path: ${a}`)}getIn(t,n){const[a,...s]=t,o=this.get(a,!0);return s.length===0?!n&&vt(o)?o.value:o:Mt(o)?o.getIn(s,n):void 0}hasAllNullValues(t){return this.items.every(n=>{if(!At(n))return!1;const a=n.value;return a==null||t&&vt(a)&&a.value==null&&!a.commentBefore&&!a.comment&&!a.tag})}hasIn(t){const[n,...a]=t;if(a.length===0)return this.has(n);const s=this.get(n,!0);return Mt(s)?s.hasIn(a):!1}setIn(t,n){const[a,...s]=t;if(s.length===0)this.set(a,n);else{const o=this.get(a,!0);if(Mt(o))o.setIn(s,n);else if(o===void 0&&this.schema)this.set(a,vf(this.schema,s,n));else throw new Error(`Expected YAML collection at ${a}. Remaining path: ${s}`)}}}const k2=e=>e.replace(/^(?!$)(?: $)?/gm,"#");function ka(e,t){return/^\n+$/.test(e)?e.substring(1):t?e.replace(/^(?! *$)/gm,t):e}const Zr=(e,t,n)=>e.endsWith(`
|
|
337
337
|
`)?ka(n,t):n.includes(`
|
|
338
338
|
`)?`
|
|
@@ -472,9 +472,9 @@ ${n.comment}`:n.comment}this.doc.range[2]=n.offset;break}default:this.errors.pus
|
|
|
472
472
|
`)+1;for(;n!==0;)this.onNewLine(this.offset+n),n=this.source.indexOf(`
|
|
473
473
|
`,n)+1}return{type:t,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue(t){switch(this.type){case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return this.flowScalar(this.type);case"block-scalar-header":return{type:"block-scalar",offset:this.offset,indent:this.indent,props:[this.sourceToken],source:""};case"flow-map-start":case"flow-seq-start":return{type:"flow-collection",offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case"seq-item-ind":return{type:"block-seq",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case"explicit-key-ind":{this.onKeyLine=!0;const n=Vu(t),a=il(n);return a.push(this.sourceToken),{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:a,explicitKey:!0}]}}case"map-value-ind":{this.onKeyLine=!0;const n=Vu(t),a=il(n);return{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:a,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment(t,n){return this.type!=="comment"||this.indent<=n?!1:t.every(a=>a.type==="newline"||a.type==="space")}*documentEnd(t){this.type!=="doc-mode"&&(t.end?t.end.push(this.sourceToken):t.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop()))}*lineEnd(t){switch(this.type){case"comma":case"doc-start":case"doc-end":case"flow-seq-end":case"flow-map-end":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;case"space":case"comment":default:t.end?t.end.push(this.sourceToken):t.end=[this.sourceToken],this.type==="newline"&&(yield*this.pop())}}}function tS(e){const t=e.prettyErrors!==!1;return{lineCounter:e.lineCounter||t&&new J1||null,prettyErrors:t}}function kO(e,t={}){const{lineCounter:n,prettyErrors:a}=tS(t),s=new sg(n==null?void 0:n.addNewLine),o=new rg(t),c=Array.from(o.compose(s.parse(e)));if(a&&n)for(const f of c)f.errors.forEach(Sf(e,n)),f.warnings.forEach(Sf(e,n));return c.length>0?c:Object.assign([],{empty:!0},o.streamInfo())}function nS(e,t={}){const{lineCounter:n,prettyErrors:a}=tS(t),s=new sg(n==null?void 0:n.addNewLine),o=new rg(t);let c=null;for(const f of o.compose(s.parse(e),!0,e.length))if(!c)c=f;else if(c.options.logLevel!=="silent"){c.errors.push(new Jr(f.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}return a&&n&&(c.errors.forEach(Sf(e,n)),c.warnings.forEach(Sf(e,n))),c}function NO(e,t,n){let a;typeof t=="function"?a=t:n===void 0&&t&&typeof t=="object"&&(n=t);const s=nS(e,n);if(!s)return null;if(s.warnings.forEach(o=>v1(s.options.logLevel,o)),s.errors.length>0){if(s.options.logLevel!=="silent")throw s.errors[0];s.errors=[]}return s.toJS(Object.assign({reviver:a},n))}function TO(e,t,n){let a=null;if(typeof t=="function"||Array.isArray(t)?a=t:n===void 0&&t&&(n=t),typeof n=="string"&&(n=n.length),typeof n=="number"){const s=Math.round(n);n=s<1?void 0:s>8?{indent:8}:{indent:s}}if(e===void 0){const{keepUndefined:s}=n??t??{};if(!s)return}return hs(e)&&!a?e.toString(n):new Pl(e,a,n).toString(n)}const Wv=Object.freeze(Object.defineProperty({__proto__:null,Alias:If,CST:SO,Composer:rg,Document:Pl,Lexer:W1,LineCounter:J1,Pair:gn,Parser:sg,Scalar:ze,Schema:U1,YAMLError:ig,YAMLMap:ii,YAMLParseError:Jr,YAMLSeq:Sr,YAMLWarning:$1,isAlias:kr,isCollection:Mt,isDocument:hs,isMap:Bl,isNode:jt,isPair:At,isScalar:vt,isSeq:Ul,parse:NO,parseAllDocuments:kO,parseDocument:nS,stringify:TO,visit:ms,visitAsync:Lf},Symbol.toStringTag,{value:"Module"}));function CO({projectName:e,file:t,onClose:n,onSaved:a}){const s=qn(),{alert:o}=si(),{data:c,isLoading:f,isError:d,error:h,refetch:y}=lt({queryKey:["pipeline-file",e,t],queryFn:()=>e2(e,t)}),[g,x]=M.useState("structured"),[v,S]=M.useState(null),[w,k]=M.useState(null);M.useEffect(()=>{c&&v===null&&(S(c.content),k(c.etag),c.parseError&&x("yaml"))},[c,v]),M.useEffect(()=>{const j=q=>{q.key==="Escape"&&n()};return window.addEventListener("keydown",j),()=>window.removeEventListener("keydown",j)},[n]);const _=Pn({mutationFn:()=>{if(v===null||w===null)throw new Error("no draft");return t2(e,t,v,w)},onSuccess:j=>{k(j.etag),s.invalidateQueries({queryKey:["pipeline-file",e,t]}),s.invalidateQueries({queryKey:["project-pipelines",e]}),a()},onError:j=>{const q=j.status;o({title:q===409?"文件已被其他地方修改":q===422?"YAML 语法错":"保存失败",body:j instanceof Error?j.message:String(j)})}}),A=v!==null&&c&&v!==c.content,{parsed:T,parseError:D}=M.useMemo(()=>{if(v===null)return{parsed:null,parseError:null};try{return{parsed:Wv.parse(v)??{},parseError:null}}catch(j){return{parsed:null,parseError:j instanceof Error?j.message:String(j)}}},[v]),$=j=>{try{const q=Wv.stringify(j,{lineWidth:0});S(q)}catch(q){o({title:"YAML 序列化失败",body:q instanceof Error?q.message:String(q)})}};return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-40 flex items-start justify-center p-6 bg-black/30 overflow-auto",children:m.jsxs("div",{className:"nb-card mt-8 w-full max-w-4xl flex flex-col",style:{maxHeight:"calc(100vh - 64px)"},children:[m.jsxs("header",{className:"flex items-start justify-between gap-3 mb-3 flex-shrink-0",children:[m.jsxs("div",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold flex items-center gap-2",children:[m.jsx(Fv,{size:20,strokeWidth:2.5}),m.jsx("code",{className:"font-[family-name:var(--font-mono)] text-lg",children:t}),(c==null?void 0:c.isActive)&&m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)",padding:"2px 8px"},children:"active"})]}),m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] mt-1",children:[e,"/pipelines/",t,w&&` · etag ${w}`]})]}),m.jsx("button",{className:"nb-btn nb-btn-mint p-2",onClick:n,type:"button","aria-label":"关闭",children:m.jsx(Er,{size:14,strokeWidth:3})})]}),f&&m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"}),d&&m.jsxs("p",{className:"text-[var(--color-crashed)]",children:["加载失败: ",h instanceof Error?h.message:String(h)]}),c&&v!==null&&m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"flex items-center gap-3 mb-3 flex-shrink-0 flex-wrap",children:[m.jsxs("div",{className:"flex gap-1 p-1 bg-[var(--color-bg)] border-[2px] border-[var(--color-text)] rounded-full shadow-[2px_2px_0_var(--color-text)]",children:[m.jsxs("button",{type:"button",onClick:()=>x("structured"),"aria-pressed":g==="structured",disabled:!!D,className:["px-3 py-1 rounded-full text-xs font-bold flex items-center gap-1.5",g==="structured"?"bg-[var(--color-primary)] text-[var(--color-text)] shadow-[1px_1px_0_var(--color-text)]":"text-[var(--color-text-muted)]",D?"opacity-50 cursor-not-allowed":""].join(" "),title:D??void 0,children:[m.jsx(qp,{size:11,strokeWidth:2.5}),"结构化"]}),m.jsxs("button",{type:"button",onClick:()=>x("yaml"),"aria-pressed":g==="yaml",className:["px-3 py-1 rounded-full text-xs font-bold flex items-center gap-1.5",g==="yaml"?"bg-[var(--color-primary)] text-[var(--color-text)] shadow-[1px_1px_0_var(--color-text)]":"text-[var(--color-text-muted)]"].join(" "),children:[m.jsx(Fv,{size:11,strokeWidth:2.5}),"原始 YAML"]})]}),D&&m.jsxs("div",{className:"flex items-center gap-1 text-xs text-[var(--color-crashed)] font-bold",children:[m.jsx(rc,{size:12,strokeWidth:2.5}),"YAML parse: ",D]}),(c==null?void 0:c.isActive)&&m.jsx("span",{className:"text-xs text-[var(--color-stuck)] font-bold ml-auto",children:"⚠ 这是当前激活的 pipeline,保存后下一轮 tick 生效"})]}),m.jsxs("div",{className:"flex-1 overflow-auto",children:[g==="structured"&&T&&m.jsx(AO,{parsed:T,onChange:$}),g==="yaml"&&m.jsx("textarea",{className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",style:{minHeight:400,resize:"vertical"},value:v,onChange:j=>S(j.target.value),spellCheck:!1,"aria-label":"pipeline YAML 编辑器"})]}),m.jsxs("div",{className:"flex items-center justify-between mt-3 pt-3 border-t-2 border-dashed border-[var(--color-text)] flex-shrink-0",children:[m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:A?m.jsx("span",{className:"text-[var(--color-stuck)] font-bold",children:"● 未保存"}):_.isSuccess?m.jsxs("span",{className:"text-[var(--color-running)] font-bold flex items-center gap-1",children:[m.jsx(Pp,{size:12,strokeWidth:2.5})," 已保存"]}):"无变化"}),m.jsxs("div",{className:"flex gap-2",children:[m.jsx("button",{className:"nb-btn",style:{padding:"6px 14px"},onClick:()=>{S(null),y()},disabled:_.isPending,type:"button",children:"重新加载"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",style:{padding:"6px 14px"},onClick:()=>_.mutate(),disabled:!A||_.isPending,type:"button","aria-label":"保存 pipeline",children:[_.isPending?m.jsx(Wt,{size:13,strokeWidth:3,className:"animate-spin"}):m.jsx(Df,{size:13,strokeWidth:3}),"保存"]})]})]})]})]})})}function AO({parsed:e,onChange:t}){const n=e.stages??[],a=d=>{t({...e,stages:d})},s=()=>{a([...n,{name:`stage-${n.length+1}`,on_complete:"move_card Done"}])},o=d=>{a(n.filter((h,y)=>y!==d))},c=(d,h)=>{const y=[...n],g=d+h;g<0||g>=y.length||([y[d],y[g]]=[y[g],y[d]],a(y))},f=(d,h)=>{a(n.map((y,g)=>g===d?{...y,...h}:y))};return m.jsxs("div",{className:"flex flex-col gap-4",children:[m.jsxs("div",{className:"flex items-center gap-3 p-3 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg",children:[m.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[m.jsx("span",{className:"font-bold",children:"mode:"}),m.jsxs("select",{className:"nb-input",style:{padding:"4px 10px",fontSize:12},value:e.mode??"project",onChange:d=>t({...e,mode:d.target.value}),children:[m.jsx("option",{value:"project",children:"project"}),m.jsx("option",{value:"steps",children:"steps"})]})]}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"project = 事件驱动流水线(默认) · steps = 顺序脚本"})]}),m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center justify-between mb-2",children:[m.jsxs("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider",children:["Stages (",n.length,")"]}),m.jsxs("button",{type:"button",className:"nb-btn nb-btn-mint",style:{padding:"4px 12px",fontSize:12},onClick:s,"aria-label":"添加 stage",children:[m.jsx(Xi,{size:11,strokeWidth:3})," 添加 stage"]})]}),n.length===0?m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] italic p-4 border-2 border-dashed border-[var(--color-text)] rounded-lg text-center",children:'还没 stage。点"添加 stage"开始。'}):m.jsx("div",{className:"flex flex-col gap-3",children:n.map((d,h)=>m.jsx(OO,{stage:d,index:h,total:n.length,onChange:y=>f(h,y),onRemove:()=>o(h),onMoveUp:()=>c(h,-1),onMoveDown:()=>c(h,1)},h))})]})]})}function OO({stage:e,index:t,total:n,onChange:a,onRemove:s,onMoveUp:o,onMoveDown:c}){const f=e.on_fail??{};return m.jsxs("div",{className:"nb-card bg-[var(--color-bg-cream)] p-4",children:[m.jsxs("div",{className:"flex items-center justify-between mb-3",children:[m.jsxs("h4",{className:"font-[family-name:var(--font-heading)] font-bold text-sm",children:["Stage #",t+1,e.name&&m.jsx("code",{className:"ml-2 text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-2 py-0.5 rounded",children:e.name})]}),m.jsxs("div",{className:"flex gap-1",children:[m.jsx("button",{type:"button",className:"nb-btn",style:{padding:"3px 8px"},onClick:o,disabled:t===0,"aria-label":"上移",children:m.jsx(kC,{size:12,strokeWidth:3})}),m.jsx("button",{type:"button",className:"nb-btn",style:{padding:"3px 8px"},onClick:c,disabled:t===n-1,"aria-label":"下移",children:m.jsx(yc,{size:12,strokeWidth:3})}),m.jsx("button",{type:"button",className:"nb-btn nb-btn-danger",style:{padding:"3px 8px"},onClick:s,"aria-label":"删除 stage",children:m.jsx(Il,{size:12,strokeWidth:3})})]})]}),m.jsxs("div",{className:"grid grid-cols-2 gap-3 text-sm",children:[m.jsx(sr,{label:"name",hint:"stage 唯一名",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.name??"",onChange:d=>a({name:d.target.value}),placeholder:"develop"})}),m.jsx(sr,{label:"profile",hint:"skill 画像,可空",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.profile??"",onChange:d=>a({profile:d.target.value||void 0}),placeholder:"fullstack"})}),m.jsx(sr,{label:"card_state",hint:"本 stage 期间卡片状态",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.card_state??"",onChange:d=>a({card_state:d.target.value||void 0}),placeholder:"Inprogress"})}),m.jsx(sr,{label:"timeout",hint:"可选,如 30m 2h",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.timeout??"",onChange:d=>a({timeout:d.target.value||void 0}),placeholder:"2h"})}),m.jsx(sr,{label:"trigger",hint:"触发条件,可空走默认",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.trigger??"",onChange:d=>a({trigger:d.target.value||void 0}),placeholder:"card_enters 'Todo'"})}),m.jsx(sr,{label:"on_complete",hint:"成功后动作",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:e.on_complete??"",onChange:d=>a({on_complete:d.target.value}),placeholder:"move_card Done"})})]}),m.jsxs("div",{className:"mt-4 pt-3 border-t-2 border-dashed border-[var(--color-text)]",children:[m.jsx("h5",{className:"text-xs font-bold uppercase tracking-wider mb-2 text-[var(--color-text-muted)]",children:"on_fail"}),m.jsxs("div",{className:"grid grid-cols-2 gap-3 text-sm",children:[m.jsx(sr,{label:"action",hint:"失败时动作,如 label NEEDS-FIX",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:f.action??"",onChange:d=>a({on_fail:{...f,action:d.target.value||void 0}}),placeholder:"label NEEDS-FIX"})}),m.jsx(sr,{label:"comment",hint:"写进卡片的注释",children:m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",value:f.comment??"",onChange:d=>a({on_fail:{...f,comment:d.target.value||void 0}}),placeholder:"Worker failed. Check logs."})})]}),m.jsxs("label",{className:"flex items-center gap-2 mt-3 text-sm cursor-pointer",children:[m.jsx("input",{type:"checkbox",checked:f.halt??!0,onChange:d=>a({on_fail:{...f,halt:d.target.checked}})}),m.jsx("span",{className:"font-bold",children:"halt"}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"(失败后停流水线;去掉则继续下一张卡)"})]})]})]})}function sr({label:e,hint:t,children:n}){return m.jsxs("label",{className:"flex flex-col gap-1",children:[m.jsx("span",{className:"text-xs font-bold font-[family-name:var(--font-mono)]",children:e}),n,t&&m.jsx("span",{className:"text-[10px] text-[var(--color-text-muted)]",children:t})]})}function RO({onCancel:e,onCreate:t,hasActive:n,hasSample:a,isPending:s}){const[o,c]=M.useState(""),[f,d]=M.useState("blank");M.useEffect(()=>{const v=S=>{S.key==="Escape"&&e()};return window.addEventListener("keydown",v),()=>window.removeEventListener("keydown",v)},[e]);const h=o.trim(),y=h.endsWith(".yaml")?h:h?`${h}.yaml`:"",g=y&&/^[a-zA-Z0-9_.-]+\.yaml$/.test(y),x=()=>{!g||s||t(y,f)};return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-50 flex items-center justify-center p-6 bg-black/30",children:m.jsxs("div",{className:"nb-card max-w-md w-full",children:[m.jsxs("header",{className:"flex items-start justify-between mb-4",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold",children:"新建 pipeline"}),m.jsx("button",{className:"nb-btn nb-btn-mint p-2",onClick:e,type:"button","aria-label":"关闭",children:m.jsx(Er,{size:14,strokeWidth:3})})]}),m.jsxs("form",{onSubmit:v=>{v.preventDefault(),x()},className:"flex flex-col gap-4",children:[m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:"文件名"}),m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",placeholder:"例如 ci",value:o,onChange:v=>c(v.target.value),autoFocus:!0}),m.jsxs("span",{className:"text-xs text-[var(--color-text-muted)]",children:["实际会保存为 ",m.jsx("code",{className:"font-[family-name:var(--font-mono)]",children:y||"xxx.yaml"}),"。 只允许 a-z A-Z 0-9 _ -;已有同名文件会 409 报错。"]})]}),m.jsxs("fieldset",{className:"flex flex-col gap-2",children:[m.jsx("legend",{className:"text-sm font-bold mb-1",children:"初始内容"}),m.jsx(xm,{value:"blank",current:f,label:"空白模板",desc:"最简 1 stage (develop → Done)",onSelect:d}),m.jsx(xm,{value:"sample",current:f,label:"教学模板",desc:"从 sample.yaml.example 复制(带注释,讲解所有字段)",onSelect:d,disabled:!a,disabledReason:"sample.yaml.example 不存在"}),m.jsx(xm,{value:"active",current:f,label:"复制当前活动的",desc:"从 project.yaml 复制(基于目前的配置改)",onSelect:d,disabled:!n,disabledReason:"project.yaml 不存在"})]}),m.jsxs("div",{className:"flex gap-3 justify-end pt-2",children:[m.jsx("button",{className:"nb-btn",onClick:e,type:"button",disabled:s,children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"submit",disabled:!g||s,"aria-label":"创建 pipeline",children:[s?m.jsx(Wt,{size:13,strokeWidth:3,className:"animate-spin"}):m.jsx(Xi,{size:13,strokeWidth:3}),"创建"]})]})]})]})})}function xm({value:e,current:t,label:n,desc:a,onSelect:s,disabled:o,disabledReason:c}){const f=t===e;return m.jsxs("label",{className:["flex items-start gap-2 p-2 rounded-lg border-2 cursor-pointer",o?"border-[var(--color-border-light)] opacity-50 cursor-not-allowed":f?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)]":"border-[var(--color-border-light)] hover:bg-[var(--color-bg-cream)] hover:border-[var(--color-text)]"].join(" "),children:[m.jsx("input",{type:"radio",name:"pipeline-template",value:e,checked:f,disabled:o,onChange:()=>s(e),className:"mt-1 flex-shrink-0"}),m.jsxs("div",{className:"flex-1",children:[m.jsx("div",{className:"text-sm font-bold",children:n}),m.jsx("div",{className:"text-xs text-[var(--color-text-muted)]",children:o?c:a})]})]})}function MO(){var o;const{name:e=""}=UE(),t=wr(),[n,a]=M.useState("overview"),s=lt({queryKey:["project",e],queryFn:()=>QA(e),enabled:!!e});return m.jsxs("div",{className:"flex flex-col gap-5 max-w-4xl",children:[m.jsxs("header",{className:"flex items-center gap-3",children:[m.jsxs("button",{type:"button",onClick:()=>t("/projects"),className:"nb-btn",style:{padding:"6px 12px"},"aria-label":"返回项目列表",children:[m.jsx(VE,{size:14,strokeWidth:3}),"返回"]}),m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-3xl font-bold flex-1",children:e}),m.jsx(ds,{to:`/board?project=${encodeURIComponent(e)}`,className:"nb-btn nb-btn-mint",children:"看板"})]}),m.jsxs("nav",{className:"flex gap-2 flex-wrap",children:[m.jsx(Xu,{current:n,value:"overview",onSelect:a,icon:$C,children:"概览"}),m.jsx(Xu,{current:n,value:"config",onSelect:a,icon:JE,children:"配置"}),m.jsx(Xu,{current:n,value:"pipelines",onSelect:a,icon:i1,children:"Pipelines"}),m.jsx(Xu,{current:n,value:"danger",onSelect:a,icon:Il,children:"危险操作"})]}),n==="overview"&&m.jsx(jO,{name:e,data:s.data,loading:s.isLoading}),n==="config"&&m.jsx(DO,{name:e}),n==="pipelines"&&m.jsx(LO,{name:e}),n==="danger"&&m.jsx(IO,{name:e,repoDir:((o=s.data)==null?void 0:o.repoDir)??null})]})}function Xu({current:e,value:t,onSelect:n,icon:a,children:s}){const o=e===t;return m.jsxs("button",{type:"button",onClick:()=>n(t),"aria-current":o?"page":void 0,className:["nb-btn",o?"nb-btn-primary":""].join(" "),style:{padding:"6px 14px",fontSize:13},children:[m.jsx(a,{size:13,strokeWidth:2.5}),s]})}function jO({name:e,data:t,loading:n}){return n?m.jsx("div",{className:"nb-card",children:m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"})}):t?m.jsx("div",{className:"nb-card",children:m.jsxs("dl",{className:"grid grid-cols-[160px_1fr] gap-y-3 text-sm",children:[m.jsx("dt",{className:"font-bold",children:"仓库路径"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.repoDir??"—"}),m.jsx("dt",{className:"font-bold",children:"PM 后端"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.pmBackend}),m.jsx("dt",{className:"font-bold",children:"Agent"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.agentProvider}),m.jsx("dt",{className:"font-bold",children:"卡片"}),m.jsxs("dd",{className:"font-[family-name:var(--font-mono)]",children:[t.cards.total," 张 · ",t.cards.inprogress," 进行中 · ",t.cards.done," 完成"]}),m.jsx("dt",{className:"font-bold",children:"Worker"}),m.jsxs("dd",{className:"font-[family-name:var(--font-mono)]",children:[t.workers.total," 个(",t.workers.active," 活跃)"]}),m.jsx("dt",{className:"font-bold",children:"Pipeline"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.pipelineStatus}),m.jsx("dt",{className:"font-bold",children:"最近活动"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.lastActivityAt?new Date(t.lastActivityAt).toLocaleString():"—"})]})}):m.jsx("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:m.jsxs("p",{children:["项目 ",e," 不存在或无法读取。"]})})}function DO({name:e}){const t=qn(),{alert:n}=si(),{data:a,isLoading:s,isError:o,error:c,refetch:f}=lt({queryKey:["project-conf",e],queryFn:()=>VA(e)}),[d,h]=M.useState(null),[y,g]=M.useState(null);M.useEffect(()=>{a&&d===null&&(h(a.content),g(a.etag))},[a,d]);const x=d!==null&&a!==void 0&&d!==a.content,v=Pn({mutationFn:()=>{if(d===null||y===null)throw new Error("no draft");return XA(e,d,y)},onSuccess:S=>{g(S.etag),t.invalidateQueries({queryKey:["project-conf",e]}),t.invalidateQueries({queryKey:["project",e]})},onError:S=>{const w=S.status;n({title:w===409?"配置已被其他地方修改":"保存失败",body:w===409?'conf 文件在你编辑期间被改过。点"重新加载"后再编辑。':S instanceof Error?S.message:String(S)})}});return s?m.jsx("div",{className:"nb-card",children:m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"})}):o?m.jsx("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:m.jsxs("p",{children:["加载失败: ",c instanceof Error?c.message:String(c)]})}):m.jsxs("div",{className:"nb-card",children:[m.jsxs("div",{className:"flex items-center justify-between mb-3",children:[m.jsxs("div",{children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-lg font-bold",children:m.jsxs("code",{className:"font-[family-name:var(--font-mono)] text-sm bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] px-2 py-0.5 rounded",children:["~/.coral/projects/",e,"/conf"]})}),y&&m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] mt-1",children:["etag: ",y]})]}),m.jsxs("div",{className:"flex gap-2",children:[m.jsxs("button",{type:"button",className:"nb-btn",style:{padding:"6px 12px"},onClick:()=>{h(null),f()},disabled:v.isPending,"aria-label":"重新加载",children:[m.jsx(Cl,{size:13,strokeWidth:2.5}),"重新加载"]}),m.jsxs("button",{type:"button",className:"nb-btn nb-btn-primary",style:{padding:"6px 12px"},onClick:()=>v.mutate(),disabled:!x||v.isPending,"aria-label":"保存配置",children:[v.isPending?m.jsx(Wt,{size:13,strokeWidth:3,className:"animate-spin"}):v.isSuccess&&!x?m.jsx(EC,{size:13,strokeWidth:3}):m.jsx(Df,{size:13,strokeWidth:3}),"保存"]})]})]}),m.jsx("textarea",{className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",style:{minHeight:480,resize:"vertical"},value:d??"",onChange:S=>h(S.target.value),spellCheck:!1,"aria-label":"conf 文件编辑器"}),x&&m.jsx("p",{className:"text-xs text-[var(--color-stuck)] mt-2 font-bold",children:"● 未保存的修改"})]})}function LO({name:e}){const t=qn(),{confirm:n,alert:a}=si(),{data:s,isLoading:o}=lt({queryKey:["project-pipelines",e],queryFn:()=>WA(e)}),[c,f]=M.useState(null),[d,h]=M.useState(!1),y=Pn({mutationFn:S=>JA(e,S),onSuccess:()=>t.invalidateQueries({queryKey:["project-pipelines",e]}),onError:S=>{a({title:"切换失败",body:S instanceof Error?S.message:String(S)})}}),g=Pn({mutationFn:S=>i2(e,S),onSuccess:()=>t.invalidateQueries({queryKey:["project-pipelines",e]}),onError:S=>{a({title:"删除失败",body:S instanceof Error?S.message:String(S)})}}),x=Pn({mutationFn:S=>n2(e,S.name,S.template),onSuccess:S=>{t.invalidateQueries({queryKey:["project-pipelines",e]}),h(!1),f(S.name)},onError:S=>{a({title:"创建失败",body:S instanceof Error?S.message:String(S)})}});if(o)return m.jsx("div",{className:"nb-card",children:m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"})});const v=[];s!=null&&s.active&&v.push({name:s.active,isActive:!0});for(const S of(s==null?void 0:s.available)??[])v.push({name:S.name,isActive:!1});return m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"nb-card",children:[m.jsxs("div",{className:"flex items-center justify-between mb-3",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-lg font-bold",children:"Pipelines"}),m.jsxs("button",{type:"button",className:"nb-btn nb-btn-mint",style:{padding:"6px 12px",fontSize:12},onClick:()=>h(!0),disabled:x.isPending,"aria-label":"新建 pipeline",children:[m.jsx(Xi,{size:12,strokeWidth:3}),"新建 pipeline"]})]}),v.length===0?m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] italic p-4 border-2 border-dashed border-[var(--color-text)] rounded-lg text-center",children:'还没有 pipeline 文件。点"新建 pipeline"开始。'}):m.jsx("ul",{className:"flex flex-col gap-2",children:v.map(S=>m.jsxs("li",{className:"flex items-center gap-3 p-3 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg",children:[m.jsx(i1,{size:16,strokeWidth:2.5}),m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold flex-1",children:S.name}),S.isActive&&m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)"},children:"active"}),m.jsxs("div",{className:"flex gap-1",children:[m.jsxs("button",{type:"button",className:"nb-btn",style:{padding:"4px 10px",fontSize:11},onClick:()=>f(S.name),"aria-label":`编辑 ${S.name}`,children:[m.jsx(Hp,{size:11,strokeWidth:2.5}),"编辑"]}),!S.isActive&&m.jsxs(m.Fragment,{children:[m.jsx("button",{type:"button",className:"nb-btn nb-btn-primary",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{await n({title:`切换到 ${S.name}`,body:`当前 project.yaml 会被 ${S.name} 的内容覆盖。继续?`,confirm:"切换"})&&y.mutate(S.name)},disabled:y.isPending,"aria-label":`切换到 ${S.name}`,children:"切换"}),m.jsx("button",{type:"button",className:"nb-btn nb-btn-danger",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{await n({title:`删除 ${S.name}`,body:"这个 pipeline 文件会被永久删除。",confirm:"删除",danger:!0})&&g.mutate(S.name)},disabled:g.isPending,"aria-label":`删除 ${S.name}`,children:m.jsx(Il,{size:11,strokeWidth:2.5})})]})]})]},S.name))})]}),c&&m.jsx(CO,{projectName:e,file:c,onClose:()=>f(null),onSaved:()=>{t.invalidateQueries({queryKey:["project-pipelines",e]})}}),d&&m.jsx(RO,{hasActive:!!(s!=null&&s.active),hasSample:!0,isPending:x.isPending,onCancel:()=>h(!1),onCreate:(S,w)=>x.mutate({name:S,template:w})})]})}function IO({name:e,repoDir:t}){const n=wr(),a=qn(),{alert:s}=si(),[o,c]=M.useState(""),[f,d]=M.useState(!0),h=Pn({mutationFn:()=>ZA(e,{includeClaudeDir:f}),onSuccess:y=>{a.invalidateQueries({queryKey:["projects"]});const g=y.claudeRemoved.filter(x=>x.ok).map(x=>x.path);s({title:"已删除",body:g.length>0?`项目已删除。同时清理了:
|
|
474
474
|
${g.join(`
|
|
475
|
-
`)}`:"项目已删除。"}).then(()=>n("/projects"))},onError:y=>{s({title:"删除失败",body:y instanceof Error?y.message:String(y)})}});return m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-lg font-bold mb-2 text-[var(--color-crashed)]",children:"删除项目"}),m.jsxs("p",{className:"text-sm mb-4",children:["这会清理 ",m.jsxs("code",{className:"font-[family-name:var(--font-mono)] bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-1.5 py-0.5 rounded",children:["~/.coral/projects/",e,"/"]}),"(包括所有卡片、runtime、logs)。"]}),t&&m.jsxs("label",{className:"flex items-start gap-2 mb-4 p-3 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-lg cursor-pointer",children:[m.jsx("input",{type:"checkbox",checked:f,onChange:y=>d(y.target.checked),className:"mt-0.5"}),m.jsxs("div",{className:"flex-1",children:[m.jsx("div",{className:"text-sm font-bold",children:"同时清理 repo 的 .claude/"}),m.jsxs("div",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)]",children:[t,"/.claude/"]}),m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-1",children:"repo 本身不动,只清这个目录。"})]})]}),m.jsx("div",{className:"mb-4",children:m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsxs("span",{className:"text-sm font-bold",children:["输入项目名 ",m.jsx("code",{className:"font-[family-name:var(--font-mono)] text-xs",children:e})," 确认:"]}),m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:o,onChange:y=>c(y.target.value),placeholder:e})]})}),m.jsxs("button",{type:"button",className:"nb-btn nb-btn-danger",disabled:o!==e||h.isPending,onClick:()=>h.mutate(),"aria-label":"永久删除项目",children:[h.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Il,{size:14,strokeWidth:3}),"永久删除"]})]})}function lg(e){const t=e?`?project=${encodeURIComponent(e)}`:"";return Ht(`/api/skills${t}`)}function zO(e){return Ht(`/api/skills/${encodeURIComponent(e)}`)}function BO(e,t){return Ht(`/api/skills/${encodeURIComponent(e)}/references/${encodeURIComponent(t)}`)}async function Yf(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok)throw new Error(`${n.status}: ${await n.text()}`);return n.json().catch(()=>({}))}function UO(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/link`,{project:t})}function FO(e,t){return fetch(`/api/skills/${encodeURIComponent(e)}/link?project=${encodeURIComponent(t)}`,{method:"DELETE"}).then(n=>{if(!n.ok)throw new Error(`${n.status}`);return n.json()})}function $O(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/freeze`,{project:t})}function PO(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/unfreeze`,{project:t})}function qO(){return Yf("/api/skills/sync")}function HO({project:e,isPending:t,onCancel:n,onCreate:a}){var A;const[s,o]=M.useState(""),[c,f]=M.useState(""),[d,h]=M.useState(new Set),[y,g]=M.useState(!0),x=lt({queryKey:["skills-all",e],queryFn:()=>lg(e)});M.useEffect(()=>{const T=D=>{D.key==="Escape"&&n()};return window.addEventListener("keydown",T),()=>window.removeEventListener("keydown",T)},[n]);const S=s.trim().length>0&&s.trim().length<=200&&!t,w=T=>{const D=new Set(d);D.has(T)?D.delete(T):D.add(T),h(D)},k=()=>{S&&a({title:s.trim(),description:c.trim(),skills:[...d],labels:y?["AI-PIPELINE"]:[]})},_=((A=x.data)==null?void 0:A.data)??[];return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-40 flex items-start justify-center p-6 bg-black/30 overflow-auto",children:m.jsxs("div",{className:"nb-card mt-8 w-full max-w-xl flex flex-col",style:{maxHeight:"calc(100vh - 64px)"},children:[m.jsxs("header",{className:"flex items-center justify-between mb-4 flex-shrink-0",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold",children:"新建卡片"}),m.jsx("button",{className:"nb-btn nb-btn-mint p-2",onClick:n,type:"button","aria-label":"关闭",children:m.jsx(Er,{size:14,strokeWidth:3})})]}),m.jsxs("form",{onSubmit:T=>{T.preventDefault(),k()},className:"flex flex-col gap-4 overflow-auto",children:[m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:"标题 *"}),m.jsx("input",{type:"text",className:"nb-input w-full",placeholder:"例如:接入 GitHub OAuth 登录",value:s,onChange:T=>o(T.target.value),maxLength:200,autoFocus:!0,required:!0}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"写简短明了的目标(<200 字符)"})]}),m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:"描述"}),m.jsx("textarea",{className:"nb-input w-full",style:{minHeight:120,resize:"vertical"},placeholder:"用户故事、需求、验收标准、参考资料… Claude 启动时会读这里的内容",value:c,onChange:T=>f(T.target.value)}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"支持 markdown。空的话就只有 title,Claude 只能靠 title 推断要做啥。"})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[m.jsx("span",{className:"text-sm font-bold",children:"Skills"}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"勾选哪些 skill 会被加载(走 frontmatter `skills:`)。不选也行,Worker 默认加载项目级 skills。"}),x.isLoading&&m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 skill 列表…"}),x.isError&&m.jsxs("p",{className:"text-xs text-[var(--color-crashed)]",children:["skill 列表加载失败,不影响创建:",x.error instanceof Error?x.error.message:String(x.error)]}),_.length>0&&m.jsx("div",{className:"flex flex-wrap gap-2",children:_.map(T=>{const D=d.has(T.name);return m.jsx("button",{type:"button",onClick:()=>w(T.name),className:["px-2.5 py-1 text-xs font-[family-name:var(--font-mono)] rounded-full border-2 transition-all",D?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)] font-bold":"bg-[var(--color-bg)] border-[var(--color-border-light)] hover:border-[var(--color-text)]"].join(" "),"aria-pressed":D,children:T.name},T.name)})}),d.size>0&&m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)]",children:["已选 ",d.size," 个:",[...d].join(", ")]})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[m.jsx("span",{className:"text-sm font-bold",children:"流水线"}),m.jsxs("label",{className:"flex items-center gap-3 cursor-pointer select-none p-3 border-[2px] border-[var(--color-text)] rounded-lg bg-[var(--color-bg-cream)]",children:[m.jsx("input",{type:"checkbox",className:"w-4 h-4 accent-[var(--color-cta)] cursor-pointer",checked:y,onChange:T=>g(T.target.checked)}),m.jsxs("div",{className:"flex-1",children:[m.jsx("div",{className:"text-sm font-bold",children:"加入流水线(`AI-PIPELINE` 标签)"}),m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-0.5",children:"打开后 pipeline 会识别这张卡并派 worker 跑。关闭则只是一个普通 todo,需要人工改标签才会被流水线拾起。"})]})]})]})]}),m.jsxs("div",{className:"flex gap-2 justify-end mt-4 pt-3 border-t-2 border-dashed border-[var(--color-text)] flex-shrink-0",children:[m.jsx("button",{className:"nb-btn",style:{padding:"6px 14px"},onClick:n,disabled:t,type:"button",children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",style:{padding:"6px 14px"},onClick:k,disabled:!S,type:"button","aria-label":"创建卡片",children:[t?m.jsx(Wt,{size:13,strokeWidth:3,className:"animate-spin"}):m.jsx(Xi,{size:13,strokeWidth:3}),"创建"]})]})]})})}function KO(e){return Ht(`/api/projects/${encodeURIComponent(e)}/cards`)}function GO(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/cards/${t}`)}async function ql(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok){const a=await n.text();throw new Error(`${n.status} ${n.statusText}: ${a}`)}return n.json().catch(()=>({}))}function QO(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/cards/${t}/reset`)}async function YO(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"DELETE"});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}}function VO(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/cards/${t}/launch`)}function XO(e,t){const n=typeof t=="string"?{title:t}:t;return ql(`/api/projects/${encodeURIComponent(e)}/cards`,n)}async function ZO(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:n})});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}}async function WO(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}return a.json()}function JO(e){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/start`)}function eR(e){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/stop`)}function tR(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/reset`,t??{})}function nR(e){const t=qn();M.useEffect(()=>{if(!e)return;const n=`/stream/projects/${encodeURIComponent(e)}`,a=new EventSource(n),s=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["cards",d.project]}),t.invalidateQueries({queryKey:["card",d.project,d.seq]}),t.invalidateQueries({queryKey:["projects"]})}catch{}},o=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["workers",d.project]}),t.invalidateQueries({queryKey:["projects"]})}catch{}},c=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["pipeline-status",d.project]}),t.invalidateQueries({queryKey:["projects"]})}catch{}};return a.addEventListener("card.created",s),a.addEventListener("card.updated",s),a.addEventListener("card.moved",s),a.addEventListener("card.deleted",s),a.addEventListener("worker.updated",o),a.addEventListener("worker.added",o),a.addEventListener("worker.deleted",o),a.addEventListener("pipeline.status",c),a.addEventListener("pipeline.started",c),a.addEventListener("pipeline.stopped",c),()=>a.close()},[e,t])}const iR=new Set(["python","typescript","golang","rust","kotlin","swift","java"]),aR=new Set(["frontend","backend","mobile","database","devops"]),rR=new Set(["backend-architect","frontend-developer","code-reviewer","database-optimizer","devops-automator","security-engineer","qa-tester","security","qa","architect","db-opt"]),sR=new Set(["coding-standards","tdd-workflow","git-workflow","architecture-decision-records","debugging-workflow"]);function lR(e){return iR.has(e)?"lang":aR.has(e)?"end":rR.has(e)?"persona":sR.has(e)?"workflow":"other"}const oR={lang:"var(--color-accent-purple)",end:"var(--color-secondary)",persona:"var(--color-primary)",workflow:"var(--color-accent-mint)",other:"var(--color-bg)"};function iS({name:e}){const t=oR[lR(e)];return m.jsx("span",{className:"nb-badge",style:{background:t},children:e})}function aS({label:e,kind:t="default"}){const n=t==="warn"?"var(--color-accent-pink)":t==="accent"?"var(--color-accent-yellow)":"var(--color-bg-cream)";return m.jsx("span",{className:"nb-badge",style:{background:n},children:e})}function cR({card:e,onClick:t,done:n,draggable:a}){const s=e.labels.some(o=>o.startsWith("STARTED-"))&&!n;return m.jsxs("article",{onClick:t,onKeyDown:o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),t())},draggable:a,onDragStart:o=>{o.dataTransfer.setData("application/x-sps-card-seq",String(e.seq)),o.dataTransfer.effectAllowed="move"},tabIndex:0,role:"button","aria-label":`Card #${e.seq}: ${e.title}`,className:["bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl p-3","shadow-[3px_3px_0_var(--color-text)] cursor-pointer","transition-[transform,box-shadow] duration-[180ms] ease-out","hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-[5px_5px_0_var(--color-text)]","focus:outline-none focus-visible:ring-[3px] focus-visible:ring-offset-2 focus-visible:ring-[var(--color-text)]",n?"opacity-60":"",a?"active:cursor-grabbing":""].join(" "),children:[m.jsxs("div",{className:"flex items-center justify-between gap-2 mb-2",children:[m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-[11px] px-2 py-0.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full",children:["#",e.seq]}),s&&m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)"},children:"running"})]}),m.jsx("p",{className:`font-bold text-sm leading-5 mb-2 line-clamp-2 ${n?"line-through decoration-2":""}`,children:e.title}),(e.skills.length>0||e.labels.length>0)&&m.jsxs("div",{className:"flex flex-wrap gap-1 mb-2",children:[e.skills.slice(0,3).map(o=>m.jsx(iS,{name:o},o)),e.labels.filter(o=>o==="NEEDS-FIX").map(o=>m.jsx(aS,{label:o,kind:"warn"},o))]}),e.checklist&&e.checklist.total>0&&m.jsx(uR,{stats:e.checklist}),m.jsxs("div",{className:"pt-2 border-t-[1.5px] border-dashed border-[var(--color-border-light)] flex items-center gap-2 text-[11px] font-[family-name:var(--font-mono)] text-[var(--color-text-subtle)]",children:[m.jsx("span",{children:fR(e.updatedAt??e.createdAt)}),e.branch&&m.jsxs("span",{className:"truncate",children:["· ",e.branch]})]})]})}function uR({stats:e}){return m.jsxs("div",{className:"mb-2",children:[m.jsxs("div",{className:"flex items-center justify-between text-[11px] font-[family-name:var(--font-mono)] mb-1",children:[m.jsxs("span",{className:"font-bold",children:["检查清单 ",e.done,"/",e.total]}),m.jsxs("span",{className:"text-[var(--color-text-subtle)]",children:[e.percent,"%"]})]}),m.jsx("div",{className:"w-full h-1.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full overflow-hidden mb-1.5",children:m.jsx("div",{className:"h-full bg-[var(--color-cta)] transition-[width] duration-200",style:{width:`${e.percent}%`}})}),m.jsxs("ul",{className:"text-[11px] space-y-0.5",children:[e.items.slice(0,3).map((t,n)=>m.jsxs("li",{className:`flex items-start gap-1 ${t.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{className:"flex-shrink-0 mt-0.5",children:t.done?"✓":"○"}),m.jsx("span",{className:"line-clamp-1",children:t.text})]},n)),e.items.length>3&&m.jsxs("li",{className:"text-[var(--color-text-subtle)] italic pl-3",children:["… 还有 ",e.items.length-3," 条"]})]})]})}function fR(e){if(!e)return"—";const t=new Date(e),n=Date.now()-t.getTime();return n<6e4?"刚才":n<36e5?`${Math.floor(n/6e4)}m ago`:n<864e5?`${Math.floor(n/36e5)}h ago`:t.toLocaleDateString()}function dR({label:e,bg:t,cards:n,onCardClick:a,onDropCard:s}){const[o,c]=M.useState(!1);return m.jsxs("div",{className:["flex flex-col gap-2 p-3 rounded-2xl border-[3px] min-h-[340px]","transition-all",o?"border-[var(--color-cta)] shadow-[4px_4px_0_var(--color-cta)]":"border-[var(--color-text)]"].join(" "),style:{background:t},onDragOver:f=>{!s||!f.dataTransfer.types.includes("application/x-sps-card-seq")||(f.preventDefault(),f.dataTransfer.dropEffect="move",o||c(!0))},onDragLeave:()=>c(!1),onDrop:f=>{if(c(!1),!s)return;const d=f.dataTransfer.getData("application/x-sps-card-seq"),h=Number.parseInt(d,10);Number.isFinite(h)&&(f.preventDefault(),s(h))},children:[m.jsxs("div",{className:"flex items-center justify-between px-1 pb-2 border-b-2 border-[var(--color-text)]",children:[m.jsx("span",{className:"font-[family-name:var(--font-heading)] font-bold text-sm uppercase tracking-wider",children:e}),m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs px-2 py-0.5 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-full",children:n.length})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[n.length===0&&m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] text-center py-6 italic",children:"— 空 —"}),n.map(f=>m.jsx(cR,{card:f,onClick:()=>a(f),done:e==="Done",draggable:!!s},f.seq))]})]})}function dp(e,t){if(!e)return"";const n=e.split(`
|
|
475
|
+
`)}`:"项目已删除。"}).then(()=>n("/projects"))},onError:y=>{s({title:"删除失败",body:y instanceof Error?y.message:String(y)})}});return m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-lg font-bold mb-2 text-[var(--color-crashed)]",children:"删除项目"}),m.jsxs("p",{className:"text-sm mb-4",children:["这会清理 ",m.jsxs("code",{className:"font-[family-name:var(--font-mono)] bg-[var(--color-bg)] border-2 border-[var(--color-text)] px-1.5 py-0.5 rounded",children:["~/.coral/projects/",e,"/"]}),"(包括所有卡片、runtime、logs)。"]}),t&&m.jsxs("label",{className:"flex items-start gap-2 mb-4 p-3 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-lg cursor-pointer",children:[m.jsx("input",{type:"checkbox",checked:f,onChange:y=>d(y.target.checked),className:"mt-0.5"}),m.jsxs("div",{className:"flex-1",children:[m.jsx("div",{className:"text-sm font-bold",children:"同时清理 repo 的 .claude/"}),m.jsxs("div",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)]",children:[t,"/.claude/"]}),m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-1",children:"repo 本身不动,只清这个目录。"})]})]}),m.jsx("div",{className:"mb-4",children:m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsxs("span",{className:"text-sm font-bold",children:["输入项目名 ",m.jsx("code",{className:"font-[family-name:var(--font-mono)] text-xs",children:e})," 确认:"]}),m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-mono)]",value:o,onChange:y=>c(y.target.value),placeholder:e})]})}),m.jsxs("button",{type:"button",className:"nb-btn nb-btn-danger",disabled:o!==e||h.isPending,onClick:()=>h.mutate(),"aria-label":"永久删除项目",children:[h.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Il,{size:14,strokeWidth:3}),"永久删除"]})]})}function lg(e){const t=e?`?project=${encodeURIComponent(e)}`:"";return Ht(`/api/skills${t}`)}function zO(e){return Ht(`/api/skills/${encodeURIComponent(e)}`)}function BO(e,t){return Ht(`/api/skills/${encodeURIComponent(e)}/references/${encodeURIComponent(t)}`)}async function Yf(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok)throw new Error(`${n.status}: ${await n.text()}`);return n.json().catch(()=>({}))}function UO(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/link`,{project:t})}function FO(e,t){return fetch(`/api/skills/${encodeURIComponent(e)}/link?project=${encodeURIComponent(t)}`,{method:"DELETE"}).then(n=>{if(!n.ok)throw new Error(`${n.status}`);return n.json()})}function $O(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/freeze`,{project:t})}function PO(e,t){return Yf(`/api/skills/${encodeURIComponent(e)}/unfreeze`,{project:t})}function qO(){return Yf("/api/skills/sync")}function HO({project:e,isPending:t,onCancel:n,onCreate:a}){var A;const[s,o]=M.useState(""),[c,f]=M.useState(""),[d,h]=M.useState(new Set),[y,g]=M.useState(!0),x=lt({queryKey:["skills-all",e],queryFn:()=>lg(e)});M.useEffect(()=>{const T=D=>{D.key==="Escape"&&n()};return window.addEventListener("keydown",T),()=>window.removeEventListener("keydown",T)},[n]);const S=s.trim().length>0&&s.trim().length<=200&&!t,w=T=>{const D=new Set(d);D.has(T)?D.delete(T):D.add(T),h(D)},k=()=>{S&&a({title:s.trim(),description:c.trim(),skills:[...d],labels:y?["AI-PIPELINE"]:[]})},_=((A=x.data)==null?void 0:A.data)??[];return m.jsx("div",{role:"dialog","aria-modal":"true",className:"fixed inset-0 z-40 flex items-start justify-center p-6 bg-black/30 overflow-auto",children:m.jsxs("div",{className:"nb-card mt-8 w-full max-w-xl flex flex-col",style:{maxHeight:"calc(100vh - 64px)"},children:[m.jsxs("header",{className:"flex items-center justify-between mb-4 flex-shrink-0",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-2xl font-bold",children:"新建卡片"}),m.jsx("button",{className:"nb-btn nb-btn-mint p-2",onClick:n,type:"button","aria-label":"关闭",children:m.jsx(Er,{size:14,strokeWidth:3})})]}),m.jsxs("form",{onSubmit:T=>{T.preventDefault(),k()},className:"flex flex-col gap-4 overflow-auto",children:[m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:"标题 *"}),m.jsx("input",{type:"text",className:"nb-input w-full",placeholder:"例如:接入 GitHub OAuth 登录",value:s,onChange:T=>o(T.target.value),maxLength:200,autoFocus:!0,required:!0}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"写简短明了的目标(<200 字符)"})]}),m.jsxs("label",{className:"flex flex-col gap-1.5",children:[m.jsx("span",{className:"text-sm font-bold",children:"描述"}),m.jsx("textarea",{className:"nb-input w-full",style:{minHeight:120,resize:"vertical"},placeholder:"用户故事、需求、验收标准、参考资料… Claude 启动时会读这里的内容",value:c,onChange:T=>f(T.target.value)}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"支持 markdown。空的话就只有 title,Claude 只能靠 title 推断要做啥。"})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[m.jsx("span",{className:"text-sm font-bold",children:"Skills"}),m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"勾选哪些 skill 会被加载(走 frontmatter `skills:`)。不选也行,Worker 默认加载项目级 skills。"}),x.isLoading&&m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 skill 列表…"}),x.isError&&m.jsxs("p",{className:"text-xs text-[var(--color-crashed)]",children:["skill 列表加载失败,不影响创建:",x.error instanceof Error?x.error.message:String(x.error)]}),_.length>0&&m.jsx("div",{className:"flex flex-wrap gap-2",children:_.map(T=>{const D=d.has(T.name);return m.jsx("button",{type:"button",onClick:()=>w(T.name),className:["px-2.5 py-1 text-xs font-[family-name:var(--font-mono)] rounded-full border-2 transition-all",D?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)] font-bold":"bg-[var(--color-bg)] border-[var(--color-border-light)] hover:border-[var(--color-text)]"].join(" "),"aria-pressed":D,children:T.name},T.name)})}),d.size>0&&m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)]",children:["已选 ",d.size," 个:",[...d].join(", ")]})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[m.jsx("span",{className:"text-sm font-bold",children:"流水线"}),m.jsxs("label",{className:"flex items-center gap-3 cursor-pointer select-none p-3 border-[2px] border-[var(--color-text)] rounded-lg bg-[var(--color-bg-cream)]",children:[m.jsx("input",{type:"checkbox",className:"w-4 h-4 accent-[var(--color-cta)] cursor-pointer",checked:y,onChange:T=>g(T.target.checked)}),m.jsxs("div",{className:"flex-1",children:[m.jsx("div",{className:"text-sm font-bold",children:"加入流水线(`AI-PIPELINE` 标签)"}),m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-0.5",children:"打开后 pipeline 会识别这张卡并派 worker 跑。关闭则只是一个普通 todo,需要人工改标签才会被流水线拾起。"})]})]})]})]}),m.jsxs("div",{className:"flex gap-2 justify-end mt-4 pt-3 border-t-2 border-dashed border-[var(--color-text)] flex-shrink-0",children:[m.jsx("button",{className:"nb-btn",style:{padding:"6px 14px"},onClick:n,disabled:t,type:"button",children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",style:{padding:"6px 14px"},onClick:k,disabled:!S,type:"button","aria-label":"创建卡片",children:[t?m.jsx(Wt,{size:13,strokeWidth:3,className:"animate-spin"}):m.jsx(Xi,{size:13,strokeWidth:3}),"创建"]})]})]})})}function KO(e){return Ht(`/api/projects/${encodeURIComponent(e)}/cards`)}function GO(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/cards/${t}`)}async function ql(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok){const a=await n.text();throw new Error(`${n.status} ${n.statusText}: ${a}`)}return n.json().catch(()=>({}))}function QO(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/cards/${t}/reset`)}async function YO(e,t){const n=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"DELETE"});if(!n.ok){const a=await n.text();throw new Error(`${n.status}: ${a}`)}}function VO(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/cards/${t}/launch`)}function XO(e,t){const n=typeof t=="string"?{title:t}:t;return ql(`/api/projects/${encodeURIComponent(e)}/cards`,n)}async function ZO(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:n})});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}}async function WO(e,t,n){const a=await fetch(`/api/projects/${encodeURIComponent(e)}/cards/${t}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!a.ok){const s=await a.text();throw new Error(`${a.status}: ${s}`)}return a.json()}function JO(e){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/start`)}function eR(e){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/stop`)}function tR(e,t){return ql(`/api/projects/${encodeURIComponent(e)}/pipeline/reset`,t??{})}function nR(e){const t=qn();M.useEffect(()=>{if(!e)return;const n=`/stream/projects/${encodeURIComponent(e)}`,a=new EventSource(n),s=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["cards",d.project]}),t.invalidateQueries({queryKey:["card",d.project,d.seq]}),t.invalidateQueries({queryKey:["projects"]})}catch{}},o=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["workers",d.project]}),t.invalidateQueries({queryKey:["projects"]})}catch{}},c=f=>{try{const d=JSON.parse(f.data);t.invalidateQueries({queryKey:["pipeline-status",d.project]}),t.invalidateQueries({queryKey:["projects"]})}catch{}};return a.addEventListener("card.created",s),a.addEventListener("card.updated",s),a.addEventListener("card.moved",s),a.addEventListener("card.deleted",s),a.addEventListener("worker.updated",o),a.addEventListener("worker.added",o),a.addEventListener("worker.deleted",o),a.addEventListener("pipeline.status",c),a.addEventListener("pipeline.started",c),a.addEventListener("pipeline.stopped",c),()=>a.close()},[e,t])}const iR=new Set(["python","typescript","golang","rust","kotlin","swift","java"]),aR=new Set(["frontend","backend","mobile","database","devops"]),rR=new Set(["backend-architect","frontend-developer","code-reviewer","database-optimizer","devops-automator","security-engineer","qa-tester","security","qa","architect","db-opt"]),sR=new Set(["coding-standards","tdd-workflow","git-workflow","architecture-decision-records","debugging-workflow"]);function lR(e){return iR.has(e)?"lang":aR.has(e)?"end":rR.has(e)?"persona":sR.has(e)?"workflow":"other"}const oR={lang:"var(--color-accent-purple)",end:"var(--color-secondary)",persona:"var(--color-primary)",workflow:"var(--color-accent-mint)",other:"var(--color-bg)"};function iS({name:e}){const t=oR[lR(e)];return m.jsx("span",{className:"nb-badge",style:{background:t},children:e})}function aS({label:e,kind:t="default"}){const n=t==="warn"?"var(--color-accent-pink)":t==="accent"?"var(--color-accent-yellow)":"var(--color-bg-cream)";return m.jsx("span",{className:"nb-badge",style:{background:n},children:e})}function cR({card:e,onClick:t,done:n,draggable:a}){const s=e.labels.some(o=>o.startsWith("STARTED-"))&&!n;return m.jsxs("article",{onClick:t,onKeyDown:o=>{(o.key==="Enter"||o.key===" ")&&(o.preventDefault(),t())},draggable:a,onDragStart:o=>{o.dataTransfer.setData("application/x-sps-card-seq",String(e.seq)),o.dataTransfer.effectAllowed="move"},tabIndex:0,role:"button","aria-label":`Card #${e.seq}: ${e.title}`,className:["bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl p-3","shadow-[3px_3px_0_var(--color-text)] cursor-pointer","transition-[transform,box-shadow] duration-[180ms] ease-out","hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-[5px_5px_0_var(--color-text)]","focus:outline-none focus-visible:ring-[3px] focus-visible:ring-offset-2 focus-visible:ring-[var(--color-text)]",n?"opacity-60":"",a?"active:cursor-grabbing":""].join(" "),children:[m.jsxs("div",{className:"flex items-center justify-between gap-2 mb-2",children:[m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-[11px] px-2 py-0.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full",children:["#",e.seq]}),s&&m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)"},children:"running"})]}),m.jsx("p",{className:`font-bold text-sm leading-5 mb-2 line-clamp-2 ${n?"line-through decoration-2":""}`,children:e.title}),(e.skills.length>0||e.labels.length>0)&&m.jsxs("div",{className:"flex flex-wrap gap-1 mb-2",children:[e.skills.slice(0,3).map(o=>m.jsx(iS,{name:o},o)),e.labels.filter(o=>o==="NEEDS-FIX").map(o=>m.jsx(aS,{label:o,kind:"warn"},o))]}),e.checklist&&e.checklist.total>0&&m.jsx(uR,{stats:e.checklist}),m.jsxs("div",{className:"pt-2 border-t-[1.5px] border-dashed border-[var(--color-border-light)] flex items-center gap-2 text-[11px] font-[family-name:var(--font-mono)] text-[var(--color-text-subtle)]",children:[m.jsx("span",{children:fR(e.updatedAt??e.createdAt)}),e.branch&&m.jsxs("span",{className:"truncate",children:["· ",e.branch]})]})]})}function uR({stats:e}){return m.jsxs("div",{className:"mb-2",children:[m.jsxs("div",{className:"flex items-center justify-between text-[11px] font-[family-name:var(--font-mono)] mb-1",children:[m.jsxs("span",{className:"font-bold",children:["检查清单 ",e.done,"/",e.total]}),m.jsxs("span",{className:"text-[var(--color-text-subtle)]",children:[e.percent,"%"]})]}),m.jsx("div",{className:"w-full h-1.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full overflow-hidden mb-1.5",children:m.jsx("div",{className:"h-full bg-[var(--color-cta)] transition-[width] duration-200",style:{width:`${e.percent}%`}})}),m.jsxs("ul",{className:"text-[11px] space-y-0.5",children:[e.items.slice(0,3).map((t,n)=>m.jsxs("li",{className:`flex items-start gap-1 ${t.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{className:"flex-shrink-0 mt-0.5",children:t.done?"✓":"○"}),m.jsx("span",{className:"line-clamp-1",children:t.text})]},n)),e.items.length>3&&m.jsxs("li",{className:"text-[var(--color-text-subtle)] italic pl-3",children:["… 还有 ",e.items.length-3," 条"]})]})]})}function fR(e){if(!e)return"—";const t=new Date(e),n=Date.now()-t.getTime();return n<6e4?"刚才":n<36e5?`${Math.floor(n/6e4)}m ago`:n<864e5?`${Math.floor(n/36e5)}h ago`:t.toLocaleDateString()}function dR({label:e,bg:t,cards:n,onCardClick:a,onDropCard:s}){const[o,c]=M.useState(!1);return m.jsxs("div",{className:["flex flex-col p-3 rounded-2xl border-[3px] min-h-[280px] h-full min-h-0 overflow-hidden","transition-all",o?"border-[var(--color-cta)] shadow-[4px_4px_0_var(--color-cta)]":"border-[var(--color-text)]"].join(" "),style:{background:t},onDragOver:f=>{!s||!f.dataTransfer.types.includes("application/x-sps-card-seq")||(f.preventDefault(),f.dataTransfer.dropEffect="move",o||c(!0))},onDragLeave:()=>c(!1),onDrop:f=>{if(c(!1),!s)return;const d=f.dataTransfer.getData("application/x-sps-card-seq"),h=Number.parseInt(d,10);Number.isFinite(h)&&(f.preventDefault(),s(h))},children:[m.jsxs("div",{className:"flex items-center justify-between px-1 pb-2 mb-2 border-b-2 border-[var(--color-text)] shrink-0",children:[m.jsx("span",{className:"font-[family-name:var(--font-heading)] font-bold text-sm uppercase tracking-wider",children:e}),m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs px-2 py-0.5 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-full",children:n.length})]}),m.jsxs("div",{className:"flex flex-col gap-2 flex-1 min-h-0 overflow-y-auto pr-1 -mr-1",style:{scrollbarWidth:"thin",scrollbarColor:"var(--color-text) transparent"},children:[n.length===0&&m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] text-center py-6 italic",children:"— 空 —"}),n.map(f=>m.jsx(cR,{card:f,onClick:()=>a(f),done:e==="Done",draggable:!!s},f.seq))]})]})}function dp(e,t){if(!e)return"";const n=e.split(`
|
|
476
476
|
`),a=new RegExp(`^##\\s+${t}\\s*$`),s=n.findIndex(c=>a.test(c));if(s===-1)return"";let o=n.length;for(let c=s+1;c<n.length;c++)if(/^##\s+/.test(n[c]??"")){o=c;break}return n.slice(s+1,o).join(`
|
|
477
|
-
`).trim()}function vm(e){return dp(e,"描述")}function hR({project:e,seq:t,onClose:n,onChanged:a}){var K,oe,V,pe,R,L,J,C,me,_e,ve;const s=qn(),{confirm:o,alert:c}=si(),{data:f,isLoading:d,isError:h,error:y,refetch:g}=lt({queryKey:["card",e,t],queryFn:()=>GO(e,t)}),[x,v]=M.useState(!1),[S,w]=M.useState(""),[k,_]=M.useState(""),[A,T]=M.useState(new Set),[D,$]=M.useState([]),[j,q]=M.useState(""),U=lt({queryKey:["skills-all",e],queryFn:()=>lg(e),enabled:x}),O=((oe=(K=lt({queryKey:["projects"],queryFn:_r,refetchInterval:1e4}).data)==null?void 0:K.data.find(ce=>ce.name===e))==null?void 0:oe.pipelineStatus)==="running";M.useEffect(()=>{x&&f&&(w(f.title),_(vm(f.body)),T(new Set(f.skills)),$([...f.labels]))},[x,f]),M.useEffect(()=>{const ce=ke=>{ke.key==="Escape"&&(x?v(!1):n())};return window.addEventListener("keydown",ce),()=>window.removeEventListener("keydown",ce)},[n,x]);const P=Pn({mutationFn:()=>{if(!f)throw new Error("no data");const ce={},ke=S.trim();ke&&ke!==f.title&&(ce.title=ke);const Ke=vm(f.body);k!==Ke&&(ce.description=k);const Dt=[...A].sort(),yn=[...f.skills].sort();return JSON.stringify(Dt)!==JSON.stringify(yn)&&(ce.skills=Dt),JSON.stringify(D)!==JSON.stringify(f.labels)&&(ce.labels=D),Object.keys(ce).length===0?Promise.resolve({ok:!0,noop:!0}):WO(e,t,ce)},onSuccess:()=>{s.invalidateQueries({queryKey:["card",e,t]}),s.invalidateQueries({queryKey:["cards",e]}),v(!1),a()},onError:ce=>{c({title:"保存失败",body:ce instanceof Error?ce.message:String(ce)})}}),G=M.useMemo(()=>{if(!x||!f)return!1;if(S.trim()!==f.title||k!==vm(f.body))return!0;const ce=[...A].sort(),ke=[...f.skills].sort();return JSON.stringify(ce)!==JSON.stringify(ke)||JSON.stringify(D)!==JSON.stringify(f.labels)},[x,f,S,k,A,D]),le=ce=>{const ke=new Set(A);ke.has(ce)?ke.delete(ce):ke.add(ce),T(ke)},ae=()=>{const ce=j.trim();if(ce){if(D.includes(ce)){q("");return}$([...D,ce]),q("")}},W=ce=>{$(D.filter(ke=>ke!==ce))};return m.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"card-modal-title",className:"fixed inset-0 z-40 flex items-start justify-center p-6 bg-black/30 overflow-auto",children:m.jsxs("div",{className:"nb-card mt-12 w-full max-w-3xl bg-[var(--color-bg)]",children:[m.jsxs("header",{className:"flex items-start justify-between gap-4 mb-4",children:[m.jsxs("div",{className:"flex-1 min-w-0",children:[m.jsxs("div",{className:"flex items-center gap-3 mb-1",children:[m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs px-2 py-0.5 bg-[var(--color-accent-purple)] border-2 border-[var(--color-text)] rounded-full",children:["#",t]}),(f==null?void 0:f.state)&&m.jsx("span",{className:"font-[family-name:var(--font-mono)] text-xs px-2 py-0.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full font-semibold",children:f.state}),x&&m.jsx("span",{className:"text-xs font-bold text-[var(--color-stuck)]",children:"⚠ 编辑中"})]}),x?m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-heading)] text-xl font-bold",value:S,onChange:ce=>w(ce.target.value),maxLength:200,"aria-label":"卡片标题"}):m.jsx("h2",{id:"card-modal-title",className:"font-[family-name:var(--font-heading)] text-2xl font-bold break-words",children:(f==null?void 0:f.title)??"加载中…"})]}),m.jsxs("div",{className:"flex gap-2 flex-shrink-0",children:[!x&&f&&m.jsxs("button",{onClick:()=>v(!0),className:"nb-btn",style:{padding:"6px 12px"},type:"button","aria-label":"编辑卡片",children:[m.jsx(Hp,{size:12,strokeWidth:2.5})," 编辑"]}),m.jsx("button",{onClick:n,className:"nb-btn nb-btn-mint p-2","aria-label":"关闭",type:"button",children:m.jsx(Er,{size:14,strokeWidth:3})})]})]}),d&&m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"}),h&&m.jsxs("p",{className:"text-[var(--color-crashed)]",children:["加载失败: ",y instanceof Error?y.message:String(y)]}),f&&m.jsxs("div",{className:"flex flex-col gap-4",children:[f.branch&&!x&&m.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[m.jsx(QC,{size:14}),m.jsx("span",{className:"font-[family-name:var(--font-mono)]",children:f.branch})]}),x?m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Skills"}),U.isLoading&&m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 skill 列表…"}),U.data&&U.data.data.length>0&&m.jsx("div",{className:"flex flex-wrap gap-1.5",children:U.data.data.map(ce=>{const ke=A.has(ce.name);return m.jsx("button",{type:"button",onClick:()=>le(ce.name),"aria-pressed":ke,className:["px-2.5 py-1 text-xs font-[family-name:var(--font-mono)] rounded-full border-2 transition-all",ke?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)] font-bold":"bg-[var(--color-bg)] border-[var(--color-border-light)] hover:border-[var(--color-text)]"].join(" "),children:ce.name},ce.name)})})]}),m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Labels"}),m.jsxs("div",{className:"flex flex-wrap gap-1.5 items-center",children:[D.map(ce=>m.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-[family-name:var(--font-mono)] bg-[var(--color-accent-yellow)] border-2 border-[var(--color-text)] rounded-full",children:[ce,m.jsx("button",{type:"button",onClick:()=>W(ce),className:"hover:text-[var(--color-crashed)]","aria-label":`删除 ${ce}`,children:m.jsx(Er,{size:10,strokeWidth:3})})]},ce)),m.jsx("input",{type:"text",className:"nb-input",style:{padding:"4px 8px",fontSize:12,width:140},placeholder:"+ 添加 label",value:j,onChange:ce=>q(ce.target.value),onKeyDown:ce=>{ce.key==="Enter"&&!ce.nativeEvent.isComposing&&(ce.preventDefault(),ae())}}),j&&m.jsx("button",{type:"button",className:"nb-btn",style:{padding:"2px 6px",fontSize:11},onClick:ae,"aria-label":"添加 label",children:m.jsx(Xi,{size:10,strokeWidth:3})})]}),m.jsx("p",{className:"text-[10px] text-[var(--color-text-muted)] mt-1",children:"注意:AI-PIPELINE / STARTED-* / COMPLETED-* / NEEDS-FIX 由流水线自动管理,手动改可能被覆盖"})]})]}):m.jsxs(m.Fragment,{children:[f.skills.length>0&&m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Skills"}),m.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:f.skills.map(ce=>m.jsx(iS,{name:ce},ce))})]}),f.labels.length>0&&m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Labels"}),m.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:f.labels.map(ce=>m.jsx(aS,{label:ce,kind:ce==="NEEDS-FIX"?"warn":"default"},ce))})]})]}),x?m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"描述"}),m.jsx("textarea",{className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",style:{minHeight:180,resize:"vertical"},value:k,onChange:ce=>_(ce.target.value),"aria-label":"卡片描述"}),m.jsx("p",{className:"text-[10px] text-[var(--color-text-muted)] mt-1",children:'只替换 "## 描述" 段的内容;检查清单和日志段不动。'})]}),(((C=f.checklist)==null?void 0:C.total)??0)>0&&m.jsxs("div",{className:"nb-card bg-[var(--color-bg-cream)] p-3",children:[m.jsx("div",{className:"flex items-center justify-between mb-2",children:m.jsxs("span",{className:"font-bold text-sm",children:["检查清单 ",((me=f.checklist)==null?void 0:me.done)??0,"/",((_e=f.checklist)==null?void 0:_e.total)??0]})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((ve=f.checklist)==null?void 0:ve.items)??[]).map((ce,ke)=>m.jsxs("li",{className:`flex items-start gap-2 ${ce.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:ce.done?"✓":"○"}),m.jsx("span",{children:ce.text})]},ke))})]})]}):m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"描述"}),m.jsx("pre",{className:"text-xs whitespace-pre-wrap font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4 max-h-64 overflow-auto",children:dp(f.body,"描述")||"(空)"})]}),m.jsxs("div",{children:[m.jsxs("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:["检查清单 ",m.jsxs("span",{className:"text-[var(--color-text-muted)] normal-case tracking-normal",children:[((V=f.checklist)==null?void 0:V.done)??0,"/",((pe=f.checklist)==null?void 0:pe.total)??0]})]}),m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)] p-3",children:(((R=f.checklist)==null?void 0:R.total)??0)>0?m.jsxs(m.Fragment,{children:[m.jsx("div",{className:"flex items-center justify-end mb-2",children:m.jsx("div",{className:"w-24 h-2 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-full overflow-hidden",children:m.jsx("div",{className:"h-full bg-[var(--color-cta)]",style:{width:`${((L=f.checklist)==null?void 0:L.percent)??0}%`}})})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((J=f.checklist)==null?void 0:J.items)??[]).map((ce,ke)=>m.jsxs("li",{className:`flex items-start gap-2 ${ce.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:ce.done?"✓":"○"}),m.jsx("span",{children:ce.text})]},ke))})]}):m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:["暂无清单项。在描述里用 ",m.jsx("code",{className:"font-[family-name:var(--font-mono)]",children:"- [ ] 项"})," 语法添加。"]})})]}),m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"日志"}),m.jsx("pre",{className:"text-xs whitespace-pre-wrap font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4 max-h-64 overflow-auto",children:dp(f.body,"日志")||"(空)"})]})]}),m.jsx("div",{className:"flex gap-2 pt-2 border-t-2 border-[var(--color-border-light)] justify-end flex-wrap",children:x?m.jsxs(m.Fragment,{children:[m.jsx("button",{className:"nb-btn",type:"button",onClick:()=>{v(!1),g()},disabled:P.isPending,children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:()=>P.mutate(),disabled:!G||!S.trim()||P.isPending,"aria-label":"保存卡片修改",children:[P.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Df,{size:14,strokeWidth:3}),"保存"]})]}):m.jsxs(m.Fragment,{children:[m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",disabled:f.state==="Done"||O,title:f.state==="Done"?"卡片已完成;先拖回 Todo 再启动":O?"Pipeline 正在跑——supervisor 会自动 dispatch,无需手动启动":void 0,onClick:async()=>{try{await VO(e,t),a()}catch(ce){c({title:"启动 worker 失败",body:ce instanceof Error?ce.message:String(ce)})}},children:[m.jsx(Kp,{size:14,strokeWidth:3}),"启动 worker"]}),m.jsxs("button",{className:"nb-btn nb-btn-yellow",type:"button",onClick:async()=>{if(await o({title:`重置卡片 #${t}`,body:"卡片状态会回到初始,已做的 checklist 会清空。",confirm:"重置",danger:!0}))try{await QO(e,t),a(),n()}catch(ke){c({title:"重置失败",body:ke instanceof Error?ke.message:String(ke)})}},children:[m.jsx(WE,{size:14,strokeWidth:2.5}),"重置卡片"]}),m.jsxs("button",{className:"nb-btn",style:{background:"var(--color-crashed)",color:"var(--color-bg)"},type:"button",onClick:async()=>{if(!(!await o({title:`删除卡片 #${t}`,body:`即将删除 "${f.title}"。此操作不可恢复(md 文件将被物理删除)。是否继续?`,confirm:"继续",danger:!0})||!await o({title:"最终确认",body:`请再次确认删除卡片 #${t}。`,confirm:"确定删除",danger:!0})))try{await YO(e,t),a(),n()}catch(Ke){c({title:"删除失败",body:Ke instanceof Error?Ke.message:String(Ke)})}},"aria-label":"删除卡片",children:[m.jsx(Il,{size:14,strokeWidth:2.5}),"删除卡片"]})]})})]})]})})}function mR({current:e,onChange:t}){const[n,a]=M.useState(!1),s=M.useRef(null),{data:o}=lt({queryKey:["projects"],queryFn:_r});return M.useEffect(()=>{const c=f=>{var d;(d=s.current)!=null&&d.contains(f.target)||a(!1)};return document.addEventListener("mousedown",c),()=>document.removeEventListener("mousedown",c)},[]),m.jsxs("div",{className:"relative",ref:s,children:[m.jsxs("button",{type:"button",className:"inline-flex items-center gap-2 px-3 py-2 bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl shadow-[3px_3px_0_var(--color-text)] font-[family-name:var(--font-mono)] text-sm font-bold hover:-translate-x-px hover:-translate-y-px hover:shadow-[4px_4px_0_var(--color-text)] transition-[transform,box-shadow] duration-150",onClick:()=>a(c=>!c),children:[e,m.jsx(yc,{size:14,strokeWidth:2.5})]}),n&&o&&m.jsx("div",{className:"absolute right-0 mt-2 z-20 min-w-[200px] bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl shadow-[5px_5px_0_var(--color-text)] overflow-hidden",children:o.data.map(c=>m.jsxs("button",{type:"button",onClick:()=>{t(c.name),a(!1)},className:["w-full text-left px-4 py-2 text-sm font-semibold",c.name===e?"bg-[var(--color-accent-mint)]":"hover:bg-[var(--color-bg-cream)]"].join(" "),children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)]",children:c.name}),m.jsxs("span",{className:"ml-2 text-xs text-[var(--color-text-muted)]",children:[c.cards.total," cards"]})]},c.name))})]})}const pR=[{state:"Planning",label:"Planning",bg:"var(--color-accent-purple)"},{state:"Backlog",label:"Backlog",bg:"var(--color-bg-cream)"},{state:"Todo",label:"Todo",bg:"var(--color-accent-yellow)"},{state:"Inprogress",label:"Inprogress",bg:"var(--color-secondary)"},{state:"QA",label:"QA / Review",bg:"var(--color-accent-pink)"},{state:"Done",label:"Done",bg:"var(--color-accent-mint)"}],rS="sps-console:last-board-project";function gR(){if(typeof window>"u")return null;try{return localStorage.getItem(rS)}catch{return null}}function bR(e){if(!(typeof window>"u"))try{localStorage.setItem(rS,e)}catch{}}function yR(){var W,K,oe;const[e,t]=QE(),n=e.get("project"),[a,s]=M.useState(null),[o,c]=M.useState(""),[f,d]=M.useState(()=>new Set),[h,y]=M.useState(()=>new Set),{confirm:g,alert:x}=si();nR(n);const v=lt({queryKey:["projects"],queryFn:_r}),S=lt({queryKey:["cards",n],queryFn:()=>KO(n??""),enabled:!!n}),w=qn(),k=()=>{w.invalidateQueries({queryKey:["cards",n]}),w.invalidateQueries({queryKey:["projects"]}),w.invalidateQueries({queryKey:["pipeline-status",n]})},_=V=>{t({project:V})};M.useEffect(()=>{var pe;if(n){bR(n);return}const V=gR();V&&((pe=v.data)!=null&&pe.data.some(R=>R.name===V))&&t({project:V},{replace:!0})},[n,v.data,t]);const A=Pn({mutationFn:()=>JO(n),onSuccess:()=>{k()},onError:V=>{x({title:"启动 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),T=Pn({mutationFn:()=>eR(n),onSuccess:()=>k(),onError:V=>{x({title:"停止 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),D=Pn({mutationFn:()=>tR(n,{all:!0}),onSuccess:()=>k(),onError:V=>{x({title:"重置失败",body:V instanceof Error?V.message:String(V)})}}),[$,j]=M.useState(!1),q=Pn({mutationFn:V=>XO(n,V),onSuccess:()=>{k(),j(!1)},onError:V=>{x({title:"新建卡片失败",body:V instanceof Error?V.message:String(V)})}}),U=Pn({mutationFn:({seq:V,state:pe})=>ZO(n,V,pe),onMutate:async({seq:V,state:pe})=>{await w.cancelQueries({queryKey:["cards",n]});const R=w.getQueryData(["cards",n]);return R&&w.setQueryData(["cards",n],{...R,data:R.data.map(L=>L.seq===V?{...L,state:pe}:L)}),{prev:R}},onError:(V,pe,R)=>{R!=null&&R.prev&&w.setQueryData(["cards",n],R.prev),x({title:"移动卡片失败",body:V instanceof Error?V.message:String(V)})},onSettled:()=>{w.invalidateQueries({queryKey:["cards",n]})}}),Z=((W=S.data)==null?void 0:W.data)??[],{allSkills:O,allLabels:P}=M.useMemo(()=>{const V=new Set,pe=new Set;for(const R of Z){for(const L of R.skills)V.add(L);for(const L of R.labels)pe.add(L)}return{allSkills:[...V].sort(),allLabels:[...pe].sort()}},[Z]);if(!n)return m.jsxs("div",{className:"flex flex-col gap-6 max-w-4xl",children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold",children:"看板"}),m.jsxs("div",{className:"nb-card bg-[var(--color-accent-yellow)] max-w-2xl",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-3",children:"选择一个项目 🎯"}),m.jsx("p",{className:"text-sm mb-4 text-[var(--color-text-muted)]",children:"看板按项目分。挑一个开始:"}),m.jsx("div",{className:"flex flex-wrap gap-2",children:(K=v.data)==null?void 0:K.data.map(V=>m.jsx("button",{className:"nb-btn nb-btn-blue",onClick:()=>_(V.name),type:"button",children:V.name},V.name))})]})]});const G=Z.filter(V=>{if(o){const pe=o.toLowerCase();if(!(V.title.toLowerCase().includes(pe)||V.skills.some(L=>L.toLowerCase().includes(pe))||V.labels.some(L=>L.toLowerCase().includes(pe))))return!1}return!(f.size>0&&!V.skills.some(R=>f.has(R))||h.size>0&&!V.labels.some(R=>h.has(R)))}),le=(oe=v.data)==null?void 0:oe.data.find(V=>V.name===n),ae=(le==null?void 0:le.pipelineStatus)==="running";return m.jsxs("div",{className:"flex flex-col gap-4 max-w-full",children:[m.jsxs("header",{className:"flex items-center justify-between flex-wrap gap-3",children:[m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"看板 ✨"}),m.jsx("p",{className:"text-[var(--color-text-muted)] text-sm mt-1",children:le?`${le.name} · ${le.cards.total} cards · ${le.workers.active} workers 活跃`:"加载中…"})]}),m.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[m.jsx(mR,{current:n,onChange:_}),m.jsxs("button",{className:ae?"nb-btn nb-btn-danger":"nb-btn nb-btn-primary",onClick:()=>ae?T.mutate():A.mutate(),disabled:A.isPending||T.isPending,type:"button","aria-label":ae?"停止 pipeline":"启动 pipeline",title:ae?"停止 pipeline":"启动 pipeline",children:[A.isPending||T.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):ae?m.jsx(e1,{size:14,strokeWidth:3}):m.jsx(Kp,{size:14,strokeWidth:3}),ae?"停止":"启动"]}),m.jsxs("button",{className:"nb-btn nb-btn-yellow",type:"button",onClick:async()=>{await g({title:"重置整个流水线",body:"这会清空所有卡片的运行状态、worker marker、分支。不可撤销。",confirm:"重置全部",danger:!0})&&D.mutate()},disabled:D.isPending,children:[D.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(WE,{size:14,strokeWidth:2.5}),"重置"]}),m.jsxs("button",{className:"nb-btn nb-btn-mint",type:"button",onClick:()=>j(!0),disabled:q.isPending,children:[q.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Xi,{size:14,strokeWidth:3}),"新卡片"]})]})]}),m.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[m.jsxs("div",{className:"relative flex-1 max-w-md",children:[m.jsx(xf,{size:14,className:"absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-subtle)]"}),m.jsx("input",{className:"nb-input pl-9 w-full",placeholder:"搜索标题 / skill / label…",value:o,onChange:V=>c(V.target.value),"aria-label":"搜索卡片"})]}),m.jsx(Jv,{label:"skill",options:O,selected:f,onChange:d}),m.jsx(Jv,{label:"label",options:P,selected:h,onChange:y}),(o||f.size>0||h.size>0)&&m.jsxs("button",{className:"nb-btn",style:{padding:"4px 10px",fontSize:11},onClick:()=>{c(""),d(new Set),y(new Set)},type:"button","aria-label":"清空筛选",children:[m.jsx(Er,{size:11,strokeWidth:3}),"清空"]}),m.jsxs("span",{className:"text-xs text-[var(--color-text-muted)] flex items-center gap-1 font-[family-name:var(--font-mono)]",children:[m.jsx(KC,{size:12}),G.length," / ",Z.length]})]}),S.isError&&m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("p",{className:"font-semibold",children:"加载卡片失败"}),m.jsx("p",{className:"text-sm mt-1 text-[var(--color-text-muted)]",children:S.error instanceof Error?S.error.message:String(S.error)})]}),!S.isError&&m.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-3",children:pR.map(V=>m.jsx(dR,{label:V.label,bg:V.bg,cards:G.filter(xR(V.state)),onCardClick:pe=>s(pe.seq),onDropCard:pe=>U.mutate({seq:pe,state:V.state})},V.state))}),a!==null&&m.jsx(hR,{project:n,seq:a,onClose:()=>s(null),onChanged:k}),$&&m.jsx(HO,{project:n,isPending:q.isPending,onCancel:()=>j(!1),onCreate:V=>q.mutate(V)})]})}function xR(e){return t=>e==="QA"?t.state==="QA"||t.state==="Review":e==="Done"?t.state==="Done"||t.state==="Canceled":t.state===e}function Jv({label:e,options:t,selected:n,onChange:a}){const[s,o]=M.useState(!1),c=M.useRef(null);M.useEffect(()=>{if(!s)return;const y=x=>{var v;(v=c.current)!=null&&v.contains(x.target)||o(!1)},g=x=>{x.key==="Escape"&&o(!1)};return window.addEventListener("click",y),window.addEventListener("keydown",g),()=>{window.removeEventListener("click",y),window.removeEventListener("keydown",g)}},[s]);const f=y=>{const g=new Set(n);g.has(y)?g.delete(y):g.add(y),a(g)},d=t.length===0,h=n.size;return m.jsxs("div",{ref:c,className:"relative",children:[m.jsxs("button",{type:"button",className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>!d&&o(y=>!y),disabled:d,"aria-haspopup":"listbox","aria-expanded":s,"aria-label":`按 ${e} 筛选`,children:[e,h>0&&m.jsx("span",{className:"ml-1 px-1.5 py-0.5 text-[10px] font-bold rounded-full bg-[var(--color-primary)] text-[var(--color-text)] border border-[var(--color-text)]",children:h}),m.jsx(yc,{size:11,strokeWidth:3,className:["transition-transform",s?"rotate-180":""].join(" ")})]}),s&&m.jsxs("div",{role:"listbox",className:"absolute left-0 top-full mt-2 z-20 min-w-[200px] max-h-64 overflow-auto nb-card p-2",style:{padding:8},children:[t.map(y=>{const g=n.has(y);return m.jsxs("label",{className:["flex items-center gap-2 px-2 py-1.5 rounded cursor-pointer text-sm font-[family-name:var(--font-mono)]",g?"bg-[var(--color-accent-mint)]":"hover:bg-[var(--color-bg-cream)]"].join(" "),children:[m.jsx("input",{type:"checkbox",checked:g,onChange:()=>f(y),className:"flex-shrink-0"}),m.jsx("span",{className:"truncate",children:y})]},y)}),h>0&&m.jsx("button",{type:"button",className:"w-full mt-2 pt-2 border-t-2 border-dashed border-[var(--color-text)] text-xs font-bold text-[var(--color-crashed)] text-center",onClick:()=>a(new Set),children:"清空选择"})]})]})}function vR(){return Ht("/api/workers/all")}function ER(e){return Ht(`/api/projects/${encodeURIComponent(e)}/workers`)}function SR(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/workers/${t}`)}async function sS(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok)throw new Error(`${n.status}: ${await n.text()}`);return n.json().catch(()=>({}))}function e0(e,t){return sS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/kill`)}function wR(e,t,n){return sS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/launch`,n?{seq:n}:void 0)}function og({state:e}){const n={running:{bg:"var(--color-running-bg)",color:"var(--color-running)",label:"running"},starting:{bg:"var(--color-secondary)",color:"var(--color-text)",label:"starting",icon:m.jsx(Wt,{size:9,strokeWidth:3,className:"animate-spin"})},stuck:{bg:"var(--color-stuck-bg)",color:"var(--color-stuck)",label:"stuck"},crashed:{bg:"var(--color-crashed-bg)",color:"var(--color-crashed)",label:"crashed",icon:m.jsx(SA,{size:9,strokeWidth:2.5})},idle:{bg:"var(--color-idle-bg)",color:"var(--color-idle)",label:"idle"}}[e];return m.jsxs("span",{className:"nb-status inline-flex items-center gap-1",style:{background:n.bg,color:n.color},children:[n.icon,n.label]})}function cg(e){if(e==null||e<=0)return"—";const t=Math.floor(e/1e3),n=Math.floor(t/3600),a=Math.floor(t%3600/60),s=t%60;return n>0?`${n}h ${a}m`:a>0?`${a}m ${s}s`:`${s}s`}function _R(e){if(e==null||e<=0)return"text-[var(--color-text-muted)]";const t=e/6e4;return t<10?"text-[var(--color-running)]":t<60?"text-[var(--color-stuck)]":"text-[var(--color-crashed)]"}function ug(e){const t=Date.now()-new Date(e).getTime();return t<6e4?`${Math.floor(t/1e3)}s 前`:t<36e5?`${Math.floor(t/6e4)}m 前`:`${Math.floor(t/36e5)}h 前`}function kR({alerts:e,selected:t,onSelect:n}){return e.length===0?m.jsxs("div",{className:"nb-card bg-[var(--color-running-bg)] flex items-center gap-3",children:[m.jsx(Pp,{size:18,strokeWidth:2.5,className:"text-[var(--color-running)]"}),m.jsx("span",{className:"text-sm font-bold text-[var(--color-running)]",children:"全部 worker 健康"})]}):m.jsxs("section",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2 flex items-center gap-2 text-[var(--color-crashed)]",children:[m.jsx(RA,{size:14,strokeWidth:2.5}),"Alerts (",e.length,")"]}),m.jsx("div",{className:"flex flex-col gap-2",children:e.map(a=>{const s=(t==null?void 0:t.project)===a.project&&(t==null?void 0:t.slot)===a.slot;return m.jsxs("button",{type:"button",onClick:()=>n(a.project,a.slot),className:["nb-card p-3 text-left",a.state==="crashed"?"bg-[var(--color-crashed-bg)]":"bg-[var(--color-stuck-bg)]",s?"ring-4 ring-[var(--color-text)]":""].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[m.jsx(og,{state:a.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold",children:[a.project,"/worker-",a.slot]}),a.card&&m.jsxs("span",{className:"truncate",children:["#",a.card.seq," ",a.card.title]}),m.jsxs("span",{className:"ml-auto text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] flex items-center gap-1",children:[m.jsx(MC,{size:10,strokeWidth:2.5}),cg(a.runtimeMs)]})]}),a.markerUpdatedAt&&m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-1 font-[family-name:var(--font-mono)]",children:a.state==="crashed"?"PID 已死。":`marker 停 ${ug(a.markerUpdatedAt)}。`})]},`${a.project}-${a.slot}`)})})]})}function NR({active:e,selected:t,onSelect:n}){return e.length===0?m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)]",children:m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] italic",children:"没有 worker 在运行。"})}):m.jsxs("section",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2 flex items-center gap-2",children:[m.jsx(jf,{size:14,strokeWidth:2.5}),"Active (",e.length,")"]}),m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:e.map(a=>{const s=(t==null?void 0:t.project)===a.project&&(t==null?void 0:t.slot)===a.slot;return m.jsxs("button",{type:"button",onClick:()=>n(a.project,a.slot),className:["nb-card p-3 text-left",a.state==="starting"?"bg-[var(--color-secondary)]":"bg-[var(--color-running-bg)]",s?"ring-4 ring-[var(--color-text)]":""].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[m.jsx(og,{state:a.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-sm flex-1 truncate",children:[a.project,"/worker-",a.slot]}),m.jsx("span",{className:`text-xs font-[family-name:var(--font-mono)] ${_R(a.runtimeMs)}`,children:cg(a.runtimeMs)})]}),a.card&&m.jsxs("div",{className:"text-sm font-semibold mb-1 truncate",children:["#",a.card.seq," · ",a.card.title]}),m.jsxs("div",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] flex items-center gap-2 mb-1",children:[a.stage&&m.jsxs("span",{children:["stage: ",a.stage]}),a.markerUpdatedAt&&m.jsxs("span",{className:"ml-auto",children:["marker ",ug(a.markerUpdatedAt)]})]}),a.lastLogLine&&m.jsxs("div",{className:"text-[11px] font-[family-name:var(--font-mono)] text-[var(--color-text-muted)] bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded px-2 py-1 mt-2 truncate",children:[m.jsx(t1,{size:9,strokeWidth:2.5,className:"inline-block mr-1 align-text-bottom"}),a.lastLogLine.msg]})]},`${a.project}-${a.slot}`)})})]})}function TR({capacity:e,selected:t,onSelect:n}){return e.length===0?null:m.jsxs("section",{children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2",children:"Capacity"}),m.jsx("div",{className:"nb-card p-0 overflow-hidden",children:m.jsxs("table",{className:"w-full text-sm",children:[m.jsx("thead",{children:m.jsxs("tr",{className:"bg-[var(--color-bg-cream)] border-b-2 border-[var(--color-text)]",children:[m.jsx("th",{className:"px-3 py-2 text-left font-bold text-xs uppercase tracking-wider",children:"项目"}),m.jsx("th",{className:"px-3 py-2 text-left font-bold text-xs uppercase tracking-wider",children:"占用"}),m.jsx("th",{className:"px-3 py-2 text-right font-bold text-xs uppercase tracking-wider",children:"running"}),m.jsx("th",{className:"px-3 py-2 text-right font-bold text-xs uppercase tracking-wider",children:"其它"}),m.jsx("th",{className:"px-3 py-2"})]})}),m.jsx("tbody",{children:e.map(a=>{const s=a.running+a.starting+a.stuck+a.crashed,o=(t==null?void 0:t.project)===a.project;return m.jsxs("tr",{onClick:()=>n(a.project),className:["border-b border-dashed border-[var(--color-border-light)] last:border-0 cursor-pointer hover:bg-[var(--color-accent-yellow)]",o?"bg-[var(--color-accent-yellow)]":""].join(" "),children:[m.jsx("td",{className:"px-3 py-2 font-[family-name:var(--font-mono)] font-bold",children:a.project}),m.jsx("td",{className:"px-3 py-2",children:m.jsx(CR,{total:a.total,cap:a})}),m.jsxs("td",{className:"px-3 py-2 text-right font-[family-name:var(--font-mono)]",children:[m.jsx("span",{className:"text-[var(--color-running)] font-bold",children:a.running}),m.jsxs("span",{className:"text-[var(--color-text-muted)]",children:["/",a.total]})]}),m.jsxs("td",{className:"px-3 py-2 text-right text-xs font-[family-name:var(--font-mono)] text-[var(--color-text-muted)]",children:[a.starting>0&&m.jsxs("span",{className:"mr-2",children:["starting ",a.starting]}),a.stuck>0&&m.jsxs("span",{className:"text-[var(--color-stuck)] font-bold mr-2",children:["stuck ",a.stuck]}),a.crashed>0&&m.jsxs("span",{className:"text-[var(--color-crashed)] font-bold mr-2",children:["crashed ",a.crashed]}),s===0&&m.jsx("span",{children:"idle"})]}),m.jsx("td",{className:"px-3 py-2 text-right",children:m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"详情 →"})})]},a.project)})})]})})]})}function CR({total:e,cap:t}){const n=[];for(let a=0;a<t.crashed;a++)n.push("crashed");for(let a=0;a<t.stuck;a++)n.push("stuck");for(let a=0;a<t.starting;a++)n.push("starting");for(let a=0;a<t.running;a++)n.push("running");for(let a=0;a<t.idle;a++)n.push("idle");return m.jsxs("div",{className:"flex gap-1 items-center",children:[n.map((a,s)=>m.jsx("span",{className:"inline-block w-3 h-3 rounded-full border-2 border-[var(--color-text)]",style:{background:AR(a)},title:a},s)),m.jsxs("span",{className:"text-xs text-[var(--color-text-muted)] ml-2 font-[family-name:var(--font-mono)]",children:[e," slot",e!==1?"s":""]})]})}function AR(e){switch(e){case"running":return"var(--color-running-bg)";case"starting":return"var(--color-secondary)";case"stuck":return"var(--color-stuck-bg)";case"crashed":return"var(--color-crashed-bg)";default:return"var(--color-idle-bg)"}}function OR({project:e,initialSlot:t,onChange:n}){var d;const a=lt({queryKey:["workers",e],queryFn:()=>ER(e),refetchInterval:3e3}),s=((d=a.data)==null?void 0:d.data)??[],[o,c]=M.useState(null);M.useEffect(()=>{if(s.length===0){c(null);return}const h=s[0].slot;c(y=>y!=null&&s.some(g=>g.slot===y)?y:t!=null&&s.some(g=>g.slot===t)?t:h)},[e,t,s.length]);const f=s.find(h=>h.slot===o)??null;return m.jsxs("div",{className:"flex flex-col h-full",children:[m.jsxs("div",{className:"px-4 py-3 border-b-2 border-[var(--color-text)] bg-[var(--color-bg-cream)]",children:[m.jsxs("div",{className:"flex items-center justify-between mb-2",children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold truncate",children:e}),m.jsx(ds,{to:`/board?project=${encodeURIComponent(e)}`,className:"text-xs underline text-[var(--color-text-muted)] hover:text-[var(--color-text)]",children:"看板 →"})]}),a.isLoading&&s.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 workers…"}):s.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"该项目没有 worker slot。"}):m.jsx("div",{className:"flex flex-wrap gap-2",children:s.map(h=>m.jsx(RR,{worker:h,active:h.slot===o,onClick:()=>c(h.slot)},h.slot))})]}),f?m.jsx(MR,{project:e,worker:f,onChange:n}):m.jsx("div",{className:"flex-1 flex items-center justify-center p-6 text-center",children:m.jsx("p",{className:"text-sm text-[var(--color-text-muted)]",children:s.length===0?"无 worker":"请选择一个 worker"})})]})}function RR({worker:e,active:t,onClick:n}){return m.jsxs("button",{type:"button",onClick:n,className:["nb-card p-2 text-left min-w-[130px] transition-transform",t?"ring-4 ring-[var(--color-text)]":"opacity-80 hover:opacity-100"].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[m.jsx(og,{state:e.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs",children:["worker-",e.slot]})]}),e.card?m.jsxs("div",{className:"text-[11px] truncate font-[family-name:var(--font-mono)]",children:["#",e.card.seq," ",e.card.title]}):m.jsx("div",{className:"text-[11px] text-[var(--color-text-muted)] italic",children:"空闲"})]})}function MR({project:e,worker:t,onChange:n}){var h,y;const{confirm:a,alert:s}=si(),o=t.state==="crashed"||t.state==="stuck",c=lt({queryKey:["worker-detail",e,t.slot],queryFn:()=>SR(e,t.slot),refetchInterval:3e3}),f=((h=c.data)==null?void 0:h.recentOutput)??[],d=((y=c.data)==null?void 0:y.recentLogs)??[];return m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"flex-1 overflow-auto p-4 flex flex-col gap-4",children:[t.card?m.jsxs("div",{children:[m.jsx("div",{className:"text-xs font-bold uppercase tracking-wider text-[var(--color-text-muted)] mb-1",children:"当前卡片"}),m.jsxs("div",{className:"text-sm font-semibold break-words",children:["#",t.card.seq," · ",t.card.title]})]}):m.jsx("div",{className:"text-sm text-[var(--color-text-muted)] italic",children:"slot 空闲,没有当前卡片。"}),m.jsxs("dl",{className:"grid grid-cols-[100px_1fr] gap-y-2 text-sm",children:[m.jsx("dt",{className:"font-bold",children:"Stage"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.stage??"—"}),m.jsx("dt",{className:"font-bold",children:"PID"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.pid??"—"}),m.jsx("dt",{className:"font-bold",children:"Runtime"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:cg(t.runtimeMs)}),m.jsx("dt",{className:"font-bold",children:"Started"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:t.startedAt?new Date(t.startedAt).toLocaleString():"—"}),m.jsx("dt",{className:"font-bold",children:"Marker"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:t.markerUpdatedAt?ug(t.markerUpdatedAt):"—"})]}),m.jsxs("div",{children:[m.jsxs("div",{className:"text-xs font-bold uppercase tracking-wider text-[var(--color-text-muted)] mb-1 flex items-center gap-1",children:[m.jsx(t1,{size:10,strokeWidth:2.5}),"Claude 输出 · 最近 ",f.length," 行"]}),c.isLoading&&f.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载中…"}):f.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"还没收到 session 输出。Worker 刚启动时需要几秒。"}):m.jsx("pre",{className:"text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded p-2 max-h-80 overflow-auto whitespace-pre-wrap break-words",children:f.map(g=>`${g.ts?`${g.ts} [${g.kind}] `:`[${g.kind}] `}${g.text}`).join(`
|
|
477
|
+
`).trim()}function vm(e){return dp(e,"描述")}function hR({project:e,seq:t,onClose:n,onChanged:a}){var K,oe,V,pe,R,L,J,C,me,_e,ve;const s=qn(),{confirm:o,alert:c}=si(),{data:f,isLoading:d,isError:h,error:y,refetch:g}=lt({queryKey:["card",e,t],queryFn:()=>GO(e,t)}),[x,v]=M.useState(!1),[S,w]=M.useState(""),[k,_]=M.useState(""),[A,T]=M.useState(new Set),[D,$]=M.useState([]),[j,q]=M.useState(""),U=lt({queryKey:["skills-all",e],queryFn:()=>lg(e),enabled:x}),O=((oe=(K=lt({queryKey:["projects"],queryFn:_r,refetchInterval:1e4}).data)==null?void 0:K.data.find(ce=>ce.name===e))==null?void 0:oe.pipelineStatus)==="running";M.useEffect(()=>{x&&f&&(w(f.title),_(vm(f.body)),T(new Set(f.skills)),$([...f.labels]))},[x,f]),M.useEffect(()=>{const ce=ke=>{ke.key==="Escape"&&(x?v(!1):n())};return window.addEventListener("keydown",ce),()=>window.removeEventListener("keydown",ce)},[n,x]);const P=Pn({mutationFn:()=>{if(!f)throw new Error("no data");const ce={},ke=S.trim();ke&&ke!==f.title&&(ce.title=ke);const Ke=vm(f.body);k!==Ke&&(ce.description=k);const Dt=[...A].sort(),yn=[...f.skills].sort();return JSON.stringify(Dt)!==JSON.stringify(yn)&&(ce.skills=Dt),JSON.stringify(D)!==JSON.stringify(f.labels)&&(ce.labels=D),Object.keys(ce).length===0?Promise.resolve({ok:!0,noop:!0}):WO(e,t,ce)},onSuccess:()=>{s.invalidateQueries({queryKey:["card",e,t]}),s.invalidateQueries({queryKey:["cards",e]}),v(!1),a()},onError:ce=>{c({title:"保存失败",body:ce instanceof Error?ce.message:String(ce)})}}),G=M.useMemo(()=>{if(!x||!f)return!1;if(S.trim()!==f.title||k!==vm(f.body))return!0;const ce=[...A].sort(),ke=[...f.skills].sort();return JSON.stringify(ce)!==JSON.stringify(ke)||JSON.stringify(D)!==JSON.stringify(f.labels)},[x,f,S,k,A,D]),le=ce=>{const ke=new Set(A);ke.has(ce)?ke.delete(ce):ke.add(ce),T(ke)},ae=()=>{const ce=j.trim();if(ce){if(D.includes(ce)){q("");return}$([...D,ce]),q("")}},W=ce=>{$(D.filter(ke=>ke!==ce))};return m.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"card-modal-title",className:"fixed inset-0 z-40 flex items-start justify-center p-6 bg-black/30 overflow-auto",children:m.jsxs("div",{className:"nb-card mt-12 w-full max-w-3xl bg-[var(--color-bg)]",children:[m.jsxs("header",{className:"flex items-start justify-between gap-4 mb-4",children:[m.jsxs("div",{className:"flex-1 min-w-0",children:[m.jsxs("div",{className:"flex items-center gap-3 mb-1",children:[m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs px-2 py-0.5 bg-[var(--color-accent-purple)] border-2 border-[var(--color-text)] rounded-full",children:["#",t]}),(f==null?void 0:f.state)&&m.jsx("span",{className:"font-[family-name:var(--font-mono)] text-xs px-2 py-0.5 bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-full font-semibold",children:f.state}),x&&m.jsx("span",{className:"text-xs font-bold text-[var(--color-stuck)]",children:"⚠ 编辑中"})]}),x?m.jsx("input",{type:"text",className:"nb-input w-full font-[family-name:var(--font-heading)] text-xl font-bold",value:S,onChange:ce=>w(ce.target.value),maxLength:200,"aria-label":"卡片标题"}):m.jsx("h2",{id:"card-modal-title",className:"font-[family-name:var(--font-heading)] text-2xl font-bold break-words",children:(f==null?void 0:f.title)??"加载中…"})]}),m.jsxs("div",{className:"flex gap-2 flex-shrink-0",children:[!x&&f&&m.jsxs("button",{onClick:()=>v(!0),className:"nb-btn",style:{padding:"6px 12px"},type:"button","aria-label":"编辑卡片",children:[m.jsx(Hp,{size:12,strokeWidth:2.5})," 编辑"]}),m.jsx("button",{onClick:n,className:"nb-btn nb-btn-mint p-2","aria-label":"关闭",type:"button",children:m.jsx(Er,{size:14,strokeWidth:3})})]})]}),d&&m.jsx("p",{className:"text-[var(--color-text-muted)]",children:"加载中…"}),h&&m.jsxs("p",{className:"text-[var(--color-crashed)]",children:["加载失败: ",y instanceof Error?y.message:String(y)]}),f&&m.jsxs("div",{className:"flex flex-col gap-4",children:[f.branch&&!x&&m.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[m.jsx(QC,{size:14}),m.jsx("span",{className:"font-[family-name:var(--font-mono)]",children:f.branch})]}),x?m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Skills"}),U.isLoading&&m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 skill 列表…"}),U.data&&U.data.data.length>0&&m.jsx("div",{className:"flex flex-wrap gap-1.5",children:U.data.data.map(ce=>{const ke=A.has(ce.name);return m.jsx("button",{type:"button",onClick:()=>le(ce.name),"aria-pressed":ke,className:["px-2.5 py-1 text-xs font-[family-name:var(--font-mono)] rounded-full border-2 transition-all",ke?"bg-[var(--color-accent-mint)] border-[var(--color-text)] shadow-[2px_2px_0_var(--color-text)] font-bold":"bg-[var(--color-bg)] border-[var(--color-border-light)] hover:border-[var(--color-text)]"].join(" "),children:ce.name},ce.name)})})]}),m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Labels"}),m.jsxs("div",{className:"flex flex-wrap gap-1.5 items-center",children:[D.map(ce=>m.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 text-xs font-[family-name:var(--font-mono)] bg-[var(--color-accent-yellow)] border-2 border-[var(--color-text)] rounded-full",children:[ce,m.jsx("button",{type:"button",onClick:()=>W(ce),className:"hover:text-[var(--color-crashed)]","aria-label":`删除 ${ce}`,children:m.jsx(Er,{size:10,strokeWidth:3})})]},ce)),m.jsx("input",{type:"text",className:"nb-input",style:{padding:"4px 8px",fontSize:12,width:140},placeholder:"+ 添加 label",value:j,onChange:ce=>q(ce.target.value),onKeyDown:ce=>{ce.key==="Enter"&&!ce.nativeEvent.isComposing&&(ce.preventDefault(),ae())}}),j&&m.jsx("button",{type:"button",className:"nb-btn",style:{padding:"2px 6px",fontSize:11},onClick:ae,"aria-label":"添加 label",children:m.jsx(Xi,{size:10,strokeWidth:3})})]}),m.jsx("p",{className:"text-[10px] text-[var(--color-text-muted)] mt-1",children:"注意:AI-PIPELINE / STARTED-* / COMPLETED-* / NEEDS-FIX 由流水线自动管理,手动改可能被覆盖"})]})]}):m.jsxs(m.Fragment,{children:[f.skills.length>0&&m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Skills"}),m.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:f.skills.map(ce=>m.jsx(iS,{name:ce},ce))})]}),f.labels.length>0&&m.jsxs("div",{children:[m.jsx("div",{className:"text-sm font-bold mb-1.5",children:"Labels"}),m.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:f.labels.map(ce=>m.jsx(aS,{label:ce,kind:ce==="NEEDS-FIX"?"warn":"default"},ce))})]})]}),x?m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"描述"}),m.jsx("textarea",{className:"nb-input w-full font-[family-name:var(--font-mono)] text-xs",style:{minHeight:180,resize:"vertical"},value:k,onChange:ce=>_(ce.target.value),"aria-label":"卡片描述"}),m.jsx("p",{className:"text-[10px] text-[var(--color-text-muted)] mt-1",children:'只替换 "## 描述" 段的内容;检查清单和日志段不动。'})]}),(((C=f.checklist)==null?void 0:C.total)??0)>0&&m.jsxs("div",{className:"nb-card bg-[var(--color-bg-cream)] p-3",children:[m.jsx("div",{className:"flex items-center justify-between mb-2",children:m.jsxs("span",{className:"font-bold text-sm",children:["检查清单 ",((me=f.checklist)==null?void 0:me.done)??0,"/",((_e=f.checklist)==null?void 0:_e.total)??0]})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((ve=f.checklist)==null?void 0:ve.items)??[]).map((ce,ke)=>m.jsxs("li",{className:`flex items-start gap-2 ${ce.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:ce.done?"✓":"○"}),m.jsx("span",{children:ce.text})]},ke))})]})]}):m.jsxs(m.Fragment,{children:[m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"描述"}),m.jsx("pre",{className:"text-xs whitespace-pre-wrap font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4 max-h-64 overflow-auto",children:dp(f.body,"描述")||"(空)"})]}),m.jsxs("div",{children:[m.jsxs("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:["检查清单 ",m.jsxs("span",{className:"text-[var(--color-text-muted)] normal-case tracking-normal",children:[((V=f.checklist)==null?void 0:V.done)??0,"/",((pe=f.checklist)==null?void 0:pe.total)??0]})]}),m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)] p-3",children:(((R=f.checklist)==null?void 0:R.total)??0)>0?m.jsxs(m.Fragment,{children:[m.jsx("div",{className:"flex items-center justify-end mb-2",children:m.jsx("div",{className:"w-24 h-2 bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded-full overflow-hidden",children:m.jsx("div",{className:"h-full bg-[var(--color-cta)]",style:{width:`${((L=f.checklist)==null?void 0:L.percent)??0}%`}})})}),m.jsx("ul",{className:"text-sm space-y-1",children:(((J=f.checklist)==null?void 0:J.items)??[]).map((ce,ke)=>m.jsxs("li",{className:`flex items-start gap-2 ${ce.done?"opacity-60 line-through":""}`,children:[m.jsx("span",{children:ce.done?"✓":"○"}),m.jsx("span",{children:ce.text})]},ke))})]}):m.jsxs("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:["暂无清单项。在描述里用 ",m.jsx("code",{className:"font-[family-name:var(--font-mono)]",children:"- [ ] 项"})," 语法添加。"]})})]}),m.jsxs("div",{children:[m.jsx("h3",{className:"font-[family-name:var(--font-heading)] text-sm font-bold mb-2 uppercase tracking-wider",children:"日志"}),m.jsx("pre",{className:"text-xs whitespace-pre-wrap font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded-lg p-4 max-h-64 overflow-auto",children:dp(f.body,"日志")||"(空)"})]})]}),m.jsx("div",{className:"flex gap-2 pt-2 border-t-2 border-[var(--color-border-light)] justify-end flex-wrap",children:x?m.jsxs(m.Fragment,{children:[m.jsx("button",{className:"nb-btn",type:"button",onClick:()=>{v(!1),g()},disabled:P.isPending,children:"取消"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",onClick:()=>P.mutate(),disabled:!G||!S.trim()||P.isPending,"aria-label":"保存卡片修改",children:[P.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Df,{size:14,strokeWidth:3}),"保存"]})]}):m.jsxs(m.Fragment,{children:[m.jsxs("button",{className:"nb-btn nb-btn-primary",type:"button",disabled:f.state==="Done"||O,title:f.state==="Done"?"卡片已完成;先拖回 Todo 再启动":O?"Pipeline 正在跑——supervisor 会自动 dispatch,无需手动启动":void 0,onClick:async()=>{try{await VO(e,t),a()}catch(ce){c({title:"启动 worker 失败",body:ce instanceof Error?ce.message:String(ce)})}},children:[m.jsx(Kp,{size:14,strokeWidth:3}),"启动 worker"]}),m.jsxs("button",{className:"nb-btn nb-btn-yellow",type:"button",onClick:async()=>{if(await o({title:`重置卡片 #${t}`,body:"卡片状态会回到初始,已做的 checklist 会清空。",confirm:"重置",danger:!0}))try{await QO(e,t),a(),n()}catch(ke){c({title:"重置失败",body:ke instanceof Error?ke.message:String(ke)})}},children:[m.jsx(WE,{size:14,strokeWidth:2.5}),"重置卡片"]}),m.jsxs("button",{className:"nb-btn",style:{background:"var(--color-crashed)",color:"var(--color-bg)"},type:"button",onClick:async()=>{if(!(!await o({title:`删除卡片 #${t}`,body:`即将删除 "${f.title}"。此操作不可恢复(md 文件将被物理删除)。是否继续?`,confirm:"继续",danger:!0})||!await o({title:"最终确认",body:`请再次确认删除卡片 #${t}。`,confirm:"确定删除",danger:!0})))try{await YO(e,t),a(),n()}catch(Ke){c({title:"删除失败",body:Ke instanceof Error?Ke.message:String(Ke)})}},"aria-label":"删除卡片",children:[m.jsx(Il,{size:14,strokeWidth:2.5}),"删除卡片"]})]})})]})]})})}function mR({current:e,onChange:t}){const[n,a]=M.useState(!1),s=M.useRef(null),{data:o}=lt({queryKey:["projects"],queryFn:_r});return M.useEffect(()=>{const c=f=>{var d;(d=s.current)!=null&&d.contains(f.target)||a(!1)};return document.addEventListener("mousedown",c),()=>document.removeEventListener("mousedown",c)},[]),m.jsxs("div",{className:"relative",ref:s,children:[m.jsxs("button",{type:"button",className:"inline-flex items-center gap-2 px-3 py-2 bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl shadow-[3px_3px_0_var(--color-text)] font-[family-name:var(--font-mono)] text-sm font-bold hover:-translate-x-px hover:-translate-y-px hover:shadow-[4px_4px_0_var(--color-text)] transition-[transform,box-shadow] duration-150",onClick:()=>a(c=>!c),children:[e,m.jsx(yc,{size:14,strokeWidth:2.5})]}),n&&o&&m.jsx("div",{className:"absolute right-0 mt-2 z-20 min-w-[200px] bg-[var(--color-bg)] border-[3px] border-[var(--color-text)] rounded-xl shadow-[5px_5px_0_var(--color-text)] overflow-hidden",children:o.data.map(c=>m.jsxs("button",{type:"button",onClick:()=>{t(c.name),a(!1)},className:["w-full text-left px-4 py-2 text-sm font-semibold",c.name===e?"bg-[var(--color-accent-mint)]":"hover:bg-[var(--color-bg-cream)]"].join(" "),children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)]",children:c.name}),m.jsxs("span",{className:"ml-2 text-xs text-[var(--color-text-muted)]",children:[c.cards.total," cards"]})]},c.name))})]})}const pR=[{state:"Planning",label:"Planning",bg:"var(--color-accent-purple)"},{state:"Backlog",label:"Backlog",bg:"var(--color-bg-cream)"},{state:"Todo",label:"Todo",bg:"var(--color-accent-yellow)"},{state:"Inprogress",label:"Inprogress",bg:"var(--color-secondary)"},{state:"QA",label:"QA / Review",bg:"var(--color-accent-pink)"},{state:"Done",label:"Done",bg:"var(--color-accent-mint)"}],rS="sps-console:last-board-project";function gR(){if(typeof window>"u")return null;try{return localStorage.getItem(rS)}catch{return null}}function bR(e){if(!(typeof window>"u"))try{localStorage.setItem(rS,e)}catch{}}function yR(){var W,K,oe;const[e,t]=QE(),n=e.get("project"),[a,s]=M.useState(null),[o,c]=M.useState(""),[f,d]=M.useState(()=>new Set),[h,y]=M.useState(()=>new Set),{confirm:g,alert:x}=si();nR(n);const v=lt({queryKey:["projects"],queryFn:_r}),S=lt({queryKey:["cards",n],queryFn:()=>KO(n??""),enabled:!!n}),w=qn(),k=()=>{w.invalidateQueries({queryKey:["cards",n]}),w.invalidateQueries({queryKey:["projects"]}),w.invalidateQueries({queryKey:["pipeline-status",n]})},_=V=>{t({project:V})};M.useEffect(()=>{var pe;if(n){bR(n);return}const V=gR();V&&((pe=v.data)!=null&&pe.data.some(R=>R.name===V))&&t({project:V},{replace:!0})},[n,v.data,t]);const A=Pn({mutationFn:()=>JO(n),onSuccess:()=>{k()},onError:V=>{x({title:"启动 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),T=Pn({mutationFn:()=>eR(n),onSuccess:()=>k(),onError:V=>{x({title:"停止 pipeline 失败",body:V instanceof Error?V.message:String(V)})}}),D=Pn({mutationFn:()=>tR(n,{all:!0}),onSuccess:()=>k(),onError:V=>{x({title:"重置失败",body:V instanceof Error?V.message:String(V)})}}),[$,j]=M.useState(!1),q=Pn({mutationFn:V=>XO(n,V),onSuccess:()=>{k(),j(!1)},onError:V=>{x({title:"新建卡片失败",body:V instanceof Error?V.message:String(V)})}}),U=Pn({mutationFn:({seq:V,state:pe})=>ZO(n,V,pe),onMutate:async({seq:V,state:pe})=>{await w.cancelQueries({queryKey:["cards",n]});const R=w.getQueryData(["cards",n]);return R&&w.setQueryData(["cards",n],{...R,data:R.data.map(L=>L.seq===V?{...L,state:pe}:L)}),{prev:R}},onError:(V,pe,R)=>{R!=null&&R.prev&&w.setQueryData(["cards",n],R.prev),x({title:"移动卡片失败",body:V instanceof Error?V.message:String(V)})},onSettled:()=>{w.invalidateQueries({queryKey:["cards",n]})}}),Z=((W=S.data)==null?void 0:W.data)??[],{allSkills:O,allLabels:P}=M.useMemo(()=>{const V=new Set,pe=new Set;for(const R of Z){for(const L of R.skills)V.add(L);for(const L of R.labels)pe.add(L)}return{allSkills:[...V].sort(),allLabels:[...pe].sort()}},[Z]);if(!n)return m.jsxs("div",{className:"flex flex-col gap-6 max-w-4xl",children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold",children:"看板"}),m.jsxs("div",{className:"nb-card bg-[var(--color-accent-yellow)] max-w-2xl",children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-xl font-bold mb-3",children:"选择一个项目 🎯"}),m.jsx("p",{className:"text-sm mb-4 text-[var(--color-text-muted)]",children:"看板按项目分。挑一个开始:"}),m.jsx("div",{className:"flex flex-wrap gap-2",children:(K=v.data)==null?void 0:K.data.map(V=>m.jsx("button",{className:"nb-btn nb-btn-blue",onClick:()=>_(V.name),type:"button",children:V.name},V.name))})]})]});const G=Z.filter(V=>{if(o){const pe=o.toLowerCase();if(!(V.title.toLowerCase().includes(pe)||V.skills.some(L=>L.toLowerCase().includes(pe))||V.labels.some(L=>L.toLowerCase().includes(pe))))return!1}return!(f.size>0&&!V.skills.some(R=>f.has(R))||h.size>0&&!V.labels.some(R=>h.has(R)))}),le=(oe=v.data)==null?void 0:oe.data.find(V=>V.name===n),ae=(le==null?void 0:le.pipelineStatus)==="running";return m.jsxs("div",{className:"flex flex-col gap-4 max-w-full flex-1 min-h-0",children:[m.jsxs("header",{className:"flex items-center justify-between flex-wrap gap-3 shrink-0",children:[m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"看板 ✨"}),m.jsx("p",{className:"text-[var(--color-text-muted)] text-sm mt-1",children:le?`${le.name} · ${le.cards.total} cards · ${le.workers.active} workers 活跃`:"加载中…"})]}),m.jsxs("div",{className:"flex items-center gap-3 flex-wrap",children:[m.jsx(mR,{current:n,onChange:_}),m.jsxs("button",{className:ae?"nb-btn nb-btn-danger":"nb-btn nb-btn-primary",onClick:()=>ae?T.mutate():A.mutate(),disabled:A.isPending||T.isPending,type:"button","aria-label":ae?"停止 pipeline":"启动 pipeline",title:ae?"停止 pipeline":"启动 pipeline",children:[A.isPending||T.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):ae?m.jsx(e1,{size:14,strokeWidth:3}):m.jsx(Kp,{size:14,strokeWidth:3}),ae?"停止":"启动"]}),m.jsxs("button",{className:"nb-btn nb-btn-yellow",type:"button",onClick:async()=>{await g({title:"重置整个流水线",body:"这会清空所有卡片的运行状态、worker marker、分支。不可撤销。",confirm:"重置全部",danger:!0})&&D.mutate()},disabled:D.isPending,children:[D.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(WE,{size:14,strokeWidth:2.5}),"重置"]}),m.jsxs("button",{className:"nb-btn nb-btn-mint",type:"button",onClick:()=>j(!0),disabled:q.isPending,children:[q.isPending?m.jsx(Wt,{size:14,strokeWidth:3,className:"animate-spin"}):m.jsx(Xi,{size:14,strokeWidth:3}),"新卡片"]})]})]}),m.jsxs("div",{className:"flex items-center gap-3 flex-wrap shrink-0",children:[m.jsxs("div",{className:"relative flex-1 max-w-md",children:[m.jsx(xf,{size:14,className:"absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-subtle)]"}),m.jsx("input",{className:"nb-input pl-9 w-full",placeholder:"搜索标题 / skill / label…",value:o,onChange:V=>c(V.target.value),"aria-label":"搜索卡片"})]}),m.jsx(Jv,{label:"skill",options:O,selected:f,onChange:d}),m.jsx(Jv,{label:"label",options:P,selected:h,onChange:y}),(o||f.size>0||h.size>0)&&m.jsxs("button",{className:"nb-btn",style:{padding:"4px 10px",fontSize:11},onClick:()=>{c(""),d(new Set),y(new Set)},type:"button","aria-label":"清空筛选",children:[m.jsx(Er,{size:11,strokeWidth:3}),"清空"]}),m.jsxs("span",{className:"text-xs text-[var(--color-text-muted)] flex items-center gap-1 font-[family-name:var(--font-mono)]",children:[m.jsx(KC,{size:12}),G.length," / ",Z.length]})]}),S.isError&&m.jsxs("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:[m.jsx("p",{className:"font-semibold",children:"加载卡片失败"}),m.jsx("p",{className:"text-sm mt-1 text-[var(--color-text-muted)]",children:S.error instanceof Error?S.error.message:String(S.error)})]}),!S.isError&&m.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 auto-rows-fr gap-3 flex-1 min-h-0",children:pR.map(V=>m.jsx(dR,{label:V.label,bg:V.bg,cards:G.filter(xR(V.state)),onCardClick:pe=>s(pe.seq),onDropCard:pe=>U.mutate({seq:pe,state:V.state})},V.state))}),a!==null&&m.jsx(hR,{project:n,seq:a,onClose:()=>s(null),onChanged:k}),$&&m.jsx(HO,{project:n,isPending:q.isPending,onCancel:()=>j(!1),onCreate:V=>q.mutate(V)})]})}function xR(e){return t=>e==="QA"?t.state==="QA"||t.state==="Review":e==="Done"?t.state==="Done"||t.state==="Canceled":t.state===e}function Jv({label:e,options:t,selected:n,onChange:a}){const[s,o]=M.useState(!1),c=M.useRef(null);M.useEffect(()=>{if(!s)return;const y=x=>{var v;(v=c.current)!=null&&v.contains(x.target)||o(!1)},g=x=>{x.key==="Escape"&&o(!1)};return window.addEventListener("click",y),window.addEventListener("keydown",g),()=>{window.removeEventListener("click",y),window.removeEventListener("keydown",g)}},[s]);const f=y=>{const g=new Set(n);g.has(y)?g.delete(y):g.add(y),a(g)},d=t.length===0,h=n.size;return m.jsxs("div",{ref:c,className:"relative",children:[m.jsxs("button",{type:"button",className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>!d&&o(y=>!y),disabled:d,"aria-haspopup":"listbox","aria-expanded":s,"aria-label":`按 ${e} 筛选`,children:[e,h>0&&m.jsx("span",{className:"ml-1 px-1.5 py-0.5 text-[10px] font-bold rounded-full bg-[var(--color-primary)] text-[var(--color-text)] border border-[var(--color-text)]",children:h}),m.jsx(yc,{size:11,strokeWidth:3,className:["transition-transform",s?"rotate-180":""].join(" ")})]}),s&&m.jsxs("div",{role:"listbox",className:"absolute left-0 top-full mt-2 z-20 min-w-[200px] max-h-64 overflow-auto nb-card p-2",style:{padding:8},children:[t.map(y=>{const g=n.has(y);return m.jsxs("label",{className:["flex items-center gap-2 px-2 py-1.5 rounded cursor-pointer text-sm font-[family-name:var(--font-mono)]",g?"bg-[var(--color-accent-mint)]":"hover:bg-[var(--color-bg-cream)]"].join(" "),children:[m.jsx("input",{type:"checkbox",checked:g,onChange:()=>f(y),className:"flex-shrink-0"}),m.jsx("span",{className:"truncate",children:y})]},y)}),h>0&&m.jsx("button",{type:"button",className:"w-full mt-2 pt-2 border-t-2 border-dashed border-[var(--color-text)] text-xs font-bold text-[var(--color-crashed)] text-center",onClick:()=>a(new Set),children:"清空选择"})]})]})}function vR(){return Ht("/api/workers/all")}function ER(e){return Ht(`/api/projects/${encodeURIComponent(e)}/workers`)}function SR(e,t){return Ht(`/api/projects/${encodeURIComponent(e)}/workers/${t}`)}async function sS(e,t){const n=await fetch(e,{method:"POST",headers:t?{"Content-Type":"application/json"}:void 0,body:t?JSON.stringify(t):void 0});if(!n.ok)throw new Error(`${n.status}: ${await n.text()}`);return n.json().catch(()=>({}))}function e0(e,t){return sS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/kill`)}function wR(e,t,n){return sS(`/api/projects/${encodeURIComponent(e)}/workers/${t}/launch`,n?{seq:n}:void 0)}function og({state:e}){const n={running:{bg:"var(--color-running-bg)",color:"var(--color-running)",label:"running"},starting:{bg:"var(--color-secondary)",color:"var(--color-text)",label:"starting",icon:m.jsx(Wt,{size:9,strokeWidth:3,className:"animate-spin"})},stuck:{bg:"var(--color-stuck-bg)",color:"var(--color-stuck)",label:"stuck"},crashed:{bg:"var(--color-crashed-bg)",color:"var(--color-crashed)",label:"crashed",icon:m.jsx(SA,{size:9,strokeWidth:2.5})},idle:{bg:"var(--color-idle-bg)",color:"var(--color-idle)",label:"idle"}}[e];return m.jsxs("span",{className:"nb-status inline-flex items-center gap-1",style:{background:n.bg,color:n.color},children:[n.icon,n.label]})}function cg(e){if(e==null||e<=0)return"—";const t=Math.floor(e/1e3),n=Math.floor(t/3600),a=Math.floor(t%3600/60),s=t%60;return n>0?`${n}h ${a}m`:a>0?`${a}m ${s}s`:`${s}s`}function _R(e){if(e==null||e<=0)return"text-[var(--color-text-muted)]";const t=e/6e4;return t<10?"text-[var(--color-running)]":t<60?"text-[var(--color-stuck)]":"text-[var(--color-crashed)]"}function ug(e){const t=Date.now()-new Date(e).getTime();return t<6e4?`${Math.floor(t/1e3)}s 前`:t<36e5?`${Math.floor(t/6e4)}m 前`:`${Math.floor(t/36e5)}h 前`}function kR({alerts:e,selected:t,onSelect:n}){return e.length===0?m.jsxs("div",{className:"nb-card bg-[var(--color-running-bg)] flex items-center gap-3",children:[m.jsx(Pp,{size:18,strokeWidth:2.5,className:"text-[var(--color-running)]"}),m.jsx("span",{className:"text-sm font-bold text-[var(--color-running)]",children:"全部 worker 健康"})]}):m.jsxs("section",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2 flex items-center gap-2 text-[var(--color-crashed)]",children:[m.jsx(RA,{size:14,strokeWidth:2.5}),"Alerts (",e.length,")"]}),m.jsx("div",{className:"flex flex-col gap-2",children:e.map(a=>{const s=(t==null?void 0:t.project)===a.project&&(t==null?void 0:t.slot)===a.slot;return m.jsxs("button",{type:"button",onClick:()=>n(a.project,a.slot),className:["nb-card p-3 text-left",a.state==="crashed"?"bg-[var(--color-crashed-bg)]":"bg-[var(--color-stuck-bg)]",s?"ring-4 ring-[var(--color-text)]":""].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[m.jsx(og,{state:a.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold",children:[a.project,"/worker-",a.slot]}),a.card&&m.jsxs("span",{className:"truncate",children:["#",a.card.seq," ",a.card.title]}),m.jsxs("span",{className:"ml-auto text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] flex items-center gap-1",children:[m.jsx(MC,{size:10,strokeWidth:2.5}),cg(a.runtimeMs)]})]}),a.markerUpdatedAt&&m.jsx("div",{className:"text-xs text-[var(--color-text-muted)] mt-1 font-[family-name:var(--font-mono)]",children:a.state==="crashed"?"PID 已死。":`marker 停 ${ug(a.markerUpdatedAt)}。`})]},`${a.project}-${a.slot}`)})})]})}function NR({active:e,selected:t,onSelect:n}){return e.length===0?m.jsx("div",{className:"nb-card bg-[var(--color-bg-cream)]",children:m.jsx("p",{className:"text-sm text-[var(--color-text-muted)] italic",children:"没有 worker 在运行。"})}):m.jsxs("section",{children:[m.jsxs("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2 flex items-center gap-2",children:[m.jsx(jf,{size:14,strokeWidth:2.5}),"Active (",e.length,")"]}),m.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:e.map(a=>{const s=(t==null?void 0:t.project)===a.project&&(t==null?void 0:t.slot)===a.slot;return m.jsxs("button",{type:"button",onClick:()=>n(a.project,a.slot),className:["nb-card p-3 text-left",a.state==="starting"?"bg-[var(--color-secondary)]":"bg-[var(--color-running-bg)]",s?"ring-4 ring-[var(--color-text)]":""].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[m.jsx(og,{state:a.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-sm flex-1 truncate",children:[a.project,"/worker-",a.slot]}),m.jsx("span",{className:`text-xs font-[family-name:var(--font-mono)] ${_R(a.runtimeMs)}`,children:cg(a.runtimeMs)})]}),a.card&&m.jsxs("div",{className:"text-sm font-semibold mb-1 truncate",children:["#",a.card.seq," · ",a.card.title]}),m.jsxs("div",{className:"text-xs text-[var(--color-text-muted)] font-[family-name:var(--font-mono)] flex items-center gap-2 mb-1",children:[a.stage&&m.jsxs("span",{children:["stage: ",a.stage]}),a.markerUpdatedAt&&m.jsxs("span",{className:"ml-auto",children:["marker ",ug(a.markerUpdatedAt)]})]}),a.lastLogLine&&m.jsxs("div",{className:"text-[11px] font-[family-name:var(--font-mono)] text-[var(--color-text-muted)] bg-[var(--color-bg)] border-2 border-[var(--color-text)] rounded px-2 py-1 mt-2 truncate",children:[m.jsx(t1,{size:9,strokeWidth:2.5,className:"inline-block mr-1 align-text-bottom"}),a.lastLogLine.msg]})]},`${a.project}-${a.slot}`)})})]})}function TR({capacity:e,selected:t,onSelect:n}){return e.length===0?null:m.jsxs("section",{children:[m.jsx("h2",{className:"font-[family-name:var(--font-heading)] text-sm font-bold uppercase tracking-wider mb-2",children:"Capacity"}),m.jsx("div",{className:"nb-card p-0 overflow-hidden",children:m.jsxs("table",{className:"w-full text-sm",children:[m.jsx("thead",{children:m.jsxs("tr",{className:"bg-[var(--color-bg-cream)] border-b-2 border-[var(--color-text)]",children:[m.jsx("th",{className:"px-3 py-2 text-left font-bold text-xs uppercase tracking-wider",children:"项目"}),m.jsx("th",{className:"px-3 py-2 text-left font-bold text-xs uppercase tracking-wider",children:"占用"}),m.jsx("th",{className:"px-3 py-2 text-right font-bold text-xs uppercase tracking-wider",children:"running"}),m.jsx("th",{className:"px-3 py-2 text-right font-bold text-xs uppercase tracking-wider",children:"其它"}),m.jsx("th",{className:"px-3 py-2"})]})}),m.jsx("tbody",{children:e.map(a=>{const s=a.running+a.starting+a.stuck+a.crashed,o=(t==null?void 0:t.project)===a.project;return m.jsxs("tr",{onClick:()=>n(a.project),className:["border-b border-dashed border-[var(--color-border-light)] last:border-0 cursor-pointer hover:bg-[var(--color-accent-yellow)]",o?"bg-[var(--color-accent-yellow)]":""].join(" "),children:[m.jsx("td",{className:"px-3 py-2 font-[family-name:var(--font-mono)] font-bold",children:a.project}),m.jsx("td",{className:"px-3 py-2",children:m.jsx(CR,{total:a.total,cap:a})}),m.jsxs("td",{className:"px-3 py-2 text-right font-[family-name:var(--font-mono)]",children:[m.jsx("span",{className:"text-[var(--color-running)] font-bold",children:a.running}),m.jsxs("span",{className:"text-[var(--color-text-muted)]",children:["/",a.total]})]}),m.jsxs("td",{className:"px-3 py-2 text-right text-xs font-[family-name:var(--font-mono)] text-[var(--color-text-muted)]",children:[a.starting>0&&m.jsxs("span",{className:"mr-2",children:["starting ",a.starting]}),a.stuck>0&&m.jsxs("span",{className:"text-[var(--color-stuck)] font-bold mr-2",children:["stuck ",a.stuck]}),a.crashed>0&&m.jsxs("span",{className:"text-[var(--color-crashed)] font-bold mr-2",children:["crashed ",a.crashed]}),s===0&&m.jsx("span",{children:"idle"})]}),m.jsx("td",{className:"px-3 py-2 text-right",children:m.jsx("span",{className:"text-xs text-[var(--color-text-muted)]",children:"详情 →"})})]},a.project)})})]})})]})}function CR({total:e,cap:t}){const n=[];for(let a=0;a<t.crashed;a++)n.push("crashed");for(let a=0;a<t.stuck;a++)n.push("stuck");for(let a=0;a<t.starting;a++)n.push("starting");for(let a=0;a<t.running;a++)n.push("running");for(let a=0;a<t.idle;a++)n.push("idle");return m.jsxs("div",{className:"flex gap-1 items-center",children:[n.map((a,s)=>m.jsx("span",{className:"inline-block w-3 h-3 rounded-full border-2 border-[var(--color-text)]",style:{background:AR(a)},title:a},s)),m.jsxs("span",{className:"text-xs text-[var(--color-text-muted)] ml-2 font-[family-name:var(--font-mono)]",children:[e," slot",e!==1?"s":""]})]})}function AR(e){switch(e){case"running":return"var(--color-running-bg)";case"starting":return"var(--color-secondary)";case"stuck":return"var(--color-stuck-bg)";case"crashed":return"var(--color-crashed-bg)";default:return"var(--color-idle-bg)"}}function OR({project:e,initialSlot:t,onChange:n}){var d;const a=lt({queryKey:["workers",e],queryFn:()=>ER(e),refetchInterval:3e3}),s=((d=a.data)==null?void 0:d.data)??[],[o,c]=M.useState(null);M.useEffect(()=>{if(s.length===0){c(null);return}const h=s[0].slot;c(y=>y!=null&&s.some(g=>g.slot===y)?y:t!=null&&s.some(g=>g.slot===t)?t:h)},[e,t,s.length]);const f=s.find(h=>h.slot===o)??null;return m.jsxs("div",{className:"flex flex-col h-full",children:[m.jsxs("div",{className:"px-4 py-3 border-b-2 border-[var(--color-text)] bg-[var(--color-bg-cream)]",children:[m.jsxs("div",{className:"flex items-center justify-between mb-2",children:[m.jsx("span",{className:"font-[family-name:var(--font-mono)] font-bold truncate",children:e}),m.jsx(ds,{to:`/board?project=${encodeURIComponent(e)}`,className:"text-xs underline text-[var(--color-text-muted)] hover:text-[var(--color-text)]",children:"看板 →"})]}),a.isLoading&&s.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载 workers…"}):s.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"该项目没有 worker slot。"}):m.jsx("div",{className:"flex flex-wrap gap-2",children:s.map(h=>m.jsx(RR,{worker:h,active:h.slot===o,onClick:()=>c(h.slot)},h.slot))})]}),f?m.jsx(MR,{project:e,worker:f,onChange:n}):m.jsx("div",{className:"flex-1 flex items-center justify-center p-6 text-center",children:m.jsx("p",{className:"text-sm text-[var(--color-text-muted)]",children:s.length===0?"无 worker":"请选择一个 worker"})})]})}function RR({worker:e,active:t,onClick:n}){return m.jsxs("button",{type:"button",onClick:n,className:["nb-card p-2 text-left min-w-[130px] transition-transform",t?"ring-4 ring-[var(--color-text)]":"opacity-80 hover:opacity-100"].join(" "),children:[m.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[m.jsx(og,{state:e.state}),m.jsxs("span",{className:"font-[family-name:var(--font-mono)] font-bold text-xs",children:["worker-",e.slot]})]}),e.card?m.jsxs("div",{className:"text-[11px] truncate font-[family-name:var(--font-mono)]",children:["#",e.card.seq," ",e.card.title]}):m.jsx("div",{className:"text-[11px] text-[var(--color-text-muted)] italic",children:"空闲"})]})}function MR({project:e,worker:t,onChange:n}){var h,y;const{confirm:a,alert:s}=si(),o=t.state==="crashed"||t.state==="stuck",c=lt({queryKey:["worker-detail",e,t.slot],queryFn:()=>SR(e,t.slot),refetchInterval:3e3}),f=((h=c.data)==null?void 0:h.recentOutput)??[],d=((y=c.data)==null?void 0:y.recentLogs)??[];return m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"flex-1 overflow-auto p-4 flex flex-col gap-4",children:[t.card?m.jsxs("div",{children:[m.jsx("div",{className:"text-xs font-bold uppercase tracking-wider text-[var(--color-text-muted)] mb-1",children:"当前卡片"}),m.jsxs("div",{className:"text-sm font-semibold break-words",children:["#",t.card.seq," · ",t.card.title]})]}):m.jsx("div",{className:"text-sm text-[var(--color-text-muted)] italic",children:"slot 空闲,没有当前卡片。"}),m.jsxs("dl",{className:"grid grid-cols-[100px_1fr] gap-y-2 text-sm",children:[m.jsx("dt",{className:"font-bold",children:"Stage"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.stage??"—"}),m.jsx("dt",{className:"font-bold",children:"PID"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:t.pid??"—"}),m.jsx("dt",{className:"font-bold",children:"Runtime"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)]",children:cg(t.runtimeMs)}),m.jsx("dt",{className:"font-bold",children:"Started"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:t.startedAt?new Date(t.startedAt).toLocaleString():"—"}),m.jsx("dt",{className:"font-bold",children:"Marker"}),m.jsx("dd",{className:"font-[family-name:var(--font-mono)] text-xs",children:t.markerUpdatedAt?ug(t.markerUpdatedAt):"—"})]}),m.jsxs("div",{children:[m.jsxs("div",{className:"text-xs font-bold uppercase tracking-wider text-[var(--color-text-muted)] mb-1 flex items-center gap-1",children:[m.jsx(t1,{size:10,strokeWidth:2.5}),"Claude 输出 · 最近 ",f.length," 行"]}),c.isLoading&&f.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"加载中…"}):f.length===0?m.jsx("p",{className:"text-xs text-[var(--color-text-muted)] italic",children:"还没收到 session 输出。Worker 刚启动时需要几秒。"}):m.jsx("pre",{className:"text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded p-2 max-h-80 overflow-auto whitespace-pre-wrap break-words",children:f.map(g=>`${g.ts?`${g.ts} [${g.kind}] `:`[${g.kind}] `}${g.text}`).join(`
|
|
478
478
|
`)})]}),d.length>0&&m.jsxs("div",{children:[m.jsxs("div",{className:"text-xs font-bold uppercase tracking-wider text-[var(--color-text-muted)] mb-1 opacity-60",children:["Supervisor 心跳 · 最近 ",d.length," 行"]}),m.jsx("pre",{className:"text-xs font-[family-name:var(--font-mono)] bg-[var(--color-bg-cream)] border-2 border-[var(--color-text)] rounded p-2 max-h-40 overflow-auto whitespace-pre-wrap break-words opacity-80",children:d.map(g=>`${g.ts??""} [${g.level}] ${g.msg}`).join(`
|
|
479
479
|
`)}),m.jsx(ds,{to:`/logs?project=${encodeURIComponent(e)}&worker=${t.slot}`,className:"text-xs underline text-[var(--color-running)] mt-1 inline-block",children:"查看完整 log →"})]})]}),m.jsxs("div",{className:"px-4 py-3 border-t-2 border-[var(--color-text)] bg-[var(--color-bg-cream)] flex gap-2 justify-end flex-wrap",children:[o&&t.card&&m.jsxs("button",{type:"button",className:"nb-btn nb-btn-mint",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{if(await a({title:`重启 worker-${t.slot}`,body:`先杀进程,再重新 launch 到 #${t.card.seq}`,confirm:"重启"})){try{await e0(e,t.slot)}catch{}try{await wR(e,t.slot,t.card.seq),n()}catch(x){s({title:"重启失败",body:x instanceof Error?x.message:String(x)})}}},children:[m.jsx(CA,{size:11,strokeWidth:2.5})," 重启"]}),t.state!=="idle"&&m.jsxs("button",{type:"button",className:"nb-btn nb-btn-danger",style:{padding:"4px 10px",fontSize:11},onClick:async()=>{if(await a({title:`终止 worker-${t.slot}`,body:"当前任务强制中断。",confirm:"终止",danger:!0}))try{await e0(e,t.slot),n()}catch(x){s({title:"终止失败",body:x instanceof Error?x.message:String(x)})}},children:[m.jsx(zA,{size:11,strokeWidth:2.5})," 终止"]})]})]})}function jR(){var o;const e=qn(),[t,n]=M.useState(null),a=lt({queryKey:["workers-agg"],queryFn:vR,refetchInterval:5e3});M.useEffect(()=>{if(!a.data)return;const c=a.data.capacity.map(d=>d.project),f=[];for(const d of c){const h=new EventSource(`/stream/projects/${encodeURIComponent(d)}`),y=()=>{e.invalidateQueries({queryKey:["workers-agg"]})};h.addEventListener("worker.updated",y),h.addEventListener("worker.added",y),h.addEventListener("worker.deleted",y),h.addEventListener("card.updated",y),f.push(h)}return()=>{for(const d of f)d.close()}},[(o=a.data)==null?void 0:o.capacity.map(c=>c.project).join(","),e]);const s=M.useMemo(()=>{if(!a.data)return{projects:0,running:0,starting:0,stuck:0,crashed:0,idle:0};const c={projects:a.data.capacity.length,running:0,starting:0,stuck:0,crashed:0,idle:0};for(const f of a.data.capacity)c.running+=f.running,c.starting+=f.starting,c.stuck+=f.stuck,c.crashed+=f.crashed,c.idle+=f.idle;return c},[a.data]);return m.jsxs("div",{className:"flex flex-col gap-4 h-[calc(100vh-140px)]",children:[m.jsxs("header",{className:"flex items-center justify-between flex-wrap gap-3",children:[m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"Workers 👷"}),m.jsxs("p",{className:"text-sm text-[var(--color-text-muted)] mt-1",children:["跨 ",s.projects," 项目 · ",s.running," 跑 · ",s.starting," 启动 ·"," ",m.jsxs("span",{className:"text-[var(--color-stuck)]",children:[s.stuck," 卡"]})," ·"," ",m.jsxs("span",{className:"text-[var(--color-crashed)]",children:[s.crashed," 崩"]})," · ",s.idle," 闲"]})]}),m.jsxs("button",{className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>a.refetch(),disabled:a.isFetching,type:"button","aria-label":"刷新",children:[a.isFetching?m.jsx(Wt,{size:12,strokeWidth:3,className:"animate-spin"}):m.jsx(Cl,{size:12,strokeWidth:2.5}),"刷新"]})]}),m.jsxs("div",{className:"grid grid-cols-1 xl:grid-cols-2 gap-4 flex-1 min-h-0",children:[m.jsxs("div",{className:"flex flex-col gap-4 overflow-auto pr-2",children:[a.isLoading&&m.jsx("p",{className:"text-[var(--color-text-muted)] italic",children:"加载中…"}),a.isError&&m.jsx("div",{className:"nb-card bg-[var(--color-crashed-bg)]",children:m.jsxs("p",{children:["加载失败: ",a.error instanceof Error?a.error.message:String(a.error)]})}),a.data&&m.jsxs(m.Fragment,{children:[m.jsx(kR,{alerts:a.data.alerts,selected:t,onSelect:(c,f)=>n({project:c,slot:f})}),m.jsx(NR,{active:a.data.active,selected:t,onSelect:(c,f)=>n({project:c,slot:f})}),m.jsx(TR,{capacity:a.data.capacity,selected:t,onSelect:c=>n({project:c})})]})]}),m.jsx("aside",{className:"nb-card p-0 overflow-hidden flex flex-col h-full",children:t?m.jsx(OR,{project:t.project,initialSlot:t.slot,onChange:()=>e.invalidateQueries({queryKey:["workers-agg"]})}):m.jsx("div",{className:"flex-1 flex items-center justify-center p-6 text-center",children:m.jsxs("div",{children:[m.jsx(jf,{size:32,className:"mx-auto mb-3 text-[var(--color-text-subtle)]",strokeWidth:2}),m.jsx("p",{className:"text-sm text-[var(--color-text-muted)]",children:"点击项目 / worker 查看详情"})]})})})]})]})}function DR(e){const t=new URLSearchParams;return e.project&&t.set("project",e.project),e.worker&&t.set("worker",e.worker),t.set("limit",String(e.limit)),e.since&&t.set("since",e.since),Ht(`/api/logs?${t}`)}function LR(e){const t=new URLSearchParams({project:e.project});return e.worker&&t.set("worker",e.worker),`/stream/logs?${t}`}const IR=["error","warn","info","debug"],zR=["error","warn","info"];function BR(){var U,Z;const[e,t]=QE(),n=e.get("project"),a=e.get("worker")??"",[s,o]=M.useState([]),[c,f]=M.useState(!1),[d,h]=M.useState(!0),[y,g]=M.useState(()=>new Set(zR)),[x,v]=M.useState(""),[S,w]=M.useState("live"),[k,_]=M.useState(()=>{const O=new Date(Date.now()-36e5),P=G=>String(G).padStart(2,"0");return`${O.getFullYear()}-${P(O.getMonth()+1)}-${P(O.getDate())}T${P(O.getHours())}:${P(O.getMinutes())}`}),A=M.useRef(null),T=!n,D=lt({queryKey:["projects"],queryFn:_r}),{data:$,refetch:j}=lt({queryKey:["logs",n??"agg",a,S,S==="history"?k:"live"],queryFn:()=>DR({project:n||void 0,worker:a||void 0,limit:S==="history"?2e3:500,since:S==="history"?new Date(k).toISOString():void 0}),refetchInterval:T&&S==="live"?5e3:!1});M.useEffect(()=>{$!=null&&$.data&&o($.data)},[$]),M.useEffect(()=>{if(!n||S!=="live")return;const O=LR({project:n,worker:a||void 0}),P=new EventSource(O);return P.addEventListener("log.line",G=>{if(!c)try{const le=JSON.parse(G.data);o(ae=>{const W=[...ae,le];return W.length>5e3&&W.splice(0,W.length-5e3),W})}catch{}}),()=>P.close()},[n,a,c,S]),M.useEffect(()=>{if(!d)return;const O=A.current;O&&(O.scrollTop=O.scrollHeight)},[s,d]);const q=M.useMemo(()=>{const O=x.toLowerCase();return s.filter(P=>!(!y.has(P.level)||O&&!P.msg.toLowerCase().includes(O)))},[s,y,x]);return m.jsxs("div",{className:"flex flex-col gap-4 max-w-full",children:[m.jsx("header",{className:"flex items-center justify-between gap-3 flex-wrap",children:m.jsxs("div",{children:[m.jsx("h1",{className:"font-[family-name:var(--font-heading)] text-4xl font-bold tracking-tight",children:"Logs 📜"}),m.jsxs("p",{className:"text-sm text-[var(--color-text-muted)] mt-1",children:[T?`全部项目(${((U=D.data)==null?void 0:U.data.length)??0})`:n,a&&` · worker-${a}`," · ",T&&S==="live"?"5s 轮询":"tail -f"," · ",s.length," lines",c&&m.jsx("span",{className:"text-[var(--color-stuck)] ml-2 font-bold",children:"⏸ PAUSED"})]})]})}),m.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[m.jsxs("div",{className:"flex gap-1 p-1 bg-[var(--color-bg)] border-[2px] border-[var(--color-text)] rounded-full shadow-[2px_2px_0_var(--color-text)]",children:[m.jsxs("button",{type:"button",onClick:()=>w("live"),"aria-pressed":S==="live",className:["px-3 py-1 rounded-full text-xs font-bold flex items-center gap-1.5",S==="live"?"bg-[var(--color-primary)] text-[var(--color-text)] shadow-[1px_1px_0_var(--color-text)]":"text-[var(--color-text-muted)]"].join(" "),children:[m.jsx(ZE,{size:11,strokeWidth:2.5}),"实时"]}),m.jsxs("button",{type:"button",onClick:()=>w("history"),"aria-pressed":S==="history",className:["px-3 py-1 rounded-full text-xs font-bold flex items-center gap-1.5",S==="history"?"bg-[var(--color-primary)] text-[var(--color-text)] shadow-[1px_1px_0_var(--color-text)]":"text-[var(--color-text-muted)]"].join(" "),children:[m.jsx(ZC,{size:11,strokeWidth:2.5}),"历史"]})]}),S==="history"&&m.jsxs(m.Fragment,{children:[m.jsx("input",{type:"datetime-local",className:"nb-input",style:{padding:"4px 8px",fontSize:12},value:k,onChange:O=>_(O.target.value),"aria-label":"查询起始时间"}),m.jsxs("button",{className:"nb-btn nb-btn-primary",style:{padding:"6px 12px",fontSize:12},onClick:()=>j(),type:"button","aria-label":"查询",children:[m.jsx(xf,{size:11,strokeWidth:3}),"查询"]})]}),m.jsxs("div",{className:"relative",children:[m.jsx(qC,{size:14,strokeWidth:2.5,className:"absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none text-[var(--color-text)]"}),m.jsxs("select",{className:"nb-input appearance-none pl-9 pr-9 font-[family-name:var(--font-mono)] cursor-pointer",style:{padding:"10px 36px 10px 36px",fontSize:13,minWidth:180},value:n??"",onChange:O=>{const P=O.target.value;t(P?{project:P}:{})},"aria-label":"筛选项目",children:[m.jsx("option",{value:"",children:"全部项目"}),(Z=D.data)==null?void 0:Z.data.map(O=>m.jsx("option",{value:O.name,children:O.name},O.name))]}),m.jsx(yc,{size:14,strokeWidth:3,className:"absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none text-[var(--color-text)]"})]}),m.jsxs("div",{className:"relative flex-1 max-w-md",children:[m.jsx(xf,{size:14,className:"absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-subtle)]"}),m.jsx("input",{className:"nb-input pl-9 w-full",placeholder:"过滤关键字…",value:x,onChange:O=>v(O.target.value),"aria-label":"过滤日志"})]}),m.jsx("div",{className:"flex items-center gap-1 p-1 bg-[var(--color-bg)] border-[2px] border-[var(--color-text)] rounded-full shadow-[2px_2px_0_var(--color-text)]",children:IR.map(O=>m.jsx(UR,{level:O,enabled:y.has(O),onToggle:()=>{g(P=>{const G=new Set(P);return G.has(O)?G.delete(O):G.add(O),G})}},O))}),m.jsxs("div",{className:"ml-auto flex gap-2",children:[S==="live"&&m.jsxs(m.Fragment,{children:[m.jsx("button",{className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>h(O=>!O),type:"button",children:d?"✓ Auto-scroll":"Auto-scroll"}),m.jsx("button",{className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>f(O=>!O),type:"button",children:c?m.jsxs(m.Fragment,{children:[m.jsx(Kp,{size:12,strokeWidth:3})," Resume"]}):m.jsxs(m.Fragment,{children:[m.jsx(cA,{size:12,strokeWidth:3})," Pause"]})})]}),m.jsxs("button",{className:"nb-btn",style:{padding:"6px 12px",fontSize:12},onClick:()=>{const O=new Blob([q.map(le=>le.raw).join(`
|
|
480
480
|
`)],{type:"text/plain"}),P=URL.createObjectURL(O),G=document.createElement("a");G.href=P,G.download=`${n}-log-${Date.now()}.log`,G.click(),URL.revokeObjectURL(P)},type:"button",children:[m.jsx(XE,{size:12,strokeWidth:2.5})," Export"]})]})]}),m.jsxs("div",{className:"nb-card p-0 overflow-hidden",children:[m.jsxs("div",{className:"px-4 py-2 bg-[var(--color-bg-cream)] border-b-2 border-[var(--color-text)] flex items-center justify-between font-[family-name:var(--font-mono)] text-xs",children:[m.jsx("span",{className:"text-[var(--color-text-muted)]",children:($==null?void 0:$.file)??"~/.coral/projects/.../logs/*.log"}),S==="live"?m.jsx("span",{className:"nb-status",style:{background:"var(--color-running-bg)",color:"var(--color-running)"},children:"live"}):m.jsx("span",{className:"nb-status",style:{background:"var(--color-accent-purple)",color:"var(--color-text)"},children:"history"})]}),m.jsxs("div",{ref:A,className:"overflow-auto font-[family-name:var(--font-mono)] text-[12px] leading-[22px] max-h-[70vh] bg-[var(--color-bg)] p-2",onScroll:O=>{const P=O.currentTarget;!(P.scrollHeight-P.scrollTop-P.clientHeight<40)&&d&&h(!1)},children:[q.map((O,P)=>m.jsx(FR,{line:O},P)),q.length===0&&m.jsx("div",{className:"text-center py-12 text-[var(--color-text-subtle)]",children:"没有匹配的日志"})]})]})]})}function UR({level:e,enabled:t,onToggle:n}){const a={error:"var(--color-crashed-bg)",warn:"var(--color-stuck-bg)",info:"var(--color-secondary)",debug:"var(--color-accent-purple)"},s={error:"var(--color-crashed)",warn:"var(--color-stuck)",info:"var(--color-text)",debug:"var(--color-text)"};return m.jsx("button",{type:"button",onClick:n,"aria-pressed":t,className:["px-3 py-0.5 rounded-full font-[family-name:var(--font-mono)] text-[10px] font-bold tracking-widest cursor-pointer",t?"border-[1.5px] border-[var(--color-text)]":"text-[var(--color-text-subtle)]"].join(" "),style:t?{background:a[e],color:s[e]}:{},children:e.toUpperCase()})}function FR({line:e}){var a;const t={error:"bg-[var(--color-crashed)] text-[var(--color-text)]",warn:"bg-[var(--color-stuck)] text-[var(--color-text)]",info:"bg-[var(--color-secondary)] text-[var(--color-text)]",debug:"",trace:""},n=!!e.project;return m.jsxs("div",{className:["grid gap-2 px-2 py-0.5 rounded hover:bg-[var(--color-bg-cream)]",n?"grid-cols-[100px_90px_60px_1fr]":"grid-cols-[100px_60px_1fr]"].join(" "),children:[m.jsx("span",{className:"text-[var(--color-text-subtle)] whitespace-nowrap",children:e.ts?((a=e.ts.split("T")[1])==null?void 0:a.replace("Z",""))??e.ts:"--"}),n&&m.jsx("span",{className:"truncate text-[var(--color-text-muted)] font-bold",title:e.project,children:e.project}),m.jsx("span",{className:`text-center font-bold ${t[e.level]??""}`,style:{borderRadius:4,padding:"0 6px"},children:e.level.toUpperCase()}),m.jsx("span",{className:"truncate text-[var(--color-text)]",children:e.msg})]})}function $R(e,t){const n={};return(e[e.length-1]===""?[...e,""]:e).join((n.padRight?" ":"")+","+(n.padLeft===!1?"":" ")).trim()}const PR=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,qR=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,HR={};function t0(e,t){return(HR.jsx?qR:PR).test(e)}const KR=/[ \t\n\f\r]/g;function GR(e){return typeof e=="object"?e.type==="text"?n0(e.value):!1:n0(e)}function n0(e){return e.replace(KR,"")===""}class Sc{constructor(t,n,a){this.normal=n,this.property=t,a&&(this.space=a)}}Sc.prototype.normal={};Sc.prototype.property={};Sc.prototype.space=void 0;function lS(e,t){const n={},a={};for(const s of e)Object.assign(n,s.property),Object.assign(a,s.normal);return new Sc(n,a,t)}function hp(e){return e.toLowerCase()}class Hn{constructor(t,n){this.attribute=n,this.property=t}}Hn.prototype.attribute="";Hn.prototype.booleanish=!1;Hn.prototype.boolean=!1;Hn.prototype.commaOrSpaceSeparated=!1;Hn.prototype.commaSeparated=!1;Hn.prototype.defined=!1;Hn.prototype.mustUseProperty=!1;Hn.prototype.number=!1;Hn.prototype.overloadedBoolean=!1;Hn.prototype.property="";Hn.prototype.spaceSeparated=!1;Hn.prototype.space=void 0;let QR=0;const Pe=ps(),Zt=ps(),mp=ps(),fe=ps(),St=ps(),pl=ps(),ti=ps();function ps(){return 2**++QR}const pp=Object.freeze(Object.defineProperty({__proto__:null,boolean:Pe,booleanish:Zt,commaOrSpaceSeparated:ti,commaSeparated:pl,number:fe,overloadedBoolean:mp,spaceSeparated:St},Symbol.toStringTag,{value:"Module"})),Em=Object.keys(pp);class fg extends Hn{constructor(t,n,a,s){let o=-1;if(super(t,n),i0(this,"space",s),typeof a=="number")for(;++o<Em.length;){const c=Em[o];i0(this,Em[o],(a&pp[c])===pp[c])}}}fg.prototype.defined=!0;function i0(e,t,n){n&&(e[t]=n)}function Hl(e){const t={},n={};for(const[a,s]of Object.entries(e.properties)){const o=new fg(a,e.transform(e.attributes||{},a),s,e.space);e.mustUseProperty&&e.mustUseProperty.includes(a)&&(o.mustUseProperty=!0),t[a]=o,n[hp(a)]=a,n[hp(o.attribute)]=a}return new Sc(t,n,e.space)}const oS=Hl({properties:{ariaActiveDescendant:null,ariaAtomic:Zt,ariaAutoComplete:null,ariaBusy:Zt,ariaChecked:Zt,ariaColCount:fe,ariaColIndex:fe,ariaColSpan:fe,ariaControls:St,ariaCurrent:null,ariaDescribedBy:St,ariaDetails:null,ariaDisabled:Zt,ariaDropEffect:St,ariaErrorMessage:null,ariaExpanded:Zt,ariaFlowTo:St,ariaGrabbed:Zt,ariaHasPopup:null,ariaHidden:Zt,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:St,ariaLevel:fe,ariaLive:null,ariaModal:Zt,ariaMultiLine:Zt,ariaMultiSelectable:Zt,ariaOrientation:null,ariaOwns:St,ariaPlaceholder:null,ariaPosInSet:fe,ariaPressed:Zt,ariaReadOnly:Zt,ariaRelevant:null,ariaRequired:Zt,ariaRoleDescription:St,ariaRowCount:fe,ariaRowIndex:fe,ariaRowSpan:fe,ariaSelected:Zt,ariaSetSize:fe,ariaSort:null,ariaValueMax:fe,ariaValueMin:fe,ariaValueNow:fe,ariaValueText:null,role:null},transform(e,t){return t==="role"?t:"aria-"+t.slice(4).toLowerCase()}});function cS(e,t){return t in e?e[t]:t}function uS(e,t){return cS(e,t.toLowerCase())}const YR=Hl({attributes:{acceptcharset:"accept-charset",classname:"class",htmlfor:"for",httpequiv:"http-equiv"},mustUseProperty:["checked","multiple","muted","selected"],properties:{abbr:null,accept:pl,acceptCharset:St,accessKey:St,action:null,allow:null,allowFullScreen:Pe,allowPaymentRequest:Pe,allowUserMedia:Pe,alt:null,as:null,async:Pe,autoCapitalize:null,autoComplete:St,autoFocus:Pe,autoPlay:Pe,blocking:St,capture:null,charSet:null,checked:Pe,cite:null,className:St,cols:fe,colSpan:null,content:null,contentEditable:Zt,controls:Pe,controlsList:St,coords:fe|pl,crossOrigin:null,data:null,dateTime:null,decoding:null,default:Pe,defer:Pe,dir:null,dirName:null,disabled:Pe,download:mp,draggable:Zt,encType:null,enterKeyHint:null,fetchPriority:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:Pe,formTarget:null,headers:St,height:fe,hidden:mp,high:fe,href:null,hrefLang:null,htmlFor:St,httpEquiv:St,id:null,imageSizes:null,imageSrcSet:null,inert:Pe,inputMode:null,integrity:null,is:null,isMap:Pe,itemId:null,itemProp:St,itemRef:St,itemScope:Pe,itemType:St,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:Pe,low:fe,manifest:null,max:null,maxLength:fe,media:null,method:null,min:null,minLength:fe,multiple:Pe,muted:Pe,name:null,nonce:null,noModule:Pe,noValidate:Pe,onAbort:null,onAfterPrint:null,onAuxClick:null,onBeforeMatch:null,onBeforePrint:null,onBeforeToggle:null,onBeforeUnload:null,onBlur:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onContextLost:null,onContextMenu:null,onContextRestored:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnded:null,onError:null,onFocus:null,onFormData:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLanguageChange:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadEnd:null,onLoadStart:null,onMessage:null,onMessageError:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRejectionHandled:null,onReset:null,onResize:null,onScroll:null,onScrollEnd:null,onSecurityPolicyViolation:null,onSeeked:null,onSeeking:null,onSelect:null,onSlotChange:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnhandledRejection:null,onUnload:null,onVolumeChange:null,onWaiting:null,onWheel:null,open:Pe,optimum:fe,pattern:null,ping:St,placeholder:null,playsInline:Pe,popover:null,popoverTarget:null,popoverTargetAction:null,poster:null,preload:null,readOnly:Pe,referrerPolicy:null,rel:St,required:Pe,reversed:Pe,rows:fe,rowSpan:fe,sandbox:St,scope:null,scoped:Pe,seamless:Pe,selected:Pe,shadowRootClonable:Pe,shadowRootDelegatesFocus:Pe,shadowRootMode:null,shape:null,size:fe,sizes:null,slot:null,span:fe,spellCheck:Zt,src:null,srcDoc:null,srcLang:null,srcSet:null,start:fe,step:null,style:null,tabIndex:fe,target:null,title:null,translate:null,type:null,typeMustMatch:Pe,useMap:null,value:Zt,width:fe,wrap:null,writingSuggestions:null,align:null,aLink:null,archive:St,axis:null,background:null,bgColor:null,border:fe,borderColor:null,bottomMargin:fe,cellPadding:null,cellSpacing:null,char:null,charOff:null,classId:null,clear:null,code:null,codeBase:null,codeType:null,color:null,compact:Pe,declare:Pe,event:null,face:null,frame:null,frameBorder:null,hSpace:fe,leftMargin:fe,link:null,longDesc:null,lowSrc:null,marginHeight:fe,marginWidth:fe,noResize:Pe,noHref:Pe,noShade:Pe,noWrap:Pe,object:null,profile:null,prompt:null,rev:null,rightMargin:fe,rules:null,scheme:null,scrolling:Zt,standby:null,summary:null,text:null,topMargin:fe,valueType:null,version:null,vAlign:null,vLink:null,vSpace:fe,allowTransparency:null,autoCorrect:null,autoSave:null,disablePictureInPicture:Pe,disableRemotePlayback:Pe,prefix:null,property:null,results:fe,security:null,unselectable:null},space:"html",transform:uS}),VR=Hl({attributes:{accentHeight:"accent-height",alignmentBaseline:"alignment-baseline",arabicForm:"arabic-form",baselineShift:"baseline-shift",capHeight:"cap-height",className:"class",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",crossOrigin:"crossorigin",dataType:"datatype",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",hrefLang:"hreflang",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",horizOriginY:"horiz-origin-y",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",navDown:"nav-down",navDownLeft:"nav-down-left",navDownRight:"nav-down-right",navLeft:"nav-left",navNext:"nav-next",navPrev:"nav-prev",navRight:"nav-right",navUp:"nav-up",navUpLeft:"nav-up-left",navUpRight:"nav-up-right",onAbort:"onabort",onActivate:"onactivate",onAfterPrint:"onafterprint",onBeforePrint:"onbeforeprint",onBegin:"onbegin",onCancel:"oncancel",onCanPlay:"oncanplay",onCanPlayThrough:"oncanplaythrough",onChange:"onchange",onClick:"onclick",onClose:"onclose",onCopy:"oncopy",onCueChange:"oncuechange",onCut:"oncut",onDblClick:"ondblclick",onDrag:"ondrag",onDragEnd:"ondragend",onDragEnter:"ondragenter",onDragExit:"ondragexit",onDragLeave:"ondragleave",onDragOver:"ondragover",onDragStart:"ondragstart",onDrop:"ondrop",onDurationChange:"ondurationchange",onEmptied:"onemptied",onEnd:"onend",onEnded:"onended",onError:"onerror",onFocus:"onfocus",onFocusIn:"onfocusin",onFocusOut:"onfocusout",onHashChange:"onhashchange",onInput:"oninput",onInvalid:"oninvalid",onKeyDown:"onkeydown",onKeyPress:"onkeypress",onKeyUp:"onkeyup",onLoad:"onload",onLoadedData:"onloadeddata",onLoadedMetadata:"onloadedmetadata",onLoadStart:"onloadstart",onMessage:"onmessage",onMouseDown:"onmousedown",onMouseEnter:"onmouseenter",onMouseLeave:"onmouseleave",onMouseMove:"onmousemove",onMouseOut:"onmouseout",onMouseOver:"onmouseover",onMouseUp:"onmouseup",onMouseWheel:"onmousewheel",onOffline:"onoffline",onOnline:"ononline",onPageHide:"onpagehide",onPageShow:"onpageshow",onPaste:"onpaste",onPause:"onpause",onPlay:"onplay",onPlaying:"onplaying",onPopState:"onpopstate",onProgress:"onprogress",onRateChange:"onratechange",onRepeat:"onrepeat",onReset:"onreset",onResize:"onresize",onScroll:"onscroll",onSeeked:"onseeked",onSeeking:"onseeking",onSelect:"onselect",onShow:"onshow",onStalled:"onstalled",onStorage:"onstorage",onSubmit:"onsubmit",onSuspend:"onsuspend",onTimeUpdate:"ontimeupdate",onToggle:"ontoggle",onUnload:"onunload",onVolumeChange:"onvolumechange",onWaiting:"onwaiting",onZoom:"onzoom",overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pointerEvents:"pointer-events",referrerPolicy:"referrerpolicy",renderingIntent:"rendering-intent",shapeRendering:"shape-rendering",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDashArray:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeLineCap:"stroke-linecap",strokeLineJoin:"stroke-linejoin",strokeMiterLimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",tabIndex:"tabindex",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",transformOrigin:"transform-origin",typeOf:"typeof",underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",vectorEffect:"vector-effect",vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode",xHeight:"x-height",playbackOrder:"playbackorder",timelineBegin:"timelinebegin"},properties:{about:ti,accentHeight:fe,accumulate:null,additive:null,alignmentBaseline:null,alphabetic:fe,amplitude:fe,arabicForm:null,ascent:fe,attributeName:null,attributeType:null,azimuth:fe,bandwidth:null,baselineShift:null,baseFrequency:null,baseProfile:null,bbox:null,begin:null,bias:fe,by:null,calcMode:null,capHeight:fe,className:St,clip:null,clipPath:null,clipPathUnits:null,clipRule:null,color:null,colorInterpolation:null,colorInterpolationFilters:null,colorProfile:null,colorRendering:null,content:null,contentScriptType:null,contentStyleType:null,crossOrigin:null,cursor:null,cx:null,cy:null,d:null,dataType:null,defaultAction:null,descent:fe,diffuseConstant:fe,direction:null,display:null,dur:null,divisor:fe,dominantBaseline:null,download:Pe,dx:null,dy:null,edgeMode:null,editable:null,elevation:fe,enableBackground:null,end:null,event:null,exponent:fe,externalResourcesRequired:null,fill:null,fillOpacity:fe,fillRule:null,filter:null,filterRes:null,filterUnits:null,floodColor:null,floodOpacity:null,focusable:null,focusHighlight:null,fontFamily:null,fontSize:null,fontSizeAdjust:null,fontStretch:null,fontStyle:null,fontVariant:null,fontWeight:null,format:null,fr:null,from:null,fx:null,fy:null,g1:pl,g2:pl,glyphName:pl,glyphOrientationHorizontal:null,glyphOrientationVertical:null,glyphRef:null,gradientTransform:null,gradientUnits:null,handler:null,hanging:fe,hatchContentUnits:null,hatchUnits:null,height:null,href:null,hrefLang:null,horizAdvX:fe,horizOriginX:fe,horizOriginY:fe,id:null,ideographic:fe,imageRendering:null,initialVisibility:null,in:null,in2:null,intercept:fe,k:fe,k1:fe,k2:fe,k3:fe,k4:fe,kernelMatrix:ti,kernelUnitLength:null,keyPoints:null,keySplines:null,keyTimes:null,kerning:null,lang:null,lengthAdjust:null,letterSpacing:null,lightingColor:null,limitingConeAngle:fe,local:null,markerEnd:null,markerMid:null,markerStart:null,markerHeight:null,markerUnits:null,markerWidth:null,mask:null,maskContentUnits:null,maskUnits:null,mathematical:null,max:null,media:null,mediaCharacterEncoding:null,mediaContentEncodings:null,mediaSize:fe,mediaTime:null,method:null,min:null,mode:null,name:null,navDown:null,navDownLeft:null,navDownRight:null,navLeft:null,navNext:null,navPrev:null,navRight:null,navUp:null,navUpLeft:null,navUpRight:null,numOctaves:null,observer:null,offset:null,onAbort:null,onActivate:null,onAfterPrint:null,onBeforePrint:null,onBegin:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnd:null,onEnded:null,onError:null,onFocus:null,onFocusIn:null,onFocusOut:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadStart:null,onMessage:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onMouseWheel:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRepeat:null,onReset:null,onResize:null,onScroll:null,onSeeked:null,onSeeking:null,onSelect:null,onShow:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnload:null,onVolumeChange:null,onWaiting:null,onZoom:null,opacity:null,operator:null,order:null,orient:null,orientation:null,origin:null,overflow:null,overlay:null,overlinePosition:fe,overlineThickness:fe,paintOrder:null,panose1:null,path:null,pathLength:fe,patternContentUnits:null,patternTransform:null,patternUnits:null,phase:null,ping:St,pitch:null,playbackOrder:null,pointerEvents:null,points:null,pointsAtX:fe,pointsAtY:fe,pointsAtZ:fe,preserveAlpha:null,preserveAspectRatio:null,primitiveUnits:null,propagate:null,property:ti,r:null,radius:null,referrerPolicy:null,refX:null,refY:null,rel:ti,rev:ti,renderingIntent:null,repeatCount:null,repeatDur:null,requiredExtensions:ti,requiredFeatures:ti,requiredFonts:ti,requiredFormats:ti,resource:null,restart:null,result:null,rotate:null,rx:null,ry:null,scale:null,seed:null,shapeRendering:null,side:null,slope:null,snapshotTime:null,specularConstant:fe,specularExponent:fe,spreadMethod:null,spacing:null,startOffset:null,stdDeviation:null,stemh:null,stemv:null,stitchTiles:null,stopColor:null,stopOpacity:null,strikethroughPosition:fe,strikethroughThickness:fe,string:null,stroke:null,strokeDashArray:ti,strokeDashOffset:null,strokeLineCap:null,strokeLineJoin:null,strokeMiterLimit:fe,strokeOpacity:fe,strokeWidth:null,style:null,surfaceScale:fe,syncBehavior:null,syncBehaviorDefault:null,syncMaster:null,syncTolerance:null,syncToleranceDefault:null,systemLanguage:ti,tabIndex:fe,tableValues:null,target:null,targetX:fe,targetY:fe,textAnchor:null,textDecoration:null,textRendering:null,textLength:null,timelineBegin:null,title:null,transformBehavior:null,type:null,typeOf:ti,to:null,transform:null,transformOrigin:null,u1:null,u2:null,underlinePosition:fe,underlineThickness:fe,unicode:null,unicodeBidi:null,unicodeRange:null,unitsPerEm:fe,values:null,vAlphabetic:fe,vMathematical:fe,vectorEffect:null,vHanging:fe,vIdeographic:fe,version:null,vertAdvY:fe,vertOriginX:fe,vertOriginY:fe,viewBox:null,viewTarget:null,visibility:null,width:null,widths:null,wordSpacing:null,writingMode:null,x:null,x1:null,x2:null,xChannelSelector:null,xHeight:fe,y:null,y1:null,y2:null,yChannelSelector:null,z:null,zoomAndPan:null},space:"svg",transform:cS}),fS=Hl({properties:{xLinkActuate:null,xLinkArcRole:null,xLinkHref:null,xLinkRole:null,xLinkShow:null,xLinkTitle:null,xLinkType:null},space:"xlink",transform(e,t){return"xlink:"+t.slice(5).toLowerCase()}}),dS=Hl({attributes:{xmlnsxlink:"xmlns:xlink"},properties:{xmlnsXLink:null,xmlns:null},space:"xmlns",transform:uS}),hS=Hl({properties:{xmlBase:null,xmlLang:null,xmlSpace:null},space:"xml",transform(e,t){return"xml:"+t.slice(3).toLowerCase()}}),XR={classId:"classID",dataType:"datatype",itemId:"itemID",strokeDashArray:"strokeDasharray",strokeDashOffset:"strokeDashoffset",strokeLineCap:"strokeLinecap",strokeLineJoin:"strokeLinejoin",strokeMiterLimit:"strokeMiterlimit",typeOf:"typeof",xLinkActuate:"xlinkActuate",xLinkArcRole:"xlinkArcrole",xLinkHref:"xlinkHref",xLinkRole:"xlinkRole",xLinkShow:"xlinkShow",xLinkTitle:"xlinkTitle",xLinkType:"xlinkType",xmlnsXLink:"xmlnsXlink"},ZR=/[A-Z]/g,a0=/-[a-z]/g,WR=/^data[-\w.:]+$/i;function JR(e,t){const n=hp(t);let a=t,s=Hn;if(n in e.normal)return e.property[e.normal[n]];if(n.length>4&&n.slice(0,4)==="data"&&WR.test(t)){if(t.charAt(4)==="-"){const o=t.slice(5).replace(a0,tM);a="data"+o.charAt(0).toUpperCase()+o.slice(1)}else{const o=t.slice(4);if(!a0.test(o)){let c=o.replace(ZR,eM);c.charAt(0)!=="-"&&(c="-"+c),t="data"+c}}s=fg}return new s(a,t)}function eM(e){return"-"+e.toLowerCase()}function tM(e){return e.charAt(1).toUpperCase()}const nM=lS([oS,YR,fS,dS,hS],"html"),dg=lS([oS,VR,fS,dS,hS],"svg");function iM(e){return e.join(" ").trim()}var al={},Sm,r0;function aM(){if(r0)return Sm;r0=1;var e=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,t=/\n/g,n=/^\s*/,a=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,s=/^:\s*/,o=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,c=/^[;\s]*/,f=/^\s+|\s+$/g,d=`
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-WUGCBcyb.js"></script>
|
|
11
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DRhdpvew.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
|
|
2
|
-
Theme: GitHub
|
|
3
|
-
Description: Light theme as seen on github.com
|
|
4
|
-
Author: github.com
|
|
5
|
-
Maintainer: @Hirse
|
|
6
|
-
Updated: 2021-05-15
|
|
7
|
-
|
|
8
|
-
Outdated base version: https://github.com/primer/github-syntax-light
|
|
9
|
-
Current colors taken from GitHub's CSS
|
|
10
|
-
*/.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}/*! tailwindcss v4.2.4 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:"JetBrains Mono", "SF Mono", Monaco, Consolas, monospace;--color-black:#000;--spacing:.25rem;--container-md:28rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-6xl:72rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--font-weight-normal:400;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-normal:0em;--tracking-wider:.05em;--tracking-widest:.1em;--radius-md:12px;--radius-lg:16px;--radius-xl:20px;--radius-2xl:1rem;--shadow-sm:0 1px 3px 0 #0000001a, 0 1px 2px -1px #0000001a;--shadow-lg:0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-bg:#fff;--color-bg-cream:#fff9f5;--color-text:#2d3748;--color-text-muted:#475569;--color-text-subtle:#64748b;--color-border-light:#e2e8f0;--color-primary:#fdbcb4;--color-secondary:#add8e6;--color-accent-mint:#98ff98;--color-accent-purple:#e6e6fa;--color-accent-yellow:#fff3b0;--color-accent-pink:#ffd1dc;--color-running:#166534;--color-running-bg:#d4f5e4;--color-stuck:#92400e;--color-stuck-bg:#ffe8cf;--color-crashed:#991b1b;--color-crashed-bg:#ffe4e6;--color-idle:#475569;--color-idle-bg:#f1f5f9;--color-cta:#22c55e;--font-heading:"Fredoka", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-body:"DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}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;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:before,:after{box-sizing:border-box}html{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{font-family:var(--font-body);color:var(--color-text);background:var(--color-bg-cream);min-height:100vh;font-size:15px;line-height:1.5}h1,h2,h3,h4,h5{font-family:var(--font-heading);color:var(--color-text);letter-spacing:-.01em;margin:0;font-weight:700}:focus-visible{outline:3px solid var(--color-text);outline-offset:2px}@media(prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important}}}@layer components{.nb-card{background:var(--color-bg);border:3px solid var(--color-text);box-shadow:5px 5px 0 var(--color-text);border-radius:16px;padding:16px}.nb-card-interactive{cursor:pointer;transition:transform .18s ease-out,box-shadow .18s ease-out}.nb-card-interactive:hover{box-shadow:7px 7px 0 var(--color-text);transform:translate(-2px,-2px)}.nb-card-interactive:active{box-shadow:3px 3px 0 var(--color-text);transform:translate(1px,1px)}.nb-btn{border:3px solid var(--color-text);font-family:var(--font-body);color:var(--color-text);background:var(--color-bg);box-shadow:3px 3px 0 var(--color-text);-webkit-user-select:none;user-select:none;cursor:pointer;border-radius:12px;align-items:center;gap:8px;padding:10px 18px;font-size:14px;font-weight:700;line-height:20px;transition:transform .12s ease-out,box-shadow .12s ease-out;display:inline-flex}.nb-btn:hover{box-shadow:4px 4px 0 var(--color-text);transform:translate(-1px,-1px)}.nb-btn:active{box-shadow:1px 1px 0 var(--color-text);transform:translate(2px,2px)}.nb-btn:disabled{opacity:.45;cursor:not-allowed;box-shadow:2px 2px 0 var(--color-text);transform:none}.nb-btn:disabled:hover{box-shadow:2px 2px 0 var(--color-text);transform:none}.nb-btn-primary{background:var(--color-cta)}.nb-btn-mint{background:var(--color-accent-mint)}.nb-btn-peach{background:var(--color-primary)}.nb-btn-blue{background:var(--color-secondary)}.nb-btn-yellow{background:var(--color-accent-yellow)}.nb-btn-purple{background:var(--color-accent-purple)}.nb-btn-danger{background:var(--color-crashed);color:#fff}.nb-input{border:3px solid var(--color-text);background:var(--color-bg);color:var(--color-text);font-family:var(--font-body);box-shadow:3px 3px 0 var(--color-text);border-radius:12px;padding:10px 16px;font-size:14px;font-weight:500;line-height:20px;transition:transform .12s,box-shadow .12s}.nb-input:focus{box-shadow:4px 4px 0 var(--color-text);outline:none;transform:translate(-1px,-1px)}.nb-badge{border:2px solid var(--color-text);font-family:var(--font-body);color:var(--color-text);background:var(--color-bg);border-radius:9999px;align-items:center;gap:4px;padding:4px 10px;font-size:12px;font-weight:700;line-height:16px;display:inline-flex}.nb-status{border:2px solid var(--color-text);font-family:var(--font-body);color:var(--color-text);border-radius:9999px;align-items:center;gap:5px;padding:4px 10px 4px 9px;font-size:11px;font-weight:700;line-height:16px;display:inline-flex}.nb-status:before{content:"";border:1.5px solid var(--color-text);background:currentColor;border-radius:50%;width:8px;height:8px}.prose-chat{color:var(--color-text);line-height:1.6}.prose-chat>:first-child{margin-top:0}.prose-chat>:last-child{margin-bottom:0}.prose-chat h1{font-family:var(--font-heading);margin:1em 0 .5em;font-size:1.5rem;font-weight:700}.prose-chat h2{font-family:var(--font-heading);margin:1em 0 .5em;font-size:1.25rem;font-weight:700}.prose-chat h3{font-family:var(--font-heading);margin:.8em 0 .4em;font-size:1.1rem;font-weight:700}.prose-chat h4,.prose-chat h5,.prose-chat h6{font-family:var(--font-heading);margin:.8em 0 .3em;font-weight:700}.prose-chat p{margin:.6em 0}.prose-chat ul,.prose-chat ol{margin:.6em 0;padding-left:1.6em}.prose-chat ul{list-style:outside}.prose-chat ol{list-style:decimal}.prose-chat li,.prose-chat li>ul,.prose-chat li>ol{margin:.2em 0}.prose-chat code{font-family:var(--font-mono);background:var(--color-bg-cream);border:1.5px solid var(--color-text);border-radius:4px;padding:0 4px;font-size:.9em}.prose-chat pre{background:var(--color-bg-cream);border:2px solid var(--color-text);font-family:var(--font-mono);border-radius:8px;margin:.8em 0;padding:12px;font-size:.85em;line-height:1.45;overflow-x:auto}.prose-chat pre code{font-size:inherit;background:0 0;border:0;padding:0}.prose-chat blockquote{border-left:3px solid var(--color-text);color:var(--color-text-muted);margin:.8em 0;padding-left:1em}.prose-chat table{border-collapse:collapse;border:2px solid var(--color-text);border-radius:8px;margin:.8em 0;overflow:hidden}.prose-chat th,.prose-chat td{border:1px solid var(--color-text);text-align:left;padding:6px 10px}.prose-chat th{background:var(--color-bg-cream);font-weight:700}.prose-chat a{color:var(--color-running);text-underline-offset:2px;text-decoration:underline}.prose-chat a:hover{color:var(--color-text)}.prose-chat hr{border:0;border-top:2px dashed var(--color-text);margin:1em 0}}@layer utilities{.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing) * 0)}.end{inset-inline-end:var(--spacing)}.top-1\/2{top:50%}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-3{right:calc(var(--spacing) * 3)}.left-0{left:calc(var(--spacing) * 0)}.left-3{left:calc(var(--spacing) * 3)}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.col-span-2{grid-column:span 2/span 2}.row-span-1{grid-row:span 1/span 1}.row-start-1{grid-row-start:1}.row-start-2{grid-row-start:2}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-12{margin-top:calc(var(--spacing) * 12)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-10{height:calc(var(--spacing) * 10)}.h-20{height:calc(var(--spacing) * 20)}.h-\[calc\(100vh-140px\)\]{height:calc(100vh - 140px)}.h-full{height:100%}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[70vh\]{max-height:70vh}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-\[340px\]{min-height:340px}.min-h-screen{min-height:100vh}.w-2{width:calc(var(--spacing) * 2)}.w-2\/3{width:66.6667%}.w-3{width:calc(var(--spacing) * 3)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-32{width:calc(var(--spacing) * 32)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[130px\]{min-width:130px}.min-w-\[200px\]{min-width:200px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.list-disc{list-style-type:disc}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-\[100px_1fr\]{grid-template-columns:100px 1fr}.grid-cols-\[100px_60px_1fr\]{grid-template-columns:100px 60px 1fr}.grid-cols-\[100px_90px_60px_1fr\]{grid-template-columns:100px 90px 60px 1fr}.grid-cols-\[160px_1fr\]{grid-template-columns:160px 1fr}.grid-cols-\[220px_1fr\]{grid-template-columns:220px 1fr}.grid-cols-\[240px_1fr\]{grid-template-columns:240px 1fr}.grid-cols-\[260px_1fr\]{grid-template-columns:260px 1fr}.grid-cols-\[repeat\(auto-fill\,minmax\(280px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}.grid-rows-\[1fr_40px\]{grid-template-rows:1fr 40px}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}.gap-y-1{row-gap:calc(var(--spacing) * 1)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.gap-y-3{row-gap:calc(var(--spacing) * 3)}.self-end{align-self:flex-end}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-\[2px\]{border-style:var(--tw-border-style);border-width:2px}.border-\[3px\]{border-style:var(--tw-border-style);border-width:3px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-t-\[1\.5px\]{border-top-style:var(--tw-border-style);border-top-width:1.5px}.border-t-\[3px\]{border-top-style:var(--tw-border-style);border-top-width:3px}.border-r-\[3px\]{border-right-style:var(--tw-border-style);border-right-width:3px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[var\(--color-border-light\)\]{border-color:var(--color-border-light)}.border-\[var\(--color-cta\)\]{border-color:var(--color-cta)}.border-\[var\(--color-running\)\]{border-color:var(--color-running)}.border-\[var\(--color-stuck\)\]{border-color:var(--color-stuck)}.border-\[var\(--color-text\)\]{border-color:var(--color-text)}.border-transparent{border-color:#0000}.bg-\[var\(--color-accent-mint\)\]{background-color:var(--color-accent-mint)}.bg-\[var\(--color-accent-purple\)\]{background-color:var(--color-accent-purple)}.bg-\[var\(--color-accent-yellow\)\]{background-color:var(--color-accent-yellow)}.bg-\[var\(--color-bg\)\]{background-color:var(--color-bg)}.bg-\[var\(--color-bg-cream\)\]{background-color:var(--color-bg-cream)}.bg-\[var\(--color-border-light\)\]{background-color:var(--color-border-light)}.bg-\[var\(--color-crashed\)\]{background-color:var(--color-crashed)}.bg-\[var\(--color-crashed-bg\)\]{background-color:var(--color-crashed-bg)}.bg-\[var\(--color-cta\)\]{background-color:var(--color-cta)}.bg-\[var\(--color-primary\)\]{background-color:var(--color-primary)}.bg-\[var\(--color-running-bg\)\]{background-color:var(--color-running-bg)}.bg-\[var\(--color-secondary\)\]{background-color:var(--color-secondary)}.bg-\[var\(--color-stuck\)\]{background-color:var(--color-stuck)}.bg-\[var\(--color-stuck-bg\)\]{background-color:var(--color-stuck-bg)}.bg-\[var\(--color-text\)\]{background-color:var(--color-text)}.bg-\[var\(--color-text-subtle\)\]{background-color:var(--color-text-subtle)}.bg-black\/30{background-color:#0000004d}@supports (color:color-mix(in lab,red,red)){.bg-black\/30{background-color:color-mix(in oklab,var(--color-black) 30%,transparent)}}.p-0{padding:calc(var(--spacing) * 0)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-9{padding-right:calc(var(--spacing) * 9)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-9{padding-left:calc(var(--spacing) * 9)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.align-text-bottom{vertical-align:text-bottom}.font-\[family-name\:var\(--font-body\)\]{font-family:var(--font-body)}.font-\[family-name\:var\(--font-heading\)\]{font-family:var(--font-heading)}.font-\[family-name\:var\(--font-mono\)\],.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-\[22px\]{--tw-leading:22px;line-height:22px}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[var\(--color-bg\)\]{color:var(--color-bg)}.text-\[var\(--color-crashed\)\]{color:var(--color-crashed)}.text-\[var\(--color-running\)\]{color:var(--color-running)}.text-\[var\(--color-stuck\)\]{color:var(--color-stuck)}.text-\[var\(--color-text\)\]{color:var(--color-text)}.text-\[var\(--color-text-muted\)\]{color:var(--color-text-muted)}.text-\[var\(--color-text-subtle\)\]{color:var(--color-text-subtle)}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.decoration-2{text-decoration-thickness:2px}.accent-\[var\(--color-cta\)\]{accent-color:var(--color-cta)}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-80{opacity:.8}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[1px_1px_0_var\(--color-text\)\]{--tw-shadow:1px 1px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[2px_2px_0_var\(--color-text\)\]{--tw-shadow:2px 2px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[3px_3px_0_var\(--color-text\)\]{--tw-shadow:3px 3px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[4px_4px_0_var\(--color-cta\)\]{--tw-shadow:4px 4px 0 var(--tw-shadow-color,var(--color-cta));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[5px_5px_0_var\(--color-text\)\]{--tw-shadow:5px 5px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-nb{--tw-shadow:5px 5px 0 var(--tw-shadow-color,#2d3748);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-4{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-\[var\(--color-text\)\]{--tw-ring-color:var(--color-text)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);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,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[transform\,box-shadow\]{transition-property:transform,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-\[180ms\]{--tw-duration:.18s;transition-duration:.18s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.last\:border-0:last-child{border-style:var(--tw-border-style);border-width:0}@media(hover:hover){.hover\:-translate-x-0\.5:hover{--tw-translate-x:calc(var(--spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:-translate-x-px:hover{--tw-translate-x:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:-translate-y-0\.5:hover{--tw-translate-y:calc(var(--spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:-translate-y-px:hover{--tw-translate-y:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:border-\[var\(--color-text\)\]:hover{border-color:var(--color-text)}.hover\:bg-\[var\(--color-accent-yellow\)\]:hover{background-color:var(--color-accent-yellow)}.hover\:bg-\[var\(--color-bg-cream\)\]:hover{background-color:var(--color-bg-cream)}.hover\:text-\[var\(--color-crashed\)\]:hover{color:var(--color-crashed)}.hover\:text-\[var\(--color-text\)\]:hover{color:var(--color-text)}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-\[3px_3px_0_var\(--color-text\)\]:hover{--tw-shadow:3px 3px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-\[4px_4px_0_var\(--color-text\)\]:hover{--tw-shadow:4px 4px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-\[5px_5px_0_var\(--color-text\)\]:hover{--tw-shadow:5px 5px 0 var(--tw-shadow-color,var(--color-text));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-\[var\(--color-text\)\]:focus-visible{--tw-ring-color:var(--color-text)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.active\:cursor-grabbing:active{cursor:grabbing}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:64rem){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:80rem){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|