@axlsdk/studio 0.13.5 → 0.13.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ /*! tailwindcss v4.2.0 | 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-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-divide-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-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-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}}}@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:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-800:oklch(44.4% .177 26.899);--color-red-900:oklch(39.6% .141 25.723);--color-red-950:oklch(25.8% .092 26.042);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-900:oklch(41.4% .112 45.904);--color-amber-950:oklch(27.9% .077 45.635);--color-green-100:oklch(96.2% .044 156.743);--color-green-300:oklch(87.1% .15 154.449);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-700:oklch(52.7% .154 150.069);--color-green-900:oklch(39.3% .095 152.535);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-emerald-900:oklch(37.8% .077 168.94);--color-emerald-950:oklch(26.2% .051 172.552);--color-cyan-500:oklch(71.5% .143 215.221);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-900:oklch(37.9% .146 265.522);--color-indigo-500:oklch(58.5% .233 277.117);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-300:oklch(82.7% .119 306.383);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-500:oklch(62.7% .265 303.9);--color-purple-600:oklch(55.8% .288 302.321);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-900:oklch(38.1% .176 304.987);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-gray-500:oklch(55.1% .027 264.364);--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-3xl:48rem;--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);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--animate-ping:ping 1s cubic-bezier(0, 0, .2, 1) 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)}}@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}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.inset-y-0{inset-block:calc(var(--spacing) * 0)}.-top-0\.5{top:calc(var(--spacing) * -.5)}.top-0{top:calc(var(--spacing) * 0)}.top-2{top:calc(var(--spacing) * 2)}.top-\[3px\]{top:3px}.-right-0\.5{right:calc(var(--spacing) * -.5)}.right-0{right:calc(var(--spacing) * 0)}.right-2{right:calc(var(--spacing) * 2)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-\[3px\]{bottom:3px}.z-10{z-index:10}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-1{margin-inline:calc(var(--spacing) * 1)}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mr-8{margin-right:calc(var(--spacing) * 8)}.-mb-px{margin-bottom:-1px}.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-8{margin-bottom:calc(var(--spacing) * 8)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-8{margin-left:calc(var(--spacing) * 8)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.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-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-40{height:calc(var(--spacing) * 40)}.h-full{height:100%}.h-screen{height:100vh}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-96{max-height:calc(var(--spacing) * 96)}.min-h-0{min-height:calc(var(--spacing) * 0)}.w-0\.5{width:calc(var(--spacing) * .5)}.w-1{width:calc(var(--spacing) * 1)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-5{width:calc(var(--spacing) * 5)}.w-8{width:calc(var(--spacing) * 8)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-48{width:calc(var(--spacing) * 48)}.w-56{width:calc(var(--spacing) * 56)}.w-\[340px\]{width:340px}.w-\[400px\]{width:400px}.w-full{width:100%}.w-px{width:1px}.max-w-3xl{max-width:var(--container-3xl)}.max-w-20{max-width:calc(var(--spacing) * 20)}.max-w-24{max-width:calc(var(--spacing) * 24)}.max-w-\[80\%\]{max-width:80%}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-\[180px\]{min-width:180px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-ping{animation:var(--animate-ping)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.resize-y{resize:vertical}.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))}.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}.justify-start{justify-content:flex-start}.gap-0{gap:calc(var(--spacing) * 0)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.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)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-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-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-\[hsl\(var\(--border\)\)\]>:not(:last-child)){border-color:hsl(var(--border))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.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-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-l-\[3px\]{border-left-style:var(--tw-border-style);border-left-width:3px}.border-none{--tw-border-style:none;border-style:none}.border-\[hsl\(var\(--border\)\)\],.border-\[hsl\(var\(--border\)\)\]\/40{border-color:hsl(var(--border))}@supports (color:color-mix(in lab,red,red)){.border-\[hsl\(var\(--border\)\)\]\/40{border-color:color-mix(in oklab,hsl(var(--border)) 40%,transparent)}}.border-\[hsl\(var\(--border\)\)\]\/50{border-color:hsl(var(--border))}@supports (color:color-mix(in lab,red,red)){.border-\[hsl\(var\(--border\)\)\]\/50{border-color:color-mix(in oklab,hsl(var(--border)) 50%,transparent)}}.border-\[hsl\(var\(--foreground\)\)\]{border-color:hsl(var(--foreground))}.border-\[hsl\(var\(--input\)\)\]{border-color:hsl(var(--input))}.border-\[hsl\(var\(--primary\)\)\]{border-color:hsl(var(--primary))}.border-emerald-200{border-color:var(--color-emerald-200)}.border-red-200{border-color:var(--color-red-200)}.border-red-300{border-color:var(--color-red-300)}.border-transparent{border-color:#0000}.border-l-\[hsl\(var\(--foreground\)\)\]{border-left-color:hsl(var(--foreground))}.border-l-blue-500{border-left-color:var(--color-blue-500)}.border-l-green-500{border-left-color:var(--color-green-500)}.border-l-red-500{border-left-color:var(--color-red-500)}.border-l-slate-400{border-left-color:var(--color-slate-400)}.border-l-transparent{border-left-color:#0000}.bg-\[hsl\(var\(--accent\)\)\],.bg-\[hsl\(var\(--accent\)\)\]\/30{background-color:hsl(var(--accent))}@supports (color:color-mix(in lab,red,red)){.bg-\[hsl\(var\(--accent\)\)\]\/30{background-color:color-mix(in oklab,hsl(var(--accent)) 30%,transparent)}}.bg-\[hsl\(var\(--background\)\)\]{background-color:hsl(var(--background))}.bg-\[hsl\(var\(--border\)\)\]{background-color:hsl(var(--border))}.bg-\[hsl\(var\(--card\)\)\]{background-color:hsl(var(--card))}.bg-\[hsl\(var\(--destructive\)\)\]{background-color:hsl(var(--destructive))}.bg-\[hsl\(var\(--foreground\)\)\]{background-color:hsl(var(--foreground))}.bg-\[hsl\(var\(--muted\)\)\],.bg-\[hsl\(var\(--muted\)\)\]\/50{background-color:hsl(var(--muted))}@supports (color:color-mix(in lab,red,red)){.bg-\[hsl\(var\(--muted\)\)\]\/50{background-color:color-mix(in oklab,hsl(var(--muted)) 50%,transparent)}}.bg-\[hsl\(var\(--primary\)\)\]{background-color:hsl(var(--primary))}.bg-\[hsl\(var\(--primary\)\/0\.08\)\]{background-color:hsl(var(--primary)/.08)}.bg-\[hsl\(var\(--secondary\)\)\]{background-color:hsl(var(--secondary))}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-50\/60{background-color:#fffbeb99}@supports (color:color-mix(in lab,red,red)){.bg-amber-50\/60{background-color:color-mix(in oklab,var(--color-amber-50) 60%,transparent)}}.bg-amber-100{background-color:var(--color-amber-100)}.bg-amber-500{background-color:var(--color-amber-500)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-cyan-500{background-color:var(--color-cyan-500)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-50\/60{background-color:#ecfdf599}@supports (color:color-mix(in lab,red,red)){.bg-emerald-50\/60{background-color:color-mix(in oklab,var(--color-emerald-50) 60%,transparent)}}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-green-100{background-color:var(--color-green-100)}.bg-green-400{background-color:var(--color-green-400)}.bg-green-500{background-color:var(--color-green-500)}.bg-indigo-500{background-color:var(--color-indigo-500)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-purple-400{background-color:var(--color-purple-400)}.bg-purple-500{background-color:var(--color-purple-500)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-50\/60{background-color:#fef2f299}@supports (color:color-mix(in lab,red,red)){.bg-red-50\/60{background-color:color-mix(in oklab,var(--color-red-50) 60%,transparent)}}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-600{background-color:var(--color-red-600)}.bg-slate-500{background-color:var(--color-slate-500)}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.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-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-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.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-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}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.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-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[hsl\(var\(--accent-foreground\)\)\]{color:hsl(var(--accent-foreground))}.text-\[hsl\(var\(--background\)\)\]{color:hsl(var(--background))}.text-\[hsl\(var\(--border\)\)\]{color:hsl(var(--border))}.text-\[hsl\(var\(--destructive-foreground\)\)\]{color:hsl(var(--destructive-foreground))}.text-\[hsl\(var\(--foreground\)\)\]{color:hsl(var(--foreground))}.text-\[hsl\(var\(--muted-foreground\)\)\]{color:hsl(var(--muted-foreground))}.text-\[hsl\(var\(--primary\)\)\]{color:hsl(var(--primary))}.text-\[hsl\(var\(--primary-foreground\)\)\]{color:hsl(var(--primary-foreground))}.text-\[hsl\(var\(--secondary-foreground\)\)\]{color:hsl(var(--secondary-foreground))}.text-amber-500{color:var(--color-amber-500)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-blue-500{color:var(--color-blue-500)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-500{color:var(--color-gray-500)}.text-green-500{color:var(--color-green-500)}.text-green-700{color:var(--color-green-700)}.text-purple-600{color:var(--color-purple-600)}.text-purple-700{color:var(--color-purple-700)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-white{color:var(--color-white)}.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,)}.opacity-0{opacity:0}.opacity-70{opacity:.7}.opacity-100{opacity:1}.invert{--tw-invert:invert(100%);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,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition-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-opacity{transition-property:opacity;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))}@media(hover:hover){.group-hover\:text-\[hsl\(var\(--foreground\)\)\]:is(:where(.group):hover *){color:hsl(var(--foreground))}.group-hover\:opacity-60:is(:where(.group):hover *){opacity:.6}.group-hover\/json\:opacity-100:is(:where(.group\/json):hover *){opacity:1}}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media(hover:hover){.hover\:bg-\[hsl\(var\(--accent\)\)\]:hover,.hover\:bg-\[hsl\(var\(--accent\)\)\]\/40:hover{background-color:hsl(var(--accent))}@supports (color:color-mix(in lab,red,red)){.hover\:bg-\[hsl\(var\(--accent\)\)\]\/40:hover{background-color:color-mix(in oklab,hsl(var(--accent)) 40%,transparent)}}.hover\:bg-\[hsl\(var\(--accent\)\)\]\/50:hover{background-color:hsl(var(--accent))}@supports (color:color-mix(in lab,red,red)){.hover\:bg-\[hsl\(var\(--accent\)\)\]\/50:hover{background-color:color-mix(in oklab,hsl(var(--accent)) 50%,transparent)}}.hover\:bg-\[hsl\(var\(--destructive\)\)\]:hover{background-color:hsl(var(--destructive))}.hover\:bg-red-50:hover{background-color:var(--color-red-50)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:text-\[hsl\(var\(--accent-foreground\)\)\]:hover{color:hsl(var(--accent-foreground))}.hover\:text-\[hsl\(var\(--destructive-foreground\)\)\]:hover{color:hsl(var(--destructive-foreground))}.hover\:text-\[hsl\(var\(--foreground\)\)\]:hover{color:hsl(var(--foreground))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-90:hover{opacity:.9}}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + 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\:ring-\[hsl\(var\(--ring\)\)\]:focus{--tw-ring-color:hsl(var(--ring))}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:64rem){.lg\:col-span-1{grid-column:span 1/span 1}.lg\:col-span-2{grid-column:span 2/span 2}.lg\:col-span-3{grid-column:span 3/span 3}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(min-width:80rem){.xl\:w-\[380px\]{width:380px}.xl\:w-\[480px\]{width:480px}}@media(prefers-color-scheme:dark){.dark\:border-emerald-900{border-color:var(--color-emerald-900)}.dark\:border-red-800{border-color:var(--color-red-800)}.dark\:border-red-900{border-color:var(--color-red-900)}.dark\:bg-amber-400{background-color:var(--color-amber-400)}.dark\:bg-amber-900{background-color:var(--color-amber-900)}.dark\:bg-amber-900\/40{background-color:#7b330666}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-900\/40{background-color:color-mix(in oklab,var(--color-amber-900) 40%,transparent)}}.dark\:bg-amber-950\/20{background-color:#46190133}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-950\/20{background-color:color-mix(in oklab,var(--color-amber-950) 20%,transparent)}}.dark\:bg-amber-950\/30{background-color:#4619014d}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-950\/30{background-color:color-mix(in oklab,var(--color-amber-950) 30%,transparent)}}.dark\:bg-blue-900{background-color:var(--color-blue-900)}.dark\:bg-emerald-400{background-color:var(--color-emerald-400)}.dark\:bg-emerald-900\/50{background-color:#004e3b80}@supports (color:color-mix(in lab,red,red)){.dark\:bg-emerald-900\/50{background-color:color-mix(in oklab,var(--color-emerald-900) 50%,transparent)}}.dark\:bg-emerald-950\/20{background-color:#002c2233}@supports (color:color-mix(in lab,red,red)){.dark\:bg-emerald-950\/20{background-color:color-mix(in oklab,var(--color-emerald-950) 20%,transparent)}}.dark\:bg-emerald-950\/30{background-color:#002c224d}@supports (color:color-mix(in lab,red,red)){.dark\:bg-emerald-950\/30{background-color:color-mix(in oklab,var(--color-emerald-950) 30%,transparent)}}.dark\:bg-green-900{background-color:var(--color-green-900)}.dark\:bg-purple-900{background-color:var(--color-purple-900)}.dark\:bg-red-400{background-color:var(--color-red-400)}.dark\:bg-red-700{background-color:var(--color-red-700)}.dark\:bg-red-900\/40{background-color:#82181a66}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-900\/40{background-color:color-mix(in oklab,var(--color-red-900) 40%,transparent)}}.dark\:bg-red-950{background-color:var(--color-red-950)}.dark\:bg-red-950\/20{background-color:#46080933}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-950\/20{background-color:color-mix(in oklab,var(--color-red-950) 20%,transparent)}}.dark\:bg-red-950\/30{background-color:#4608094d}@supports (color:color-mix(in lab,red,red)){.dark\:bg-red-950\/30{background-color:color-mix(in oklab,var(--color-red-950) 30%,transparent)}}.dark\:text-amber-300{color:var(--color-amber-300)}.dark\:text-amber-400{color:var(--color-amber-400)}.dark\:text-blue-300{color:var(--color-blue-300)}.dark\:text-blue-400{color:var(--color-blue-400)}.dark\:text-emerald-300{color:var(--color-emerald-300)}.dark\:text-emerald-400{color:var(--color-emerald-400)}.dark\:text-green-300{color:var(--color-green-300)}.dark\:text-purple-300{color:var(--color-purple-300)}.dark\:text-purple-400{color:var(--color-purple-400)}.dark\:text-red-300{color:var(--color-red-300)}.dark\:text-red-400{color:var(--color-red-400)}@media(hover:hover){.dark\:hover\:bg-red-800:hover{background-color:var(--color-red-800)}.dark\:hover\:bg-red-950:hover{background-color:var(--color-red-950)}}}.\[\&\:\:-moz-range-thumb\]\:h-3\.5::-moz-range-thumb{height:calc(var(--spacing) * 3.5)}.\[\&\:\:-moz-range-thumb\]\:w-3\.5::-moz-range-thumb{width:calc(var(--spacing) * 3.5)}.\[\&\:\:-moz-range-thumb\]\:rounded-full::-moz-range-thumb{border-radius:3.40282e38px}.\[\&\:\:-moz-range-thumb\]\:border-0::-moz-range-thumb{border-style:var(--tw-border-style);border-width:0}.\[\&\:\:-moz-range-thumb\]\:bg-\[hsl\(var\(--primary\)\)\]::-moz-range-thumb{background-color:hsl(var(--primary))}.\[\&\:\:-webkit-slider-thumb\]\:h-3\.5::-webkit-slider-thumb{height:calc(var(--spacing) * 3.5)}.\[\&\:\:-webkit-slider-thumb\]\:w-3\.5::-webkit-slider-thumb{width:calc(var(--spacing) * 3.5)}.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none}.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb{border-radius:3.40282e38px}.\[\&\:\:-webkit-slider-thumb\]\:bg-\[hsl\(var\(--primary\)\)\]::-webkit-slider-thumb{background-color:hsl(var(--primary))}.\[\&\:\:-webkit-slider-thumb\]\:shadow-sm::-webkit-slider-thumb{--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)}}:root{--background:0 0% 100%;--foreground:240 10% 3.9%;--card:0 0% 100%;--card-foreground:240 10% 3.9%;--popover:0 0% 100%;--popover-foreground:240 10% 3.9%;--primary:240 5.9% 10%;--primary-foreground:0 0% 98%;--secondary:240 4.8% 95.9%;--secondary-foreground:240 5.9% 10%;--muted:240 4.8% 95.9%;--muted-foreground:240 3.8% 46.1%;--accent:240 4.8% 95.9%;--accent-foreground:240 5.9% 10%;--destructive:0 84.2% 60.2%;--destructive-foreground:0 0% 98%;--border:240 5.9% 90%;--input:240 5.9% 90%;--ring:240 5.9% 10%;--radius:.5rem;--studio-green:142 71% 45%;--studio-blue:217 91% 60%;--studio-amber:38 92% 50%;--studio-red:0 84% 60%}.dark{--background:240 10% 3.9%;--foreground:0 0% 98%;--card:240 10% 3.9%;--card-foreground:0 0% 98%;--popover:240 10% 3.9%;--popover-foreground:0 0% 98%;--primary:0 0% 98%;--primary-foreground:240 5.9% 10%;--secondary:240 3.7% 15.9%;--secondary-foreground:0 0% 98%;--muted:240 3.7% 15.9%;--muted-foreground:240 5% 64.9%;--accent:240 3.7% 15.9%;--accent-foreground:0 0% 98%;--destructive:0 62.8% 30.6%;--destructive-foreground:0 0% 98%;--border:240 3.7% 15.9%;--input:240 3.7% 15.9%;--ring:240 4.9% 83.9%}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));font-family:system-ui,-apple-system,sans-serif}@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-divide-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-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-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}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes pulse{50%{opacity:.5}}
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Axl Studio</title>
7
- <script type="module" crossorigin src="./assets/index-DG2zy3iH.js"></script>
8
- <link rel="stylesheet" crossorigin href="./assets/index-WUBHc-Rd.css">
7
+ <script type="module" crossorigin src="./assets/index-CO-ZIHXe.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/index-DaCmnARn.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -45,26 +45,32 @@ interface BroadcastTarget {
45
45
  * Manages WebSocket connections and channel subscriptions.
46
46
  * Supports channel multiplexing: clients subscribe/unsubscribe to channels
47
47
  * and receive events only for channels they're subscribed to.
48
+ *
49
+ * Execution channels (`execution:*`) are replay-buffered: events are stored
50
+ * so that late subscribers receive the full event history. Buffers are cleaned
51
+ * up shortly after the stream completes.
48
52
  */
49
53
  declare class ConnectionManager {
50
54
  /** channel -> set of WS connections */
51
55
  private channels;
52
56
  /** ws -> set of subscribed channels (for cleanup) */
53
57
  private connections;
58
+ /** channel -> replay buffer for execution streams */
59
+ private buffers;
54
60
  private maxConnections;
55
61
  /** Register a new WS connection. */
56
62
  add(ws: BroadcastTarget): void;
57
63
  /** Remove a WS connection and all its subscriptions. */
58
64
  remove(ws: BroadcastTarget): void;
59
- /** Subscribe a connection to a channel. No-op if the connection was not added. */
65
+ /** Subscribe a connection to a channel. Replays buffered events for execution channels. */
60
66
  subscribe(ws: BroadcastTarget, channel: string): void;
61
67
  /** Unsubscribe a connection from a channel. */
62
68
  unsubscribe(ws: BroadcastTarget, channel: string): void;
63
- /** Broadcast data to all subscribers of a channel. */
69
+ /** Broadcast data to all subscribers of a channel. Buffers events for execution channels. */
64
70
  broadcast(channel: string, data: unknown): void;
65
71
  /** Broadcast to channel and all wildcard subscribers (e.g., trace:* matches trace:abc). */
66
72
  broadcastWithWildcard(channel: string, data: unknown): void;
67
- /** Close all connections and clear all state. Used during shutdown. */
73
+ /** Close all connections, clear all state and buffers. Used during shutdown. */
68
74
  closeAll(): void;
69
75
  /** Get the number of active connections. */
70
76
  get connectionCount(): number;
@@ -45,26 +45,32 @@ interface BroadcastTarget {
45
45
  * Manages WebSocket connections and channel subscriptions.
46
46
  * Supports channel multiplexing: clients subscribe/unsubscribe to channels
47
47
  * and receive events only for channels they're subscribed to.
48
+ *
49
+ * Execution channels (`execution:*`) are replay-buffered: events are stored
50
+ * so that late subscribers receive the full event history. Buffers are cleaned
51
+ * up shortly after the stream completes.
48
52
  */
49
53
  declare class ConnectionManager {
50
54
  /** channel -> set of WS connections */
51
55
  private channels;
52
56
  /** ws -> set of subscribed channels (for cleanup) */
53
57
  private connections;
58
+ /** channel -> replay buffer for execution streams */
59
+ private buffers;
54
60
  private maxConnections;
55
61
  /** Register a new WS connection. */
56
62
  add(ws: BroadcastTarget): void;
57
63
  /** Remove a WS connection and all its subscriptions. */
58
64
  remove(ws: BroadcastTarget): void;
59
- /** Subscribe a connection to a channel. No-op if the connection was not added. */
65
+ /** Subscribe a connection to a channel. Replays buffered events for execution channels. */
60
66
  subscribe(ws: BroadcastTarget, channel: string): void;
61
67
  /** Unsubscribe a connection from a channel. */
62
68
  unsubscribe(ws: BroadcastTarget, channel: string): void;
63
- /** Broadcast data to all subscribers of a channel. */
69
+ /** Broadcast data to all subscribers of a channel. Buffers events for execution channels. */
64
70
  broadcast(channel: string, data: unknown): void;
65
71
  /** Broadcast to channel and all wildcard subscribers (e.g., trace:* matches trace:abc). */
66
72
  broadcastWithWildcard(channel: string, data: unknown): void;
67
- /** Close all connections and clear all state. Used during shutdown. */
73
+ /** Close all connections, clear all state and buffers. Used during shutdown. */
68
74
  closeAll(): void;
69
75
  /** Get the number of active connections. */
70
76
  get connectionCount(): number;
@@ -74,11 +74,18 @@ async function errorHandler(c, next) {
74
74
  }
75
75
 
76
76
  // src/server/ws/connection-manager.ts
77
+ function isBufferedChannel(channel) {
78
+ return channel.startsWith("execution:");
79
+ }
80
+ var BUFFER_TTL_MS = 3e4;
81
+ var MAX_BUFFER_EVENTS = 500;
77
82
  var ConnectionManager = class {
78
83
  /** channel -> set of WS connections */
79
84
  channels = /* @__PURE__ */ new Map();
80
85
  /** ws -> set of subscribed channels (for cleanup) */
81
86
  connections = /* @__PURE__ */ new Map();
87
+ /** channel -> replay buffer for execution streams */
88
+ buffers = /* @__PURE__ */ new Map();
82
89
  maxConnections = 100;
83
90
  /** Register a new WS connection. */
84
91
  add(ws) {
@@ -101,7 +108,7 @@ var ConnectionManager = class {
101
108
  }
102
109
  this.connections.delete(ws);
103
110
  }
104
- /** Subscribe a connection to a channel. No-op if the connection was not added. */
111
+ /** Subscribe a connection to a channel. Replays buffered events for execution channels. */
105
112
  subscribe(ws, channel) {
106
113
  if (!this.connections.has(ws)) return;
107
114
  let subs = this.channels.get(channel);
@@ -111,6 +118,17 @@ var ConnectionManager = class {
111
118
  }
112
119
  subs.add(ws);
113
120
  this.connections.get(ws).add(channel);
121
+ const buffer = this.buffers.get(channel);
122
+ if (buffer) {
123
+ for (const msg of buffer.events) {
124
+ try {
125
+ ws.send(msg);
126
+ } catch {
127
+ this.remove(ws);
128
+ return;
129
+ }
130
+ }
131
+ }
114
132
  }
115
133
  /** Unsubscribe a connection from a channel. */
116
134
  unsubscribe(ws, channel) {
@@ -120,11 +138,30 @@ var ConnectionManager = class {
120
138
  }
121
139
  this.connections.get(ws)?.delete(channel);
122
140
  }
123
- /** Broadcast data to all subscribers of a channel. */
141
+ /** Broadcast data to all subscribers of a channel. Buffers events for execution channels. */
124
142
  broadcast(channel, data) {
143
+ const msg = JSON.stringify({ type: "event", channel, data });
144
+ if (isBufferedChannel(channel)) {
145
+ let buffer = this.buffers.get(channel);
146
+ if (!buffer) {
147
+ buffer = { events: [], complete: false };
148
+ this.buffers.set(channel, buffer);
149
+ }
150
+ const event = data;
151
+ const isTerminal = event.type === "done" || event.type === "error";
152
+ if (buffer.events.length < MAX_BUFFER_EVENTS || isTerminal) {
153
+ buffer.events.push(msg);
154
+ }
155
+ if (isTerminal) {
156
+ buffer.complete = true;
157
+ if (buffer.timer) clearTimeout(buffer.timer);
158
+ buffer.timer = setTimeout(() => {
159
+ this.buffers.delete(channel);
160
+ }, BUFFER_TTL_MS);
161
+ }
162
+ }
125
163
  const subs = this.channels.get(channel);
126
164
  if (!subs || subs.size === 0) return;
127
- const msg = JSON.stringify({ type: "event", channel, data });
128
165
  for (const ws of [...subs]) {
129
166
  try {
130
167
  ws.send(msg);
@@ -151,13 +188,17 @@ var ConnectionManager = class {
151
188
  }
152
189
  }
153
190
  }
154
- /** Close all connections and clear all state. Used during shutdown. */
191
+ /** Close all connections, clear all state and buffers. Used during shutdown. */
155
192
  closeAll() {
156
193
  for (const ws of this.connections.keys()) {
157
194
  ws.close?.();
158
195
  }
196
+ for (const buffer of this.buffers.values()) {
197
+ if (buffer.timer) clearTimeout(buffer.timer);
198
+ }
159
199
  this.connections.clear();
160
200
  this.channels.clear();
201
+ this.buffers.clear();
161
202
  }
162
203
  /** Get the number of active connections. */
163
204
  get connectionCount() {
@@ -362,15 +403,8 @@ function createWorkflowRoutes(connMgr) {
362
403
  const stream = runtime.stream(name, body.input ?? {}, { metadata: body.metadata });
363
404
  const executionId = `stream-${Date.now()}`;
364
405
  (async () => {
365
- try {
366
- for await (const event of stream) {
367
- connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
368
- }
369
- } catch (err) {
370
- connMgr.broadcastWithWildcard(`execution:${executionId}`, {
371
- type: "error",
372
- message: err instanceof Error ? err.message : "Stream error"
373
- });
406
+ for await (const event of stream) {
407
+ connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
374
408
  }
375
409
  })();
376
410
  return c.json({ ok: true, data: { executionId, streaming: true } });
@@ -451,15 +485,8 @@ function createSessionRoutes(connMgr) {
451
485
  const stream = await session.stream(body.workflow, body.message);
452
486
  const executionId = `session-${id}-${Date.now()}`;
453
487
  (async () => {
454
- try {
455
- for await (const event of stream) {
456
- connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
457
- }
458
- } catch (err) {
459
- connMgr.broadcastWithWildcard(`execution:${executionId}`, {
460
- type: "error",
461
- message: err instanceof Error ? err.message : "Stream error"
462
- });
488
+ for await (const event of stream) {
489
+ connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
463
490
  }
464
491
  })();
465
492
  return c.json({ ok: true, data: { executionId, streaming: true } });
@@ -770,26 +797,57 @@ function createPlaygroundRoutes(connMgr) {
770
797
  app7.post("/playground/chat", async (c) => {
771
798
  const runtime = c.get("runtime");
772
799
  const body = await c.req.json();
773
- const workflowName = body.workflow ?? runtime.getWorkflowNames()[0];
774
- if (!workflowName) {
800
+ if (!body.message || typeof body.message !== "string" || !body.message.trim()) {
801
+ return c.json(
802
+ {
803
+ ok: false,
804
+ error: {
805
+ code: "INVALID_INPUT",
806
+ message: "message is required and must be a non-empty string"
807
+ }
808
+ },
809
+ 400
810
+ );
811
+ }
812
+ const agents = runtime.getAgents();
813
+ const agent = body.agent ? agents.find((a) => a._name === body.agent) : agents[0];
814
+ if (!agent) {
775
815
  return c.json(
776
- { ok: false, error: { code: "NO_WORKFLOW", message: "No workflows registered" } },
816
+ {
817
+ ok: false,
818
+ error: { code: "NO_AGENT", message: `Agent "${body.agent ?? ""}" not found` }
819
+ },
777
820
  400
778
821
  );
779
822
  }
780
823
  const sessionId = body.sessionId ?? `playground-${Date.now()}`;
781
- const session = runtime.session(sessionId);
782
- const stream = await session.stream(workflowName, body.message);
783
824
  const executionId = `playground-${sessionId}-${Date.now()}`;
825
+ const store = runtime.getStateStore();
826
+ const history = await store.getSession(sessionId);
827
+ history.push({ role: "user", content: body.message });
828
+ const ctx = runtime.createContext({
829
+ sessionHistory: history,
830
+ onToken: (token) => {
831
+ connMgr.broadcastWithWildcard(`execution:${executionId}`, {
832
+ type: "token",
833
+ data: token
834
+ });
835
+ }
836
+ });
784
837
  (async () => {
785
838
  try {
786
- for await (const event of stream) {
787
- connMgr.broadcastWithWildcard(`execution:${executionId}`, event);
788
- }
839
+ const result = await ctx.ask(agent, body.message);
840
+ const resultText = typeof result === "string" ? result : JSON.stringify(result);
841
+ history.push({ role: "assistant", content: resultText });
842
+ await store.saveSession(sessionId, history);
843
+ connMgr.broadcastWithWildcard(`execution:${executionId}`, {
844
+ type: "done",
845
+ data: resultText
846
+ });
789
847
  } catch (err) {
790
848
  connMgr.broadcastWithWildcard(`execution:${executionId}`, {
791
849
  type: "error",
792
- message: err instanceof Error ? err.message : "Stream error"
850
+ message: err instanceof Error ? err.message : String(err)
793
851
  });
794
852
  }
795
853
  })();
@@ -901,19 +959,24 @@ function createServer(options) {
901
959
  app7.use("/*", async (c, next) => {
902
960
  const reqPath = c.req.path;
903
961
  const resolved = basePath && reqPath.startsWith(basePath) ? reqPath.slice(basePath.length) || "/" : reqPath;
904
- if (resolved === "/" || resolved === "/index.html") {
962
+ if (resolved === "/" || resolved === "/index.html" || resolved === "/ws") {
905
963
  return next();
906
964
  }
907
965
  return staticHandler(c, next);
908
966
  });
909
967
  if (spaHtml) {
910
- app7.get("*", (c) => c.html(spaHtml));
968
+ app7.get("*", async (c, next) => {
969
+ const resolved = basePath && c.req.path.startsWith(basePath) ? c.req.path.slice(basePath.length) || "/" : c.req.path;
970
+ if (resolved === "/ws") return next();
971
+ return c.html(spaHtml);
972
+ });
911
973
  }
912
974
  }
913
975
  return {
914
976
  app: app7,
915
977
  connMgr,
916
978
  costAggregator,
979
+ /** Create WS handlers. Call before registering static/SPA routes are reached. */
917
980
  createWsHandlers: () => createWsHandlers(connMgr),
918
981
  traceListener
919
982
  };