@ash-cloud/ash-ui 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.bottom-0{bottom:0}.left-0{left:0}.left-\[19px\]{left:19px}.right-0{right:0}.right-3{right:.75rem}.top-1\/2{top:50%}.top-10{top:2.5rem}.z-10{z-index:10}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.ml-0\.5{margin-left:.125rem}.ml-6{margin-left:1.5rem}.mr-1\.5{margin-right:.375rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-12{height:3rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-full{height:100%}.max-h-\[400px\]{max-height:400px}.w-0\.5{width:.125rem}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0}.min-w-\[3rem\]{min-width:3rem}.max-w-\[85\%\]{max-width:85%}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y:-50%}.-translate-y-1\/2,.rotate-180{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate:180deg}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-0{border-width:0}.border-b{border-bottom-width:1px}.border-l-2{border-left-width:2px}.border-t{border-top-width:1px}.border-orange-500\/30{border-color:rgba(249,115,22,.3)}.border-purple-500\/30{border-color:rgba(168,85,247,.3)}.border-red-500\/30{border-color:rgba(239,68,68,.3)}.border-white\/10{border-color:hsla(0,0%,100%,.1)}.border-white\/20{border-color:hsla(0,0%,100%,.2)}.border-white\/5{border-color:hsla(0,0%,100%,.05)}.border-yellow-500\/30{border-color:rgba(234,179,8,.3)}.bg-\[var\(--ash-accent\)\]{background-color:var(--ash-accent)}.bg-\[var\(--ash-surface-dark\2c \#0a0a0a\)\]{background-color:var(--ash-surface-dark,#0a0a0a)}.bg-black\/20{background-color:rgba(0,0,0,.2)}.bg-blue-900\/20{background-color:rgba(30,58,138,.2)}.bg-current{background-color:currentColor}.bg-emerald-400{--tw-bg-opacity:1;background-color:rgb(52 211 153/var(--tw-bg-opacity,1))}.bg-orange-500\/20{background-color:rgba(249,115,22,.2)}.bg-orange-500\/5{background-color:rgba(249,115,22,.05)}.bg-purple-500\/10{background-color:rgba(168,85,247,.1)}.bg-purple-500\/20{background-color:rgba(168,85,247,.2)}.bg-red-500\/10{background-color:rgba(239,68,68,.1)}.bg-red-500\/20{background-color:rgba(239,68,68,.2)}.bg-red-500\/5{background-color:rgba(239,68,68,.05)}.bg-red-900\/20{background-color:rgba(127,29,29,.2)}.bg-red-900\/50{background-color:rgba(127,29,29,.5)}.bg-white\/10{background-color:hsla(0,0%,100%,.1)}.bg-white\/5{background-color:hsla(0,0%,100%,.05)}.bg-yellow-500\/10{background-color:rgba(234,179,8,.1)}.bg-yellow-500\/20{background-color:rgba(234,179,8,.2)}.bg-yellow-500\/5{background-color:rgba(234,179,8,.05)}.bg-yellow-900\/20{background-color:rgba(113,63,18,.2)}.bg-yellow-900\/50{background-color:rgba(113,63,18,.5)}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-2{padding-bottom:.5rem}.pl-4{padding-left:1rem}.pr-2{padding-right:.5rem}.pt-0\.5{padding-top:.125rem}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.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)}.leading-relaxed{line-height:1.625}.text-\[var\(--ash-accent\)\]{color:var(--ash-accent)}.text-\[var\(--ash-accent-foreground\)\]{color:var(--ash-accent-foreground)}.text-blue-400{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity,1))}.text-emerald-400{--tw-text-opacity:1;color:rgb(52 211 153/var(--tw-text-opacity,1))}.text-orange-400{--tw-text-opacity:1;color:rgb(251 146 60/var(--tw-text-opacity,1))}.text-purple-300{--tw-text-opacity:1;color:rgb(216 180 254/var(--tw-text-opacity,1))}.text-purple-400{--tw-text-opacity:1;color:rgb(192 132 252/var(--tw-text-opacity,1))}.text-red-300{--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.text-red-400{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.text-red-400\/70{color:hsla(0,91%,71%,.7)}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.text-white\/30{color:hsla(0,0%,100%,.3)}.text-white\/40{color:hsla(0,0%,100%,.4)}.text-white\/50{color:hsla(0,0%,100%,.5)}.text-white\/60{color:hsla(0,0%,100%,.6)}.text-white\/70{color:hsla(0,0%,100%,.7)}.text-white\/80{color:hsla(0,0%,100%,.8)}.text-white\/90{color:hsla(0,0%,100%,.9)}.text-yellow-400{--tw-text-opacity:1;color:rgb(250 204 21/var(--tw-text-opacity,1))}.text-yellow-500{--tw-text-opacity:1;color:rgb(234 179 8/var(--tw-text-opacity,1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-80{opacity:.8}.blur{--tw-blur:blur(8px)}.blur,.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:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-500{transition-duration:.5s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}:root{--ash-accent:#cf0;--ash-accent-foreground:#000;--ash-accent-50:#f8ffe5;--ash-accent-100:#eeffb8;--ash-accent-200:#e0ff85;--ash-accent-300:#d4ff52;--ash-accent-400:#cf0;--ash-accent-500:#b8e600;--ash-accent-600:#9c0;--ash-accent-700:#739900;--ash-accent-800:#4d6600;--ash-accent-900:#263300;--ash-surface-dark:#0a0a0a;--ash-surface-darker:#050505;--ash-surface-card:#0c0c0c;--ash-surface-elevated:#111;--ash-surface-border:hsla(0,0%,100%,.1)}.ash-glass-panel{border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);--tw-backdrop-blur:blur(24px)}.ash-glass-panel,.ash-glass-panel-elevated{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);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)}.ash-glass-panel-elevated{background-color:hsla(0,0%,100%,.08);border-width:1px;--tw-shadow:0 25px 50px -12px rgba(0,0,0,.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);--tw-backdrop-blur:blur(40px);border-color:hsla(0,0%,100%,.15)}.ash-card-glass{border-radius:1rem;border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);--tw-backdrop-blur:blur(24px);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);--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-card-glass,.ash-card-glass:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.ash-card-glass:hover{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);border-color:hsla(0,0%,100%,.2);background-color:hsla(0,0%,100%,.08)}.ash-btn-accent{border-radius:9999px;background-color:var(--ash-accent);padding:.75rem 1.5rem;font-weight:500;--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1));border-width:1px;border-color:var(--ash-accent);box-shadow:0 0 20px rgba(204,255,0,.3);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-btn-accent:hover{background-color:var(--ash-accent-500);box-shadow:0 0 30px rgba(204,255,0,.5)}.ash-btn-ghost{border-radius:.75rem;padding:.5rem 1rem;color:hsla(0,0%,100%,.7)}.ash-btn-ghost:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.ash-btn-ghost{border-width:1px;border-color:transparent;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-btn-ghost:hover{background-color:hsla(0,0%,100%,.1);border-color:hsla(0,0%,100%,.1)}.ash-btn-outline{border-radius:.75rem;border-width:1px;border-color:hsla(0,0%,100%,.2);padding:.5rem 1rem;color:hsla(0,0%,100%,.8);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-btn-outline:hover{border-color:hsla(0,0%,100%,.3);background-color:hsla(0,0%,100%,.1)}.ash-input-glass{width:100%;border-radius:.75rem;padding:.75rem 1rem;border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.ash-input-glass::-moz-placeholder{color:hsla(0,0%,100%,.4)}.ash-input-glass::placeholder{color:hsla(0,0%,100%,.4)}.ash-input-glass:focus{background-color:hsla(0,0%,100%,.1);outline:2px solid transparent;outline-offset:2px}.ash-input-glass{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-input-glass:focus{border-color:rgba(204,255,0,.5);box-shadow:0 0 20px rgba(204,255,0,.15)}.ash-message-content pre{margin-top:.5rem;margin-bottom:.5rem;overflow-x:auto;border-radius:.75rem;background-color:rgba(0,0,0,.4);padding:1rem;--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity,1));border-width:1px;border-color:hsla(0,0%,100%,.1)}.ash-message-content code{border-radius:.25rem;background-color:hsla(0,0%,100%,.1);padding:.125rem .375rem;font-size:.875rem;line-height:1.25rem;color:var(--ash-accent)}.ash-message-content pre code{background-color:transparent;padding:0;--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity,1))}@keyframes ash-tool-pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes ash-glow-pulse{0%,to{box-shadow:0 0 20px rgba(204,255,0,.3)}50%{box-shadow:0 0 40px rgba(204,255,0,.5)}}.ash-tool-status-pending{animation:ash-tool-pulse 1.5s ease-in-out infinite}.ash-tool-card-details{transition:max-height .2s ease-out,opacity .2s ease-out}.ash-tool-code-block{overflow-x:auto;border-radius:.75rem;background-color:rgba(0,0,0,.4);padding:.75rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.75rem;line-height:1rem;border-width:1px;border-color:hsla(0,0%,100%,.1);word-break:break-word;white-space:pre-wrap}.ash-tool-section-header{border-bottom-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);padding:.5rem .75rem;font-size:.75rem;line-height:1rem;font-weight:500;text-transform:uppercase;letter-spacing:.025em;color:hsla(0,0%,100%,.5)}.ash-status-pending{--tw-bg-opacity:1;background-color:rgb(250 204 21/var(--tw-bg-opacity,1));animation:ash-tool-pulse 1.5s ease-in-out infinite}.ash-status-success{background-color:var(--ash-accent)}.ash-status-failed{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.ash-truncate-fade{background:linear-gradient(0deg,#0a0a0a,transparent)}.ash-ambient-glow{pointer-events:none;position:absolute;border-radius:9999px;opacity:.08;--tw-blur:blur(120px);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)}.ash-ambient-glow-accent{background:radial-gradient(circle,rgba(204,255,0,.15) 0,transparent 70%)}.ash-ambient-glow-green{background:radial-gradient(circle,rgba(5,46,22,.25) 0,transparent 70%)}.ash-grid-pattern{background-image:linear-gradient(hsla(0,0%,100%,.03) 1px,transparent 0),linear-gradient(90deg,hsla(0,0%,100%,.03) 1px,transparent 0);background-size:50px 50px}.ash-noise-overlay{opacity:.02;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='.9' numOctaves='4' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)'/%3E%3C/svg%3E")}@keyframes ash-fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes ash-slide-up{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes ash-pulse-slow{0%,to{opacity:.06}50%{opacity:.1}}.ash-animate-fade-in{animation:ash-fade-in .3s ease-out forwards}.ash-animate-slide-up{animation:ash-slide-up .4s ease-out forwards}.ash-animate-pulse-slow{animation:ash-pulse-slow 8s ease-in-out infinite}.ash-delay-100{animation-delay:.1s}.ash-delay-200{animation-delay:.2s}.ash-delay-300{animation-delay:.3s}.ash-delay-400{animation-delay:.4s}@keyframes ash-status-line-enter{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes ash-status-line-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}@keyframes ash-status-line-replace{0%{opacity:1;transform:translateX(0)}50%{opacity:0;transform:translateX(-20px)}51%{opacity:0;transform:translateX(20px)}to{opacity:1;transform:translateX(0)}}@keyframes ash-text-shimmer{0%{background-position:-200%}to{background-position:200%}}.ash-status-line-enter{animation:ash-status-line-enter ease-out forwards}.ash-status-line-exit{animation:ash-status-line-exit ease-out forwards}.ash-status-line-replace{animation:ash-status-line-replace ease-in-out forwards}.ash-text-shimmer{background:linear-gradient(90deg,hsla(0,0%,100%,.6),#fff 50%,hsla(0,0%,100%,.6));background-size:200% auto;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;animation:ash-text-shimmer 2s linear infinite}.ash-execution-connector{position:absolute;left:1rem;top:2.5rem;bottom:0;width:1px;background:linear-gradient(180deg,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.05))}@keyframes ash-accordion-expand{0%{opacity:0;max-height:0;transform:translateY(-10px)}to{opacity:1;max-height:2000px;transform:translateY(0)}}.ash-accordion-content{animation:ash-accordion-expand .3s ease-out forwards;overflow:hidden}.ash-badge{display:inline-flex;align-items:center;border-radius:9999px;padding:.25rem .625rem;font-size:.75rem;line-height:1rem;font-weight:500}.ash-badge-accent{background-color:rgba(204,255,0,.2);color:var(--ash-accent);border:1px solid rgba(204,255,0,.3)}.ash-badge-success{background-color:rgba(16,185,129,.2);color:#34d399;border:1px solid rgba(16,185,129,.3)}.ash-badge-warning{background-color:rgba(234,179,8,.2);color:#facc15;border:1px solid rgba(234,179,8,.3)}.ash-badge-error{background-color:rgba(239,68,68,.2);color:#f87171;border:1px solid rgba(239,68,68,.3)}.ash-badge-info{background-color:rgba(59,130,246,.2);color:#60a5fa;border:1px solid rgba(59,130,246,.3)}.ash-scrollbar::-webkit-scrollbar{width:8px;height:8px}.ash-scrollbar::-webkit-scrollbar-track{background:hsla(0,0%,100%,.05);border-radius:4px}.ash-scrollbar::-webkit-scrollbar-thumb{background:hsla(0,0%,100%,.15);border-radius:4px}.ash-scrollbar::-webkit-scrollbar-thumb:hover{background:hsla(0,0%,100%,.25)}.ash-message-content.prose-invert{--tw-prose-body:hsla(0,0%,100%,.8);--tw-prose-headings:#fff;--tw-prose-links:var(--ash-accent);--tw-prose-bold:#fff;--tw-prose-code:var(--ash-accent);--tw-prose-quotes:hsla(0,0%,100%,.6)}.ash-message-content a{color:var(--ash-accent);text-decoration:underline;text-underline-offset:2px}.ash-message-content a:hover{opacity:.8}.ash-message-content ol,.ash-message-content ul{margin-top:.5rem;margin-bottom:.5rem}.ash-message-content li{margin-top:.25rem;margin-bottom:.25rem}.ash-message-content p{margin-top:.5rem;margin-bottom:.5rem}.ash-message-content p:first-child{margin-top:0}.ash-message-content p:last-child{margin-bottom:0}.ash-card-glow{border-color:rgba(204,255,0,.2);box-shadow:0 0 20px rgba(204,255,0,.08);transition:all .4s cubic-bezier(.4,0,.2,1)}.ash-card-glow:hover{border-color:rgba(204,255,0,.4);box-shadow:0 0 30px rgba(204,255,0,.15);transform:translateY(-2px) scale(1.01)}.ash-container{background-color:var(--ash-surface-dark);color:#fff}.ash-chat-container{display:flex;height:100%;flex-direction:column;background-color:var(--ash-surface-card);border-radius:.75rem;border-width:1px;border-color:hsla(0,0%,100%,.05)}.ash-env-vars-panel{margin-bottom:.75rem}.ash-env-vars-header{display:flex;align-items:center;gap:.5rem;font-size:.75rem;line-height:1rem;font-weight:500;cursor:pointer;color:hsla(0,0%,100%,.5);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ash-env-vars-header:hover{color:hsla(0,0%,100%,.8)}.ash-env-vars-chevron{height:.75rem;width:.75rem;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ash-env-vars-chevron-expanded{transform:rotate(90deg)}.ash-env-vars-label{text-transform:uppercase;letter-spacing:.025em}.ash-env-vars-badge{display:inline-flex;height:1.25rem;min-width:20px;align-items:center;justify-content:center;padding-left:.375rem;padding-right:.375rem;border-radius:9999px;font-size:.75rem;line-height:1rem;font-weight:500;background-color:rgba(204,255,0,.2);color:var(--ash-accent)}.ash-env-vars-content{margin-top:.5rem}.ash-env-vars-content>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ash-env-vars-item{display:flex;align-items:center;gap:.5rem;border-radius:.75rem;border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);padding:.5rem .75rem;font-size:.875rem;line-height:1.25rem}.ash-env-vars-key{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-weight:500;color:var(--ash-accent)}.ash-env-vars-equals{color:hsla(0,0%,100%,.4)}.ash-env-vars-value{flex:1 1 0%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;color:hsla(0,0%,100%,.7)}.ash-env-vars-remove{cursor:pointer;color:hsla(0,0%,100%,.4);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ash-env-vars-remove:hover{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.ash-env-vars-add{display:flex;align-items:center;gap:.5rem}.ash-env-vars-input{border-radius:.75rem;padding:.5rem .75rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem;border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-env-vars-input:focus{outline:2px solid transparent;outline-offset:2px;border-color:rgba(204,255,0,.5)}.ash-env-vars-input-key{min-width:0;flex:1 1 0%}.ash-env-vars-input-value{min-width:0;flex:2}.ash-env-vars-add-button{border-radius:.75rem;padding:.5rem .75rem;font-size:.875rem;line-height:1.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s;background-color:rgba(204,255,0,.2);color:var(--ash-accent)}.ash-env-vars-add-button:disabled{cursor:not-allowed;opacity:.3}.ash-env-vars-add-button:hover:not(:disabled){background-color:rgba(204,255,0,.3)}.ash-env-vars-helper{margin-top:.25rem;font-size:.75rem;line-height:1rem;color:hsla(0,0%,100%,.4)}.ash-display-mode-toggle{display:flex;align-items:center;gap:.375rem;border-radius:.5rem;padding:.375rem .5rem;border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);font-size:.875rem;line-height:1.25rem;color:hsla(0,0%,100%,.7)}.ash-display-mode-toggle:hover{border-color:hsla(0,0%,100%,.2);background-color:hsla(0,0%,100%,.1);--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.ash-display-mode-toggle{cursor:pointer;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-display-mode-icon{height:1rem;width:1rem}.ash-display-mode-label{display:none}@media (min-width:640px){.ash-display-mode-label{display:inline}}.last\:border-b-0:last-child{border-bottom-width:0}.hover\:bg-white\/5:hover{background-color:hsla(0,0%,100%,.05)}.hover\:text-\[var\(--ash-accent-300\)\]:hover{color:var(--ash-accent-300)}.hover\:text-blue-300:hover{--tw-text-opacity:1;color:rgb(147 197 253/var(--tw-text-opacity,1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.group:hover .group-hover\:translate-x-0\.5{--tw-translate-x:0.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:text-\[var\(--ash-accent\)\]{color:var(--ash-accent)}.group:hover .group-hover\:text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.group:hover .group-hover\:text-white\/60{color:hsla(0,0%,100%,.6)}
1
+ *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.bottom-0{bottom:0}.left-0{left:0}.left-\[19px\]{left:19px}.right-0{right:0}.right-3{right:.75rem}.top-1\/2{top:50%}.top-10{top:2.5rem}.z-10{z-index:10}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.ml-0\.5{margin-left:.125rem}.ml-6{margin-left:1.5rem}.mr-1\.5{margin-right:.375rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-12{height:3rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-full{height:100%}.max-h-\[400px\]{max-height:400px}.w-0\.5{width:.125rem}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-full{width:100%}.w-px{width:1px}.min-w-0{min-width:0}.min-w-\[3rem\]{min-width:3rem}.max-w-\[85\%\]{max-width:85%}.max-w-none{max-width:none}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y:-50%}.-rotate-90,.-translate-y-1\/2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-rotate-90{--tw-rotate:-90deg}.rotate-180{--tw-rotate:180deg}.rotate-180,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem*var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem*var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px*var(--tw-divide-y-reverse))}.divide-white\/5>:not([hidden])~:not([hidden]){border-color:hsla(0,0%,100%,.05)}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-0{border-width:0}.border-b{border-bottom-width:1px}.border-l-2{border-left-width:2px}.border-t{border-top-width:1px}.border-orange-500\/30{border-color:rgba(249,115,22,.3)}.border-purple-500\/30{border-color:rgba(168,85,247,.3)}.border-red-500\/30{border-color:rgba(239,68,68,.3)}.border-white\/10{border-color:hsla(0,0%,100%,.1)}.border-white\/20{border-color:hsla(0,0%,100%,.2)}.border-white\/5{border-color:hsla(0,0%,100%,.05)}.border-yellow-500\/30{border-color:rgba(234,179,8,.3)}.bg-\[var\(--ash-accent\)\]{background-color:var(--ash-accent)}.bg-\[var\(--ash-surface-dark\2c \#0a0a0a\)\]{background-color:var(--ash-surface-dark,#0a0a0a)}.bg-black\/20{background-color:rgba(0,0,0,.2)}.bg-blue-900\/20{background-color:rgba(30,58,138,.2)}.bg-current{background-color:currentColor}.bg-emerald-400{--tw-bg-opacity:1;background-color:rgb(52 211 153/var(--tw-bg-opacity,1))}.bg-orange-500\/20{background-color:rgba(249,115,22,.2)}.bg-orange-500\/5{background-color:rgba(249,115,22,.05)}.bg-purple-500\/10{background-color:rgba(168,85,247,.1)}.bg-purple-500\/20{background-color:rgba(168,85,247,.2)}.bg-red-500\/10{background-color:rgba(239,68,68,.1)}.bg-red-500\/20{background-color:rgba(239,68,68,.2)}.bg-red-500\/5{background-color:rgba(239,68,68,.05)}.bg-red-900\/20{background-color:rgba(127,29,29,.2)}.bg-red-900\/50{background-color:rgba(127,29,29,.5)}.bg-white\/10{background-color:hsla(0,0%,100%,.1)}.bg-white\/5{background-color:hsla(0,0%,100%,.05)}.bg-yellow-500\/10{background-color:rgba(234,179,8,.1)}.bg-yellow-500\/20{background-color:rgba(234,179,8,.2)}.bg-yellow-500\/5{background-color:rgba(234,179,8,.05)}.bg-yellow-900\/20{background-color:rgba(113,63,18,.2)}.bg-yellow-900\/50{background-color:rgba(113,63,18,.5)}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-2{padding-bottom:.5rem}.pl-4{padding-left:1rem}.pr-2{padding-right:.5rem}.pt-0\.5{padding-top:.125rem}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.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)}.leading-relaxed{line-height:1.625}.text-\[var\(--ash-accent\)\]{color:var(--ash-accent)}.text-\[var\(--ash-accent-foreground\)\]{color:var(--ash-accent-foreground)}.text-blue-400{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity,1))}.text-emerald-400{--tw-text-opacity:1;color:rgb(52 211 153/var(--tw-text-opacity,1))}.text-orange-400{--tw-text-opacity:1;color:rgb(251 146 60/var(--tw-text-opacity,1))}.text-purple-300{--tw-text-opacity:1;color:rgb(216 180 254/var(--tw-text-opacity,1))}.text-purple-400{--tw-text-opacity:1;color:rgb(192 132 252/var(--tw-text-opacity,1))}.text-red-300{--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.text-red-400{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.text-red-400\/70{color:hsla(0,91%,71%,.7)}.text-red-400\/80{color:hsla(0,91%,71%,.8)}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.text-white\/30{color:hsla(0,0%,100%,.3)}.text-white\/40{color:hsla(0,0%,100%,.4)}.text-white\/50{color:hsla(0,0%,100%,.5)}.text-white\/60{color:hsla(0,0%,100%,.6)}.text-white\/70{color:hsla(0,0%,100%,.7)}.text-white\/80{color:hsla(0,0%,100%,.8)}.text-white\/90{color:hsla(0,0%,100%,.9)}.text-yellow-400{--tw-text-opacity:1;color:rgb(250 204 21/var(--tw-text-opacity,1))}.text-yellow-500{--tw-text-opacity:1;color:rgb(234 179 8/var(--tw-text-opacity,1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-80{opacity:.8}.blur{--tw-blur:blur(8px)}.blur,.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:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-500{transition-duration:.5s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}:root{--ash-accent:#cf0;--ash-accent-foreground:#000;--ash-accent-50:#f8ffe5;--ash-accent-100:#eeffb8;--ash-accent-200:#e0ff85;--ash-accent-300:#d4ff52;--ash-accent-400:#cf0;--ash-accent-500:#b8e600;--ash-accent-600:#9c0;--ash-accent-700:#739900;--ash-accent-800:#4d6600;--ash-accent-900:#263300;--ash-surface-dark:#0a0a0a;--ash-surface-darker:#050505;--ash-surface-card:#0c0c0c;--ash-surface-elevated:#111;--ash-surface-border:hsla(0,0%,100%,.1)}.ash-glass-panel{border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);--tw-backdrop-blur:blur(24px)}.ash-glass-panel,.ash-glass-panel-elevated{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);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)}.ash-glass-panel-elevated{background-color:hsla(0,0%,100%,.08);border-width:1px;--tw-shadow:0 25px 50px -12px rgba(0,0,0,.25);--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);--tw-backdrop-blur:blur(40px);border-color:hsla(0,0%,100%,.15)}.ash-card-glass{border-radius:1rem;border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);--tw-backdrop-blur:blur(24px);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);--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-card-glass,.ash-card-glass:hover{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.ash-card-glass:hover{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);border-color:hsla(0,0%,100%,.2);background-color:hsla(0,0%,100%,.08)}.ash-btn-accent{border-radius:9999px;background-color:var(--ash-accent);padding:.75rem 1.5rem;font-weight:500;--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1));border-width:1px;border-color:var(--ash-accent);box-shadow:0 0 20px rgba(204,255,0,.3);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-btn-accent:hover{background-color:var(--ash-accent-500);box-shadow:0 0 30px rgba(204,255,0,.5)}.ash-btn-ghost{border-radius:.75rem;padding:.5rem 1rem;color:hsla(0,0%,100%,.7)}.ash-btn-ghost:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.ash-btn-ghost{border-width:1px;border-color:transparent;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-btn-ghost:hover{background-color:hsla(0,0%,100%,.1);border-color:hsla(0,0%,100%,.1)}.ash-btn-outline{border-radius:.75rem;border-width:1px;border-color:hsla(0,0%,100%,.2);padding:.5rem 1rem;color:hsla(0,0%,100%,.8);transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-btn-outline:hover{border-color:hsla(0,0%,100%,.3);background-color:hsla(0,0%,100%,.1)}.ash-input-glass{width:100%;border-radius:.75rem;padding:.75rem 1rem;border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.ash-input-glass::-moz-placeholder{color:hsla(0,0%,100%,.4)}.ash-input-glass::placeholder{color:hsla(0,0%,100%,.4)}.ash-input-glass:focus{background-color:hsla(0,0%,100%,.1);outline:2px solid transparent;outline-offset:2px}.ash-input-glass{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-input-glass:focus{border-color:rgba(204,255,0,.5);box-shadow:0 0 20px rgba(204,255,0,.15)}.ash-message-content pre{margin-top:.5rem;margin-bottom:.5rem;overflow-x:auto;border-radius:.75rem;background-color:rgba(0,0,0,.4);padding:1rem;--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity,1));border-width:1px;border-color:hsla(0,0%,100%,.1)}.ash-message-content code{border-radius:.25rem;background-color:hsla(0,0%,100%,.1);padding:.125rem .375rem;font-size:.875rem;line-height:1.25rem;color:var(--ash-accent)}.ash-message-content pre code{background-color:transparent;padding:0;--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity,1))}@keyframes ash-tool-pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes ash-glow-pulse{0%,to{box-shadow:0 0 20px rgba(204,255,0,.3)}50%{box-shadow:0 0 40px rgba(204,255,0,.5)}}.ash-tool-status-pending{animation:ash-tool-pulse 1.5s ease-in-out infinite}.ash-tool-card-details{transition:max-height .2s ease-out,opacity .2s ease-out}.ash-tool-code-block{overflow-x:auto;border-radius:.75rem;background-color:rgba(0,0,0,.4);padding:.75rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.75rem;line-height:1rem;border-width:1px;border-color:hsla(0,0%,100%,.1);word-break:break-word;white-space:pre-wrap}.ash-tool-section-header{border-bottom-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);padding:.5rem .75rem;font-size:.75rem;line-height:1rem;font-weight:500;text-transform:uppercase;letter-spacing:.025em;color:hsla(0,0%,100%,.5)}.ash-status-pending{--tw-bg-opacity:1;background-color:rgb(250 204 21/var(--tw-bg-opacity,1));animation:ash-tool-pulse 1.5s ease-in-out infinite}.ash-status-success{background-color:var(--ash-accent)}.ash-status-failed{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.ash-truncate-fade{background:linear-gradient(0deg,#0a0a0a,transparent)}.ash-ambient-glow{pointer-events:none;position:absolute;border-radius:9999px;opacity:.08;--tw-blur:blur(120px);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)}.ash-ambient-glow-accent{background:radial-gradient(circle,rgba(204,255,0,.15) 0,transparent 70%)}.ash-ambient-glow-green{background:radial-gradient(circle,rgba(5,46,22,.25) 0,transparent 70%)}.ash-grid-pattern{background-image:linear-gradient(hsla(0,0%,100%,.03) 1px,transparent 0),linear-gradient(90deg,hsla(0,0%,100%,.03) 1px,transparent 0);background-size:50px 50px}.ash-noise-overlay{opacity:.02;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cfilter id='a'%3E%3CfeTurbulence baseFrequency='.9' numOctaves='4' stitchTiles='stitch' type='fractalNoise'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)'/%3E%3C/svg%3E")}@keyframes ash-fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes ash-slide-up{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes ash-pulse-slow{0%,to{opacity:.06}50%{opacity:.1}}.ash-animate-fade-in{animation:ash-fade-in .3s ease-out forwards}.ash-animate-slide-up{animation:ash-slide-up .4s ease-out forwards}.ash-animate-pulse-slow{animation:ash-pulse-slow 8s ease-in-out infinite}.ash-delay-100{animation-delay:.1s}.ash-delay-200{animation-delay:.2s}.ash-delay-300{animation-delay:.3s}.ash-delay-400{animation-delay:.4s}@keyframes ash-status-line-enter{0%{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}@keyframes ash-status-line-exit{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-100%)}}@keyframes ash-status-line-replace{0%{opacity:1;transform:translateX(0)}50%{opacity:0;transform:translateX(-20px)}51%{opacity:0;transform:translateX(20px)}to{opacity:1;transform:translateX(0)}}@keyframes ash-text-shimmer{0%{background-position:-200%}to{background-position:200%}}.ash-status-line-enter{animation:ash-status-line-enter ease-out forwards}.ash-status-line-exit{animation:ash-status-line-exit ease-out forwards}.ash-status-line-replace{animation:ash-status-line-replace ease-in-out forwards}.ash-text-shimmer{background:linear-gradient(90deg,hsla(0,0%,100%,.6),#fff 50%,hsla(0,0%,100%,.6));background-size:200% auto;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;animation:ash-text-shimmer 2s linear infinite}.ash-execution-connector{position:absolute;left:1rem;top:2.5rem;bottom:0;width:1px;background:linear-gradient(180deg,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.05))}@keyframes ash-accordion-expand{0%{opacity:0;max-height:0;transform:translateY(-10px)}to{opacity:1;max-height:2000px;transform:translateY(0)}}.ash-accordion-content{animation:ash-accordion-expand .3s ease-out forwards;overflow:hidden}.ash-badge{display:inline-flex;align-items:center;border-radius:9999px;padding:.25rem .625rem;font-size:.75rem;line-height:1rem;font-weight:500}.ash-badge-accent{background-color:rgba(204,255,0,.2);color:var(--ash-accent);border:1px solid rgba(204,255,0,.3)}.ash-badge-success{background-color:rgba(16,185,129,.2);color:#34d399;border:1px solid rgba(16,185,129,.3)}.ash-badge-warning{background-color:rgba(234,179,8,.2);color:#facc15;border:1px solid rgba(234,179,8,.3)}.ash-badge-error{background-color:rgba(239,68,68,.2);color:#f87171;border:1px solid rgba(239,68,68,.3)}.ash-badge-info{background-color:rgba(59,130,246,.2);color:#60a5fa;border:1px solid rgba(59,130,246,.3)}.ash-scrollbar::-webkit-scrollbar{width:8px;height:8px}.ash-scrollbar::-webkit-scrollbar-track{background:hsla(0,0%,100%,.05);border-radius:4px}.ash-scrollbar::-webkit-scrollbar-thumb{background:hsla(0,0%,100%,.15);border-radius:4px}.ash-scrollbar::-webkit-scrollbar-thumb:hover{background:hsla(0,0%,100%,.25)}.ash-message-content.prose-invert{--tw-prose-body:hsla(0,0%,100%,.8);--tw-prose-headings:#fff;--tw-prose-links:var(--ash-accent);--tw-prose-bold:#fff;--tw-prose-code:var(--ash-accent);--tw-prose-quotes:hsla(0,0%,100%,.6)}.ash-message-content a{color:var(--ash-accent);text-decoration:underline;text-underline-offset:2px}.ash-message-content a:hover{opacity:.8}.ash-message-content ol,.ash-message-content ul{margin-top:.5rem;margin-bottom:.5rem}.ash-message-content li{margin-top:.25rem;margin-bottom:.25rem}.ash-message-content p{margin-top:.5rem;margin-bottom:.5rem}.ash-message-content p:first-child{margin-top:0}.ash-message-content p:last-child{margin-bottom:0}.ash-card-glow{border-color:rgba(204,255,0,.2);box-shadow:0 0 20px rgba(204,255,0,.08);transition:all .4s cubic-bezier(.4,0,.2,1)}.ash-card-glow:hover{border-color:rgba(204,255,0,.4);box-shadow:0 0 30px rgba(204,255,0,.15);transform:translateY(-2px) scale(1.01)}.ash-container{background-color:var(--ash-surface-dark);color:#fff}.ash-chat-container{display:flex;height:100%;flex-direction:column;background-color:var(--ash-surface-card);border-radius:.75rem;border-width:1px;border-color:hsla(0,0%,100%,.05)}.ash-env-vars-panel{margin-bottom:.75rem}.ash-env-vars-header{display:flex;align-items:center;gap:.5rem;font-size:.75rem;line-height:1rem;font-weight:500;cursor:pointer;color:hsla(0,0%,100%,.5);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ash-env-vars-header:hover{color:hsla(0,0%,100%,.8)}.ash-env-vars-chevron{height:.75rem;width:.75rem;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ash-env-vars-chevron-expanded{transform:rotate(90deg)}.ash-env-vars-label{text-transform:uppercase;letter-spacing:.025em}.ash-env-vars-badge{display:inline-flex;height:1.25rem;min-width:20px;align-items:center;justify-content:center;padding-left:.375rem;padding-right:.375rem;border-radius:9999px;font-size:.75rem;line-height:1rem;font-weight:500;background-color:rgba(204,255,0,.2);color:var(--ash-accent)}.ash-env-vars-content{margin-top:.5rem}.ash-env-vars-content>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.ash-env-vars-item{display:flex;align-items:center;gap:.5rem;border-radius:.75rem;border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);padding:.5rem .75rem;font-size:.875rem;line-height:1.25rem}.ash-env-vars-key{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-weight:500;color:var(--ash-accent)}.ash-env-vars-equals{color:hsla(0,0%,100%,.4)}.ash-env-vars-value{flex:1 1 0%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;color:hsla(0,0%,100%,.7)}.ash-env-vars-remove{cursor:pointer;color:hsla(0,0%,100%,.4);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ash-env-vars-remove:hover{--tw-text-opacity:1;color:rgb(248 113 113/var(--tw-text-opacity,1))}.ash-env-vars-add{display:flex;align-items:center;gap:.5rem}.ash-env-vars-input{border-radius:.75rem;padding:.5rem .75rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem;border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-env-vars-input:focus{outline:2px solid transparent;outline-offset:2px;border-color:rgba(204,255,0,.5)}.ash-env-vars-input-key{min-width:0;flex:1 1 0%}.ash-env-vars-input-value{min-width:0;flex:2}.ash-env-vars-add-button{border-radius:.75rem;padding:.5rem .75rem;font-size:.875rem;line-height:1.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s;background-color:rgba(204,255,0,.2);color:var(--ash-accent)}.ash-env-vars-add-button:disabled{cursor:not-allowed;opacity:.3}.ash-env-vars-add-button:hover:not(:disabled){background-color:rgba(204,255,0,.3)}.ash-env-vars-helper{margin-top:.25rem;font-size:.75rem;line-height:1rem;color:hsla(0,0%,100%,.4)}.ash-display-mode-toggle{display:flex;align-items:center;gap:.375rem;border-radius:.5rem;padding:.375rem .5rem;border-width:1px;border-color:hsla(0,0%,100%,.1);background-color:hsla(0,0%,100%,.05);font-size:.875rem;line-height:1.25rem;color:hsla(0,0%,100%,.7)}.ash-display-mode-toggle:hover{border-color:hsla(0,0%,100%,.2);background-color:hsla(0,0%,100%,.1);--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.ash-display-mode-toggle{cursor:pointer;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.3s}.ash-display-mode-icon{height:1rem;width:1rem}.ash-display-mode-label{display:none}@media (min-width:640px){.ash-display-mode-label{display:inline}}.last\:border-b-0:last-child{border-bottom-width:0}.hover\:bg-white\/10:hover{background-color:hsla(0,0%,100%,.1)}.hover\:bg-white\/5:hover{background-color:hsla(0,0%,100%,.05)}.hover\:text-\[var\(--ash-accent-300\)\]:hover{color:var(--ash-accent-300)}.hover\:text-blue-300:hover{--tw-text-opacity:1;color:rgb(147 197 253/var(--tw-text-opacity,1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.group:hover .group-hover\:translate-x-0\.5{--tw-translate-x:0.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:text-\[var\(--ash-accent\)\]{color:var(--ash-accent)}.group:hover .group-hover\:text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.group:hover .group-hover\:text-white\/60{color:hsla(0,0%,100%,.6)}
package/dist/types.cjs CHANGED
@@ -40,6 +40,9 @@ function isToolCallEntry(entry) {
40
40
  function isErrorEntry(entry) {
41
41
  return entry.type === "error";
42
42
  }
43
+ function isWidgetEntry(entry) {
44
+ return entry.type === "widget";
45
+ }
43
46
  var DEFAULT_DISPLAY_CONFIG = {
44
47
  mode: "inline",
45
48
  breakEveryNToolCalls: 0,
@@ -61,5 +64,6 @@ exports.isTodoWriteAction = isTodoWriteAction;
61
64
  exports.isToolCallEntry = isToolCallEntry;
62
65
  exports.isWebFetchAction = isWebFetchAction;
63
66
  exports.isWebSearchAction = isWebSearchAction;
67
+ exports.isWidgetEntry = isWidgetEntry;
64
68
  //# sourceMappingURL=types.cjs.map
65
69
  //# sourceMappingURL=types.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";;;AA+SO,SAAS,mBAAmB,MAAA,EAAgD;AACjF,EAAA,OAAO,OAAO,MAAA,KAAW,aAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,eAAe,MAAA,EAA4C;AACzE,EAAA,OAAO,OAAO,MAAA,KAAW,QAAA;AAC3B;AAEO,SAAS,aAAa,MAAA,EAA0C;AACrE,EAAA,OAAO,OAAO,MAAA,KAAW,MAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,gBAAgB,MAAA,EAA6C;AAC3E,EAAA,OAAO,OAAO,MAAA,KAAW,UAAA;AAC3B;AAEO,SAAS,oBAAoB,MAAA,EAAiD;AACnF,EAAA,OAAO,OAAO,MAAA,KAAW,cAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,gBAAgB,KAAA,EAAoD;AAClF,EAAA,OAAO,MAAM,IAAA,KAAS,WAAA;AACxB;AAEO,SAAS,aAAa,KAAA,EAAiD;AAC5E,EAAA,OAAO,MAAM,IAAA,KAAS,OAAA;AACxB;AA0EO,IAAM,sBAAA,GAA4C;AAAA,EACvD,IAAA,EAAM,QAAA;AAAA,EACN,oBAAA,EAAsB,CAAA;AAAA,EACtB,eAAA,EAAiB,KAAA;AAAA,EACjB,iBAAA,EAAmB;AACrB","file":"types.cjs","sourcesContent":["/**\n * @ash-cloud/ash-ui - Types\n *\n * Normalized types for structured tool call display in agentic UIs.\n * These types provide a unified representation for displaying tool calls\n * with their arguments and results together.\n */\n\n// =============================================================================\n// Tool Status\n// =============================================================================\n\n/**\n * Status of a tool call execution\n */\nexport type ToolStatus = 'pending' | 'success' | 'failed';\n\n// =============================================================================\n// Action-Specific Result Types\n// =============================================================================\n\n/**\n * Result from a command/bash execution\n */\nexport interface CommandRunResult {\n exitCode?: number;\n success?: boolean;\n output?: string;\n}\n\n/**\n * Generic tool result that can be markdown or structured JSON\n */\nexport interface ToolResult {\n type: 'markdown' | 'json';\n value: unknown;\n}\n\n// =============================================================================\n// Action Types (Discriminated Union)\n// =============================================================================\n\n/**\n * Bash/command execution action\n */\nexport interface CommandRunAction {\n action: 'command_run';\n command: string;\n description?: string;\n result?: CommandRunResult;\n}\n\n/**\n * File read action\n */\nexport interface FileReadAction {\n action: 'file_read';\n path: string;\n offset?: number;\n limit?: number;\n}\n\n/**\n * File edit action\n */\nexport interface FileEditAction {\n action: 'file_edit';\n path: string;\n oldString?: string;\n newString?: string;\n replaceAll?: boolean;\n}\n\n/**\n * File write action\n */\nexport interface FileWriteAction {\n action: 'file_write';\n path: string;\n content?: string;\n}\n\n/**\n * Search/grep action\n */\nexport interface SearchAction {\n action: 'search';\n pattern: string;\n path?: string;\n glob?: string;\n type?: string;\n}\n\n/**\n * Glob/file pattern matching action\n */\nexport interface GlobAction {\n action: 'glob';\n pattern: string;\n path?: string;\n}\n\n/**\n * Web fetch action\n */\nexport interface WebFetchAction {\n action: 'web_fetch';\n url: string;\n prompt?: string;\n}\n\n/**\n * Web search action\n */\nexport interface WebSearchAction {\n action: 'web_search';\n query: string;\n}\n\n/**\n * MCP (Model Context Protocol) tool action\n */\nexport interface McpToolAction {\n action: 'mcp_tool';\n serverName: string;\n toolName: string;\n arguments?: unknown;\n result?: ToolResult;\n}\n\n/**\n * Generic/unknown tool action\n */\nexport interface GenericToolAction {\n action: 'generic_tool';\n toolName: string;\n arguments?: unknown;\n result?: ToolResult;\n}\n\n// =============================================================================\n// Todo Types\n// =============================================================================\n\n/**\n * Status of a todo item\n */\nexport type TodoStatus = 'pending' | 'in_progress' | 'completed';\n\n/**\n * A single todo item from TodoWrite tool\n */\nexport interface TodoItem {\n /** Task content - imperative form (e.g., \"Run tests\") */\n content: string;\n /** Current status of the todo */\n status: TodoStatus;\n /** Active form shown during execution (e.g., \"Running tests\") */\n activeForm: string;\n}\n\n/**\n * TodoWrite tool action - tracks task progress\n */\nexport interface TodoWriteAction {\n action: 'todo_write';\n /** All todos in the current list */\n todos: TodoItem[];\n /** Summary statistics */\n stats?: {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n };\n}\n\n/**\n * Discriminated union of all action types\n */\nexport type ActionType =\n | CommandRunAction\n | FileReadAction\n | FileEditAction\n | FileWriteAction\n | SearchAction\n | GlobAction\n | WebFetchAction\n | WebSearchAction\n | McpToolAction\n | GenericToolAction\n | TodoWriteAction;\n\n// =============================================================================\n// Normalized Tool Call\n// =============================================================================\n\n/**\n * A normalized tool call that combines tool_use and tool_result data\n */\nexport interface NormalizedToolCall {\n /** Unique ID from the tool_use block */\n id: string;\n\n /** Original tool name (e.g., 'Bash', 'Read', 'mcp__server__tool') */\n toolName: string;\n\n /** Parsed action type with structured arguments and result */\n actionType: ActionType;\n\n /** Current execution status */\n status: ToolStatus;\n\n /** Human-readable one-liner summary */\n summary: string;\n\n /** When the tool call started */\n startedAt?: string;\n\n /** When the tool call completed */\n completedAt?: string;\n\n /** Whether this tool call resulted in an error */\n isError?: boolean;\n}\n\n// =============================================================================\n// Normalized Entry Types\n// =============================================================================\n\n/**\n * User message entry\n */\nexport interface UserMessageEntry {\n type: 'user_message';\n}\n\n/**\n * Assistant message entry\n */\nexport interface AssistantMessageEntry {\n type: 'assistant_message';\n}\n\n/**\n * Thinking/reasoning entry (extended thinking)\n */\nexport interface ThinkingEntry {\n type: 'thinking';\n}\n\n/**\n * Tool call entry with full tool call data\n */\nexport interface ToolCallEntry {\n type: 'tool_call';\n toolCall: NormalizedToolCall;\n}\n\n/**\n * Error entry\n */\nexport interface ErrorEntry {\n type: 'error';\n message: string;\n code?: string;\n}\n\n/**\n * Discriminated union of all entry types\n */\nexport type NormalizedEntryType =\n | UserMessageEntry\n | AssistantMessageEntry\n | ThinkingEntry\n | ToolCallEntry\n | ErrorEntry;\n\n// =============================================================================\n// Normalized Entry\n// =============================================================================\n\n/**\n * A normalized conversation entry for display\n */\nexport interface NormalizedEntry {\n /** Unique entry ID */\n id: string;\n\n /** ISO timestamp */\n timestamp?: string;\n\n /** Entry type with type-specific data */\n entryType: NormalizedEntryType;\n\n /** Text content for display */\n content: string;\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\nexport function isCommandRunAction(action: ActionType): action is CommandRunAction {\n return action.action === 'command_run';\n}\n\nexport function isFileReadAction(action: ActionType): action is FileReadAction {\n return action.action === 'file_read';\n}\n\nexport function isFileEditAction(action: ActionType): action is FileEditAction {\n return action.action === 'file_edit';\n}\n\nexport function isFileWriteAction(action: ActionType): action is FileWriteAction {\n return action.action === 'file_write';\n}\n\nexport function isSearchAction(action: ActionType): action is SearchAction {\n return action.action === 'search';\n}\n\nexport function isGlobAction(action: ActionType): action is GlobAction {\n return action.action === 'glob';\n}\n\nexport function isWebFetchAction(action: ActionType): action is WebFetchAction {\n return action.action === 'web_fetch';\n}\n\nexport function isWebSearchAction(action: ActionType): action is WebSearchAction {\n return action.action === 'web_search';\n}\n\nexport function isMcpToolAction(action: ActionType): action is McpToolAction {\n return action.action === 'mcp_tool';\n}\n\nexport function isGenericToolAction(action: ActionType): action is GenericToolAction {\n return action.action === 'generic_tool';\n}\n\nexport function isTodoWriteAction(action: ActionType): action is TodoWriteAction {\n return action.action === 'todo_write';\n}\n\nexport function isToolCallEntry(entry: NormalizedEntryType): entry is ToolCallEntry {\n return entry.type === 'tool_call';\n}\n\nexport function isErrorEntry(entry: NormalizedEntryType): entry is ErrorEntry {\n return entry.type === 'error';\n}\n\n// =============================================================================\n// Log Types (for SandboxLogsPanel)\n// =============================================================================\n\nexport type LogLevel = 'info' | 'warn' | 'error' | 'debug';\nexport type LogCategory = 'setup' | 'skills' | 'execution' | 'process' | 'startup';\n\nexport interface LogEntry {\n timestamp: string;\n level: LogLevel;\n category: LogCategory;\n message: string;\n data?: Record<string, unknown>;\n}\n\n// =============================================================================\n// File Attachment\n// =============================================================================\n\nexport interface FileAttachment {\n name: string;\n type: string;\n size: number;\n base64: string;\n}\n\n// =============================================================================\n// Display Mode Configuration\n// =============================================================================\n\n/**\n * Display mode for tool calls in the chat interface\n *\n * - 'inline': Each tool call rendered inline as expandable cards (current behavior)\n * - 'compact': Single animated status line that updates with each tool call,\n * with accordion to expand and see execution details. Text streams unbroken.\n */\nexport type ToolDisplayMode = 'inline' | 'compact';\n\n/**\n * Configuration for tool display behavior\n */\nexport interface ToolDisplayConfig {\n /**\n * Display mode for tool calls\n * @default 'inline'\n */\n mode: ToolDisplayMode;\n\n /**\n * For 'compact' mode: break into a new group every N tool calls\n * Set to 0 or undefined to never break (all tool calls in single group)\n * @default 0\n */\n breakEveryNToolCalls?: number;\n\n /**\n * Whether tool call groups start expanded\n * @default false\n */\n defaultExpanded?: boolean;\n\n /**\n * Animation duration for status line transitions (ms)\n * @default 300\n */\n animationDuration?: number;\n}\n\n/**\n * Default display configuration\n */\nexport const DEFAULT_DISPLAY_CONFIG: ToolDisplayConfig = {\n mode: 'inline',\n breakEveryNToolCalls: 0,\n defaultExpanded: false,\n animationDuration: 300,\n};\n\n// =============================================================================\n// Tool Execution Group (for compact mode)\n// =============================================================================\n\n/**\n * A group of consecutive tool calls that are displayed together\n * in compact mode. Text content before/after flows around the group.\n */\nexport interface ToolExecutionGroup {\n /** Unique ID for the group */\n id: string;\n\n /** Tool calls in this group (in order) */\n toolCalls: NormalizedToolCall[];\n\n /** Index of the currently active/latest tool call for status display */\n activeIndex: number;\n\n /** Whether all tool calls in this group have completed */\n isComplete: boolean;\n\n /** Overall status of the group */\n status: 'pending' | 'success' | 'partial_failure' | 'failed';\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";;;AAiVO,SAAS,mBAAmB,MAAA,EAAgD;AACjF,EAAA,OAAO,OAAO,MAAA,KAAW,aAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,eAAe,MAAA,EAA4C;AACzE,EAAA,OAAO,OAAO,MAAA,KAAW,QAAA;AAC3B;AAEO,SAAS,aAAa,MAAA,EAA0C;AACrE,EAAA,OAAO,OAAO,MAAA,KAAW,MAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,gBAAgB,MAAA,EAA6C;AAC3E,EAAA,OAAO,OAAO,MAAA,KAAW,UAAA;AAC3B;AAEO,SAAS,oBAAoB,MAAA,EAAiD;AACnF,EAAA,OAAO,OAAO,MAAA,KAAW,cAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,gBAAgB,KAAA,EAAoD;AAClF,EAAA,OAAO,MAAM,IAAA,KAAS,WAAA;AACxB;AAEO,SAAS,aAAa,KAAA,EAAiD;AAC5E,EAAA,OAAO,MAAM,IAAA,KAAS,OAAA;AACxB;AAEO,SAAS,cAAc,KAAA,EAAkD;AAC9E,EAAA,OAAO,MAAM,IAAA,KAAS,QAAA;AACxB;AAsIO,IAAM,sBAAA,GAA4C;AAAA,EACvD,IAAA,EAAM,QAAA;AAAA,EACN,oBAAA,EAAsB,CAAA;AAAA,EACtB,eAAA,EAAiB,KAAA;AAAA,EACjB,iBAAA,EAAmB;AACrB","file":"types.cjs","sourcesContent":["/**\n * @ash-cloud/ash-ui - Types\n *\n * Normalized types for structured tool call display in agentic UIs.\n * These types provide a unified representation for displaying tool calls\n * with their arguments and results together.\n */\n\nimport type { ReactNode } from 'react';\n\n// =============================================================================\n// Tool Status\n// =============================================================================\n\n/**\n * Status of a tool call execution\n */\nexport type ToolStatus = 'pending' | 'success' | 'failed';\n\n// =============================================================================\n// Action-Specific Result Types\n// =============================================================================\n\n/**\n * Result from a command/bash execution\n */\nexport interface CommandRunResult {\n exitCode?: number;\n success?: boolean;\n output?: string;\n}\n\n/**\n * Generic tool result that can be markdown or structured JSON\n */\nexport interface ToolResult {\n type: 'markdown' | 'json';\n value: unknown;\n}\n\n// =============================================================================\n// Action Types (Discriminated Union)\n// =============================================================================\n\n/**\n * Bash/command execution action\n */\nexport interface CommandRunAction {\n action: 'command_run';\n command: string;\n description?: string;\n result?: CommandRunResult;\n}\n\n/**\n * File read action\n */\nexport interface FileReadAction {\n action: 'file_read';\n path: string;\n offset?: number;\n limit?: number;\n}\n\n/**\n * File edit action\n */\nexport interface FileEditAction {\n action: 'file_edit';\n path: string;\n oldString?: string;\n newString?: string;\n replaceAll?: boolean;\n}\n\n/**\n * File write action\n */\nexport interface FileWriteAction {\n action: 'file_write';\n path: string;\n content?: string;\n}\n\n/**\n * Search/grep action\n */\nexport interface SearchAction {\n action: 'search';\n pattern: string;\n path?: string;\n glob?: string;\n type?: string;\n}\n\n/**\n * Glob/file pattern matching action\n */\nexport interface GlobAction {\n action: 'glob';\n pattern: string;\n path?: string;\n}\n\n/**\n * Web fetch action\n */\nexport interface WebFetchAction {\n action: 'web_fetch';\n url: string;\n prompt?: string;\n}\n\n/**\n * Web search action\n */\nexport interface WebSearchAction {\n action: 'web_search';\n query: string;\n}\n\n/**\n * MCP (Model Context Protocol) tool action\n */\nexport interface McpToolAction {\n action: 'mcp_tool';\n serverName: string;\n toolName: string;\n arguments?: unknown;\n result?: ToolResult;\n}\n\n/**\n * Generic/unknown tool action\n */\nexport interface GenericToolAction {\n action: 'generic_tool';\n toolName: string;\n arguments?: unknown;\n result?: ToolResult;\n}\n\n// =============================================================================\n// Todo Types\n// =============================================================================\n\n/**\n * Status of a todo item\n */\nexport type TodoStatus = 'pending' | 'in_progress' | 'completed';\n\n/**\n * A single todo item from TodoWrite tool\n */\nexport interface TodoItem {\n /** Task content - imperative form (e.g., \"Run tests\") */\n content: string;\n /** Current status of the todo */\n status: TodoStatus;\n /** Active form shown during execution (e.g., \"Running tests\") */\n activeForm: string;\n}\n\n/**\n * TodoWrite tool action - tracks task progress\n */\nexport interface TodoWriteAction {\n action: 'todo_write';\n /** All todos in the current list */\n todos: TodoItem[];\n /** Summary statistics */\n stats?: {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n };\n}\n\n/**\n * Discriminated union of all action types\n */\nexport type ActionType =\n | CommandRunAction\n | FileReadAction\n | FileEditAction\n | FileWriteAction\n | SearchAction\n | GlobAction\n | WebFetchAction\n | WebSearchAction\n | McpToolAction\n | GenericToolAction\n | TodoWriteAction;\n\n// =============================================================================\n// Normalized Tool Call\n// =============================================================================\n\n/**\n * A normalized tool call that combines tool_use and tool_result data\n */\nexport interface NormalizedToolCall {\n /** Unique ID from the tool_use block */\n id: string;\n\n /** Original tool name (e.g., 'Bash', 'Read', 'mcp__server__tool') */\n toolName: string;\n\n /** Parsed action type with structured arguments and result */\n actionType: ActionType;\n\n /** Current execution status */\n status: ToolStatus;\n\n /** Human-readable one-liner summary */\n summary: string;\n\n /** When the tool call started */\n startedAt?: string;\n\n /** When the tool call completed */\n completedAt?: string;\n\n /** Whether this tool call resulted in an error */\n isError?: boolean;\n}\n\n// =============================================================================\n// Normalized Entry Types\n// =============================================================================\n\n/**\n * User message entry\n */\nexport interface UserMessageEntry {\n type: 'user_message';\n}\n\n/**\n * Assistant message entry\n */\nexport interface AssistantMessageEntry {\n type: 'assistant_message';\n}\n\n/**\n * Thinking/reasoning entry (extended thinking)\n */\nexport interface ThinkingEntry {\n type: 'thinking';\n}\n\n/**\n * Tool call entry with full tool call data\n */\nexport interface ToolCallEntry {\n type: 'tool_call';\n toolCall: NormalizedToolCall;\n}\n\n/**\n * Error entry\n */\nexport interface ErrorEntry {\n type: 'error';\n message: string;\n code?: string;\n}\n\n/**\n * Custom widget entry - rendered via consumer-provided render function\n *\n * Use this for interactive UI components like:\n * - Image grid selectors\n * - Product carousels\n * - Form inputs\n * - Data visualizations\n * - Any custom interactive widget\n *\n * @example\n * ```tsx\n * const entry: NormalizedEntry = {\n * id: 'widget-1',\n * entryType: {\n * type: 'widget',\n * widgetType: 'image-grid',\n * widgetData: { images: [...], selected: null },\n * },\n * content: 'Select an image',\n * };\n * ```\n */\nexport interface WidgetEntry {\n type: 'widget';\n /** Widget type identifier (e.g., 'image-grid', 'product-selector') */\n widgetType: string;\n /** Widget-specific data passed to the render function */\n widgetData: unknown;\n}\n\n/**\n * Discriminated union of all entry types\n */\nexport type NormalizedEntryType =\n | UserMessageEntry\n | AssistantMessageEntry\n | ThinkingEntry\n | ToolCallEntry\n | ErrorEntry\n | WidgetEntry;\n\n// =============================================================================\n// Normalized Entry\n// =============================================================================\n\n/**\n * A normalized conversation entry for display\n */\nexport interface NormalizedEntry {\n /** Unique entry ID */\n id: string;\n\n /** ISO timestamp */\n timestamp?: string;\n\n /** Entry type with type-specific data */\n entryType: NormalizedEntryType;\n\n /** Text content for display */\n content: string;\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\nexport function isCommandRunAction(action: ActionType): action is CommandRunAction {\n return action.action === 'command_run';\n}\n\nexport function isFileReadAction(action: ActionType): action is FileReadAction {\n return action.action === 'file_read';\n}\n\nexport function isFileEditAction(action: ActionType): action is FileEditAction {\n return action.action === 'file_edit';\n}\n\nexport function isFileWriteAction(action: ActionType): action is FileWriteAction {\n return action.action === 'file_write';\n}\n\nexport function isSearchAction(action: ActionType): action is SearchAction {\n return action.action === 'search';\n}\n\nexport function isGlobAction(action: ActionType): action is GlobAction {\n return action.action === 'glob';\n}\n\nexport function isWebFetchAction(action: ActionType): action is WebFetchAction {\n return action.action === 'web_fetch';\n}\n\nexport function isWebSearchAction(action: ActionType): action is WebSearchAction {\n return action.action === 'web_search';\n}\n\nexport function isMcpToolAction(action: ActionType): action is McpToolAction {\n return action.action === 'mcp_tool';\n}\n\nexport function isGenericToolAction(action: ActionType): action is GenericToolAction {\n return action.action === 'generic_tool';\n}\n\nexport function isTodoWriteAction(action: ActionType): action is TodoWriteAction {\n return action.action === 'todo_write';\n}\n\nexport function isToolCallEntry(entry: NormalizedEntryType): entry is ToolCallEntry {\n return entry.type === 'tool_call';\n}\n\nexport function isErrorEntry(entry: NormalizedEntryType): entry is ErrorEntry {\n return entry.type === 'error';\n}\n\nexport function isWidgetEntry(entry: NormalizedEntryType): entry is WidgetEntry {\n return entry.type === 'widget';\n}\n\n// =============================================================================\n// Widget Rendering\n// =============================================================================\n\n/**\n * Props passed to the widget render function\n */\nexport interface WidgetRenderProps<T = unknown> {\n /** The widget entry being rendered */\n entry: NormalizedEntry;\n /** Widget type identifier */\n widgetType: string;\n /** Widget-specific data */\n widgetData: T;\n /** Callback for widget interactions (e.g., selection, submit) */\n onAction?: (action: WidgetAction) => void;\n}\n\n/**\n * Action dispatched from a widget interaction\n */\nexport interface WidgetAction {\n /** Action type (e.g., 'select', 'submit', 'cancel') */\n type: string;\n /** Widget type that dispatched the action */\n widgetType: string;\n /** Entry ID of the widget */\n entryId: string;\n /** Action-specific payload */\n payload?: unknown;\n}\n\n/**\n * Function type for rendering custom widgets\n *\n * @example\n * ```tsx\n * const renderWidget: WidgetRenderFunction = ({ widgetType, widgetData, onAction }) => {\n * switch (widgetType) {\n * case 'image-grid':\n * return (\n * <ImageGrid\n * images={widgetData.images}\n * onSelect={(id) => onAction?.({ type: 'select', widgetType, entryId, payload: { id } })}\n * />\n * );\n * case 'product-selector':\n * return <ProductSelector data={widgetData} onAction={onAction} />;\n * default:\n * return null;\n * }\n * };\n *\n * <MessageList entries={entries} renderWidget={renderWidget} />\n * ```\n */\nexport type WidgetRenderFunction = (props: WidgetRenderProps) => ReactNode;\n\n// =============================================================================\n// Log Types (for SandboxLogsPanel)\n// =============================================================================\n\nexport type LogLevel = 'info' | 'warn' | 'error' | 'debug';\nexport type LogCategory = 'setup' | 'skills' | 'execution' | 'process' | 'startup';\n\nexport interface LogEntry {\n timestamp: string;\n level: LogLevel;\n category: LogCategory;\n message: string;\n data?: Record<string, unknown>;\n}\n\n// =============================================================================\n// File Attachment\n// =============================================================================\n\nexport interface FileAttachment {\n name: string;\n type: string;\n size: number;\n base64: string;\n}\n\n// =============================================================================\n// Display Mode Configuration\n// =============================================================================\n\n/**\n * Display mode for tool calls in the chat interface\n *\n * - 'inline': Each tool call rendered inline as expandable cards (current behavior)\n * - 'compact': Single animated status line that updates with each tool call,\n * with accordion to expand and see execution details. Text streams unbroken.\n * - 'accordion': Simpler step-based accordion list that accumulates tool calls\n * with icons, labels, and durations (like Vidra's ThinkingIndicator).\n */\nexport type ToolDisplayMode = 'inline' | 'compact' | 'accordion';\n\n/**\n * Configuration for tool display behavior\n */\nexport interface ToolDisplayConfig {\n /**\n * Display mode for tool calls\n * @default 'inline'\n */\n mode: ToolDisplayMode;\n\n /**\n * For 'compact' mode: break into a new group every N tool calls\n * Set to 0 or undefined to never break (all tool calls in single group)\n * @default 0\n */\n breakEveryNToolCalls?: number;\n\n /**\n * Whether tool call groups start expanded\n * @default false\n */\n defaultExpanded?: boolean;\n\n /**\n * Animation duration for status line transitions (ms)\n * @default 300\n */\n animationDuration?: number;\n}\n\n/**\n * Default display configuration\n */\nexport const DEFAULT_DISPLAY_CONFIG: ToolDisplayConfig = {\n mode: 'inline',\n breakEveryNToolCalls: 0,\n defaultExpanded: false,\n animationDuration: 300,\n};\n\n// =============================================================================\n// Tool Execution Group (for compact mode)\n// =============================================================================\n\n/**\n * A group of consecutive tool calls that are displayed together\n * in compact mode. Text content before/after flows around the group.\n */\nexport interface ToolExecutionGroup {\n /** Unique ID for the group */\n id: string;\n\n /** Tool calls in this group (in order) */\n toolCalls: NormalizedToolCall[];\n\n /** Index of the currently active/latest tool call for status display */\n activeIndex: number;\n\n /** Whether all tool calls in this group have completed */\n isComplete: boolean;\n\n /** Overall status of the group */\n status: 'pending' | 'success' | 'partial_failure' | 'failed';\n}\n"]}
package/dist/types.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ import { ReactNode } from 'react';
2
+
1
3
  /**
2
4
  * @ash-cloud/ash-ui - Types
3
5
  *
@@ -5,6 +7,7 @@
5
7
  * These types provide a unified representation for displaying tool calls
6
8
  * with their arguments and results together.
7
9
  */
10
+
8
11
  /**
9
12
  * Status of a tool call execution
10
13
  */
@@ -200,10 +203,40 @@ interface ErrorEntry {
200
203
  message: string;
201
204
  code?: string;
202
205
  }
206
+ /**
207
+ * Custom widget entry - rendered via consumer-provided render function
208
+ *
209
+ * Use this for interactive UI components like:
210
+ * - Image grid selectors
211
+ * - Product carousels
212
+ * - Form inputs
213
+ * - Data visualizations
214
+ * - Any custom interactive widget
215
+ *
216
+ * @example
217
+ * ```tsx
218
+ * const entry: NormalizedEntry = {
219
+ * id: 'widget-1',
220
+ * entryType: {
221
+ * type: 'widget',
222
+ * widgetType: 'image-grid',
223
+ * widgetData: { images: [...], selected: null },
224
+ * },
225
+ * content: 'Select an image',
226
+ * };
227
+ * ```
228
+ */
229
+ interface WidgetEntry {
230
+ type: 'widget';
231
+ /** Widget type identifier (e.g., 'image-grid', 'product-selector') */
232
+ widgetType: string;
233
+ /** Widget-specific data passed to the render function */
234
+ widgetData: unknown;
235
+ }
203
236
  /**
204
237
  * Discriminated union of all entry types
205
238
  */
206
- type NormalizedEntryType = UserMessageEntry | AssistantMessageEntry | ThinkingEntry | ToolCallEntry | ErrorEntry;
239
+ type NormalizedEntryType = UserMessageEntry | AssistantMessageEntry | ThinkingEntry | ToolCallEntry | ErrorEntry | WidgetEntry;
207
240
  /**
208
241
  * A normalized conversation entry for display
209
242
  */
@@ -230,6 +263,58 @@ declare function isGenericToolAction(action: ActionType): action is GenericToolA
230
263
  declare function isTodoWriteAction(action: ActionType): action is TodoWriteAction;
231
264
  declare function isToolCallEntry(entry: NormalizedEntryType): entry is ToolCallEntry;
232
265
  declare function isErrorEntry(entry: NormalizedEntryType): entry is ErrorEntry;
266
+ declare function isWidgetEntry(entry: NormalizedEntryType): entry is WidgetEntry;
267
+ /**
268
+ * Props passed to the widget render function
269
+ */
270
+ interface WidgetRenderProps<T = unknown> {
271
+ /** The widget entry being rendered */
272
+ entry: NormalizedEntry;
273
+ /** Widget type identifier */
274
+ widgetType: string;
275
+ /** Widget-specific data */
276
+ widgetData: T;
277
+ /** Callback for widget interactions (e.g., selection, submit) */
278
+ onAction?: (action: WidgetAction) => void;
279
+ }
280
+ /**
281
+ * Action dispatched from a widget interaction
282
+ */
283
+ interface WidgetAction {
284
+ /** Action type (e.g., 'select', 'submit', 'cancel') */
285
+ type: string;
286
+ /** Widget type that dispatched the action */
287
+ widgetType: string;
288
+ /** Entry ID of the widget */
289
+ entryId: string;
290
+ /** Action-specific payload */
291
+ payload?: unknown;
292
+ }
293
+ /**
294
+ * Function type for rendering custom widgets
295
+ *
296
+ * @example
297
+ * ```tsx
298
+ * const renderWidget: WidgetRenderFunction = ({ widgetType, widgetData, onAction }) => {
299
+ * switch (widgetType) {
300
+ * case 'image-grid':
301
+ * return (
302
+ * <ImageGrid
303
+ * images={widgetData.images}
304
+ * onSelect={(id) => onAction?.({ type: 'select', widgetType, entryId, payload: { id } })}
305
+ * />
306
+ * );
307
+ * case 'product-selector':
308
+ * return <ProductSelector data={widgetData} onAction={onAction} />;
309
+ * default:
310
+ * return null;
311
+ * }
312
+ * };
313
+ *
314
+ * <MessageList entries={entries} renderWidget={renderWidget} />
315
+ * ```
316
+ */
317
+ type WidgetRenderFunction = (props: WidgetRenderProps) => ReactNode;
233
318
  type LogLevel = 'info' | 'warn' | 'error' | 'debug';
234
319
  type LogCategory = 'setup' | 'skills' | 'execution' | 'process' | 'startup';
235
320
  interface LogEntry {
@@ -251,8 +336,10 @@ interface FileAttachment {
251
336
  * - 'inline': Each tool call rendered inline as expandable cards (current behavior)
252
337
  * - 'compact': Single animated status line that updates with each tool call,
253
338
  * with accordion to expand and see execution details. Text streams unbroken.
339
+ * - 'accordion': Simpler step-based accordion list that accumulates tool calls
340
+ * with icons, labels, and durations (like Vidra's ThinkingIndicator).
254
341
  */
255
- type ToolDisplayMode = 'inline' | 'compact';
342
+ type ToolDisplayMode = 'inline' | 'compact' | 'accordion';
256
343
  /**
257
344
  * Configuration for tool display behavior
258
345
  */
@@ -300,4 +387,4 @@ interface ToolExecutionGroup {
300
387
  status: 'pending' | 'success' | 'partial_failure' | 'failed';
301
388
  }
302
389
 
303
- export { type ActionType, type AssistantMessageEntry, type CommandRunAction, type CommandRunResult, DEFAULT_DISPLAY_CONFIG, type ErrorEntry, type FileAttachment, type FileEditAction, type FileReadAction, type FileWriteAction, type GenericToolAction, type GlobAction, type LogCategory, type LogEntry, type LogLevel, type McpToolAction, type NormalizedEntry, type NormalizedEntryType, type NormalizedToolCall, type SearchAction, type ThinkingEntry, type TodoItem, type TodoStatus, type TodoWriteAction, type ToolCallEntry, type ToolDisplayConfig, type ToolDisplayMode, type ToolExecutionGroup, type ToolResult, type ToolStatus, type UserMessageEntry, type WebFetchAction, type WebSearchAction, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction };
390
+ export { type ActionType, type AssistantMessageEntry, type CommandRunAction, type CommandRunResult, DEFAULT_DISPLAY_CONFIG, type ErrorEntry, type FileAttachment, type FileEditAction, type FileReadAction, type FileWriteAction, type GenericToolAction, type GlobAction, type LogCategory, type LogEntry, type LogLevel, type McpToolAction, type NormalizedEntry, type NormalizedEntryType, type NormalizedToolCall, type SearchAction, type ThinkingEntry, type TodoItem, type TodoStatus, type TodoWriteAction, type ToolCallEntry, type ToolDisplayConfig, type ToolDisplayMode, type ToolExecutionGroup, type ToolResult, type ToolStatus, type UserMessageEntry, type WebFetchAction, type WebSearchAction, type WidgetAction, type WidgetEntry, type WidgetRenderFunction, type WidgetRenderProps, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction, isWidgetEntry };
package/dist/types.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { ReactNode } from 'react';
2
+
1
3
  /**
2
4
  * @ash-cloud/ash-ui - Types
3
5
  *
@@ -5,6 +7,7 @@
5
7
  * These types provide a unified representation for displaying tool calls
6
8
  * with their arguments and results together.
7
9
  */
10
+
8
11
  /**
9
12
  * Status of a tool call execution
10
13
  */
@@ -200,10 +203,40 @@ interface ErrorEntry {
200
203
  message: string;
201
204
  code?: string;
202
205
  }
206
+ /**
207
+ * Custom widget entry - rendered via consumer-provided render function
208
+ *
209
+ * Use this for interactive UI components like:
210
+ * - Image grid selectors
211
+ * - Product carousels
212
+ * - Form inputs
213
+ * - Data visualizations
214
+ * - Any custom interactive widget
215
+ *
216
+ * @example
217
+ * ```tsx
218
+ * const entry: NormalizedEntry = {
219
+ * id: 'widget-1',
220
+ * entryType: {
221
+ * type: 'widget',
222
+ * widgetType: 'image-grid',
223
+ * widgetData: { images: [...], selected: null },
224
+ * },
225
+ * content: 'Select an image',
226
+ * };
227
+ * ```
228
+ */
229
+ interface WidgetEntry {
230
+ type: 'widget';
231
+ /** Widget type identifier (e.g., 'image-grid', 'product-selector') */
232
+ widgetType: string;
233
+ /** Widget-specific data passed to the render function */
234
+ widgetData: unknown;
235
+ }
203
236
  /**
204
237
  * Discriminated union of all entry types
205
238
  */
206
- type NormalizedEntryType = UserMessageEntry | AssistantMessageEntry | ThinkingEntry | ToolCallEntry | ErrorEntry;
239
+ type NormalizedEntryType = UserMessageEntry | AssistantMessageEntry | ThinkingEntry | ToolCallEntry | ErrorEntry | WidgetEntry;
207
240
  /**
208
241
  * A normalized conversation entry for display
209
242
  */
@@ -230,6 +263,58 @@ declare function isGenericToolAction(action: ActionType): action is GenericToolA
230
263
  declare function isTodoWriteAction(action: ActionType): action is TodoWriteAction;
231
264
  declare function isToolCallEntry(entry: NormalizedEntryType): entry is ToolCallEntry;
232
265
  declare function isErrorEntry(entry: NormalizedEntryType): entry is ErrorEntry;
266
+ declare function isWidgetEntry(entry: NormalizedEntryType): entry is WidgetEntry;
267
+ /**
268
+ * Props passed to the widget render function
269
+ */
270
+ interface WidgetRenderProps<T = unknown> {
271
+ /** The widget entry being rendered */
272
+ entry: NormalizedEntry;
273
+ /** Widget type identifier */
274
+ widgetType: string;
275
+ /** Widget-specific data */
276
+ widgetData: T;
277
+ /** Callback for widget interactions (e.g., selection, submit) */
278
+ onAction?: (action: WidgetAction) => void;
279
+ }
280
+ /**
281
+ * Action dispatched from a widget interaction
282
+ */
283
+ interface WidgetAction {
284
+ /** Action type (e.g., 'select', 'submit', 'cancel') */
285
+ type: string;
286
+ /** Widget type that dispatched the action */
287
+ widgetType: string;
288
+ /** Entry ID of the widget */
289
+ entryId: string;
290
+ /** Action-specific payload */
291
+ payload?: unknown;
292
+ }
293
+ /**
294
+ * Function type for rendering custom widgets
295
+ *
296
+ * @example
297
+ * ```tsx
298
+ * const renderWidget: WidgetRenderFunction = ({ widgetType, widgetData, onAction }) => {
299
+ * switch (widgetType) {
300
+ * case 'image-grid':
301
+ * return (
302
+ * <ImageGrid
303
+ * images={widgetData.images}
304
+ * onSelect={(id) => onAction?.({ type: 'select', widgetType, entryId, payload: { id } })}
305
+ * />
306
+ * );
307
+ * case 'product-selector':
308
+ * return <ProductSelector data={widgetData} onAction={onAction} />;
309
+ * default:
310
+ * return null;
311
+ * }
312
+ * };
313
+ *
314
+ * <MessageList entries={entries} renderWidget={renderWidget} />
315
+ * ```
316
+ */
317
+ type WidgetRenderFunction = (props: WidgetRenderProps) => ReactNode;
233
318
  type LogLevel = 'info' | 'warn' | 'error' | 'debug';
234
319
  type LogCategory = 'setup' | 'skills' | 'execution' | 'process' | 'startup';
235
320
  interface LogEntry {
@@ -251,8 +336,10 @@ interface FileAttachment {
251
336
  * - 'inline': Each tool call rendered inline as expandable cards (current behavior)
252
337
  * - 'compact': Single animated status line that updates with each tool call,
253
338
  * with accordion to expand and see execution details. Text streams unbroken.
339
+ * - 'accordion': Simpler step-based accordion list that accumulates tool calls
340
+ * with icons, labels, and durations (like Vidra's ThinkingIndicator).
254
341
  */
255
- type ToolDisplayMode = 'inline' | 'compact';
342
+ type ToolDisplayMode = 'inline' | 'compact' | 'accordion';
256
343
  /**
257
344
  * Configuration for tool display behavior
258
345
  */
@@ -300,4 +387,4 @@ interface ToolExecutionGroup {
300
387
  status: 'pending' | 'success' | 'partial_failure' | 'failed';
301
388
  }
302
389
 
303
- export { type ActionType, type AssistantMessageEntry, type CommandRunAction, type CommandRunResult, DEFAULT_DISPLAY_CONFIG, type ErrorEntry, type FileAttachment, type FileEditAction, type FileReadAction, type FileWriteAction, type GenericToolAction, type GlobAction, type LogCategory, type LogEntry, type LogLevel, type McpToolAction, type NormalizedEntry, type NormalizedEntryType, type NormalizedToolCall, type SearchAction, type ThinkingEntry, type TodoItem, type TodoStatus, type TodoWriteAction, type ToolCallEntry, type ToolDisplayConfig, type ToolDisplayMode, type ToolExecutionGroup, type ToolResult, type ToolStatus, type UserMessageEntry, type WebFetchAction, type WebSearchAction, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction };
390
+ export { type ActionType, type AssistantMessageEntry, type CommandRunAction, type CommandRunResult, DEFAULT_DISPLAY_CONFIG, type ErrorEntry, type FileAttachment, type FileEditAction, type FileReadAction, type FileWriteAction, type GenericToolAction, type GlobAction, type LogCategory, type LogEntry, type LogLevel, type McpToolAction, type NormalizedEntry, type NormalizedEntryType, type NormalizedToolCall, type SearchAction, type ThinkingEntry, type TodoItem, type TodoStatus, type TodoWriteAction, type ToolCallEntry, type ToolDisplayConfig, type ToolDisplayMode, type ToolExecutionGroup, type ToolResult, type ToolStatus, type UserMessageEntry, type WebFetchAction, type WebSearchAction, type WidgetAction, type WidgetEntry, type WidgetRenderFunction, type WidgetRenderProps, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction, isWidgetEntry };
package/dist/types.js CHANGED
@@ -38,6 +38,9 @@ function isToolCallEntry(entry) {
38
38
  function isErrorEntry(entry) {
39
39
  return entry.type === "error";
40
40
  }
41
+ function isWidgetEntry(entry) {
42
+ return entry.type === "widget";
43
+ }
41
44
  var DEFAULT_DISPLAY_CONFIG = {
42
45
  mode: "inline",
43
46
  breakEveryNToolCalls: 0,
@@ -45,6 +48,6 @@ var DEFAULT_DISPLAY_CONFIG = {
45
48
  animationDuration: 300
46
49
  };
47
50
 
48
- export { DEFAULT_DISPLAY_CONFIG, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction };
51
+ export { DEFAULT_DISPLAY_CONFIG, isCommandRunAction, isErrorEntry, isFileEditAction, isFileReadAction, isFileWriteAction, isGenericToolAction, isGlobAction, isMcpToolAction, isSearchAction, isTodoWriteAction, isToolCallEntry, isWebFetchAction, isWebSearchAction, isWidgetEntry };
49
52
  //# sourceMappingURL=types.js.map
50
53
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";AA+SO,SAAS,mBAAmB,MAAA,EAAgD;AACjF,EAAA,OAAO,OAAO,MAAA,KAAW,aAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,eAAe,MAAA,EAA4C;AACzE,EAAA,OAAO,OAAO,MAAA,KAAW,QAAA;AAC3B;AAEO,SAAS,aAAa,MAAA,EAA0C;AACrE,EAAA,OAAO,OAAO,MAAA,KAAW,MAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,gBAAgB,MAAA,EAA6C;AAC3E,EAAA,OAAO,OAAO,MAAA,KAAW,UAAA;AAC3B;AAEO,SAAS,oBAAoB,MAAA,EAAiD;AACnF,EAAA,OAAO,OAAO,MAAA,KAAW,cAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,gBAAgB,KAAA,EAAoD;AAClF,EAAA,OAAO,MAAM,IAAA,KAAS,WAAA;AACxB;AAEO,SAAS,aAAa,KAAA,EAAiD;AAC5E,EAAA,OAAO,MAAM,IAAA,KAAS,OAAA;AACxB;AA0EO,IAAM,sBAAA,GAA4C;AAAA,EACvD,IAAA,EAAM,QAAA;AAAA,EACN,oBAAA,EAAsB,CAAA;AAAA,EACtB,eAAA,EAAiB,KAAA;AAAA,EACjB,iBAAA,EAAmB;AACrB","file":"types.js","sourcesContent":["/**\n * @ash-cloud/ash-ui - Types\n *\n * Normalized types for structured tool call display in agentic UIs.\n * These types provide a unified representation for displaying tool calls\n * with their arguments and results together.\n */\n\n// =============================================================================\n// Tool Status\n// =============================================================================\n\n/**\n * Status of a tool call execution\n */\nexport type ToolStatus = 'pending' | 'success' | 'failed';\n\n// =============================================================================\n// Action-Specific Result Types\n// =============================================================================\n\n/**\n * Result from a command/bash execution\n */\nexport interface CommandRunResult {\n exitCode?: number;\n success?: boolean;\n output?: string;\n}\n\n/**\n * Generic tool result that can be markdown or structured JSON\n */\nexport interface ToolResult {\n type: 'markdown' | 'json';\n value: unknown;\n}\n\n// =============================================================================\n// Action Types (Discriminated Union)\n// =============================================================================\n\n/**\n * Bash/command execution action\n */\nexport interface CommandRunAction {\n action: 'command_run';\n command: string;\n description?: string;\n result?: CommandRunResult;\n}\n\n/**\n * File read action\n */\nexport interface FileReadAction {\n action: 'file_read';\n path: string;\n offset?: number;\n limit?: number;\n}\n\n/**\n * File edit action\n */\nexport interface FileEditAction {\n action: 'file_edit';\n path: string;\n oldString?: string;\n newString?: string;\n replaceAll?: boolean;\n}\n\n/**\n * File write action\n */\nexport interface FileWriteAction {\n action: 'file_write';\n path: string;\n content?: string;\n}\n\n/**\n * Search/grep action\n */\nexport interface SearchAction {\n action: 'search';\n pattern: string;\n path?: string;\n glob?: string;\n type?: string;\n}\n\n/**\n * Glob/file pattern matching action\n */\nexport interface GlobAction {\n action: 'glob';\n pattern: string;\n path?: string;\n}\n\n/**\n * Web fetch action\n */\nexport interface WebFetchAction {\n action: 'web_fetch';\n url: string;\n prompt?: string;\n}\n\n/**\n * Web search action\n */\nexport interface WebSearchAction {\n action: 'web_search';\n query: string;\n}\n\n/**\n * MCP (Model Context Protocol) tool action\n */\nexport interface McpToolAction {\n action: 'mcp_tool';\n serverName: string;\n toolName: string;\n arguments?: unknown;\n result?: ToolResult;\n}\n\n/**\n * Generic/unknown tool action\n */\nexport interface GenericToolAction {\n action: 'generic_tool';\n toolName: string;\n arguments?: unknown;\n result?: ToolResult;\n}\n\n// =============================================================================\n// Todo Types\n// =============================================================================\n\n/**\n * Status of a todo item\n */\nexport type TodoStatus = 'pending' | 'in_progress' | 'completed';\n\n/**\n * A single todo item from TodoWrite tool\n */\nexport interface TodoItem {\n /** Task content - imperative form (e.g., \"Run tests\") */\n content: string;\n /** Current status of the todo */\n status: TodoStatus;\n /** Active form shown during execution (e.g., \"Running tests\") */\n activeForm: string;\n}\n\n/**\n * TodoWrite tool action - tracks task progress\n */\nexport interface TodoWriteAction {\n action: 'todo_write';\n /** All todos in the current list */\n todos: TodoItem[];\n /** Summary statistics */\n stats?: {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n };\n}\n\n/**\n * Discriminated union of all action types\n */\nexport type ActionType =\n | CommandRunAction\n | FileReadAction\n | FileEditAction\n | FileWriteAction\n | SearchAction\n | GlobAction\n | WebFetchAction\n | WebSearchAction\n | McpToolAction\n | GenericToolAction\n | TodoWriteAction;\n\n// =============================================================================\n// Normalized Tool Call\n// =============================================================================\n\n/**\n * A normalized tool call that combines tool_use and tool_result data\n */\nexport interface NormalizedToolCall {\n /** Unique ID from the tool_use block */\n id: string;\n\n /** Original tool name (e.g., 'Bash', 'Read', 'mcp__server__tool') */\n toolName: string;\n\n /** Parsed action type with structured arguments and result */\n actionType: ActionType;\n\n /** Current execution status */\n status: ToolStatus;\n\n /** Human-readable one-liner summary */\n summary: string;\n\n /** When the tool call started */\n startedAt?: string;\n\n /** When the tool call completed */\n completedAt?: string;\n\n /** Whether this tool call resulted in an error */\n isError?: boolean;\n}\n\n// =============================================================================\n// Normalized Entry Types\n// =============================================================================\n\n/**\n * User message entry\n */\nexport interface UserMessageEntry {\n type: 'user_message';\n}\n\n/**\n * Assistant message entry\n */\nexport interface AssistantMessageEntry {\n type: 'assistant_message';\n}\n\n/**\n * Thinking/reasoning entry (extended thinking)\n */\nexport interface ThinkingEntry {\n type: 'thinking';\n}\n\n/**\n * Tool call entry with full tool call data\n */\nexport interface ToolCallEntry {\n type: 'tool_call';\n toolCall: NormalizedToolCall;\n}\n\n/**\n * Error entry\n */\nexport interface ErrorEntry {\n type: 'error';\n message: string;\n code?: string;\n}\n\n/**\n * Discriminated union of all entry types\n */\nexport type NormalizedEntryType =\n | UserMessageEntry\n | AssistantMessageEntry\n | ThinkingEntry\n | ToolCallEntry\n | ErrorEntry;\n\n// =============================================================================\n// Normalized Entry\n// =============================================================================\n\n/**\n * A normalized conversation entry for display\n */\nexport interface NormalizedEntry {\n /** Unique entry ID */\n id: string;\n\n /** ISO timestamp */\n timestamp?: string;\n\n /** Entry type with type-specific data */\n entryType: NormalizedEntryType;\n\n /** Text content for display */\n content: string;\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\nexport function isCommandRunAction(action: ActionType): action is CommandRunAction {\n return action.action === 'command_run';\n}\n\nexport function isFileReadAction(action: ActionType): action is FileReadAction {\n return action.action === 'file_read';\n}\n\nexport function isFileEditAction(action: ActionType): action is FileEditAction {\n return action.action === 'file_edit';\n}\n\nexport function isFileWriteAction(action: ActionType): action is FileWriteAction {\n return action.action === 'file_write';\n}\n\nexport function isSearchAction(action: ActionType): action is SearchAction {\n return action.action === 'search';\n}\n\nexport function isGlobAction(action: ActionType): action is GlobAction {\n return action.action === 'glob';\n}\n\nexport function isWebFetchAction(action: ActionType): action is WebFetchAction {\n return action.action === 'web_fetch';\n}\n\nexport function isWebSearchAction(action: ActionType): action is WebSearchAction {\n return action.action === 'web_search';\n}\n\nexport function isMcpToolAction(action: ActionType): action is McpToolAction {\n return action.action === 'mcp_tool';\n}\n\nexport function isGenericToolAction(action: ActionType): action is GenericToolAction {\n return action.action === 'generic_tool';\n}\n\nexport function isTodoWriteAction(action: ActionType): action is TodoWriteAction {\n return action.action === 'todo_write';\n}\n\nexport function isToolCallEntry(entry: NormalizedEntryType): entry is ToolCallEntry {\n return entry.type === 'tool_call';\n}\n\nexport function isErrorEntry(entry: NormalizedEntryType): entry is ErrorEntry {\n return entry.type === 'error';\n}\n\n// =============================================================================\n// Log Types (for SandboxLogsPanel)\n// =============================================================================\n\nexport type LogLevel = 'info' | 'warn' | 'error' | 'debug';\nexport type LogCategory = 'setup' | 'skills' | 'execution' | 'process' | 'startup';\n\nexport interface LogEntry {\n timestamp: string;\n level: LogLevel;\n category: LogCategory;\n message: string;\n data?: Record<string, unknown>;\n}\n\n// =============================================================================\n// File Attachment\n// =============================================================================\n\nexport interface FileAttachment {\n name: string;\n type: string;\n size: number;\n base64: string;\n}\n\n// =============================================================================\n// Display Mode Configuration\n// =============================================================================\n\n/**\n * Display mode for tool calls in the chat interface\n *\n * - 'inline': Each tool call rendered inline as expandable cards (current behavior)\n * - 'compact': Single animated status line that updates with each tool call,\n * with accordion to expand and see execution details. Text streams unbroken.\n */\nexport type ToolDisplayMode = 'inline' | 'compact';\n\n/**\n * Configuration for tool display behavior\n */\nexport interface ToolDisplayConfig {\n /**\n * Display mode for tool calls\n * @default 'inline'\n */\n mode: ToolDisplayMode;\n\n /**\n * For 'compact' mode: break into a new group every N tool calls\n * Set to 0 or undefined to never break (all tool calls in single group)\n * @default 0\n */\n breakEveryNToolCalls?: number;\n\n /**\n * Whether tool call groups start expanded\n * @default false\n */\n defaultExpanded?: boolean;\n\n /**\n * Animation duration for status line transitions (ms)\n * @default 300\n */\n animationDuration?: number;\n}\n\n/**\n * Default display configuration\n */\nexport const DEFAULT_DISPLAY_CONFIG: ToolDisplayConfig = {\n mode: 'inline',\n breakEveryNToolCalls: 0,\n defaultExpanded: false,\n animationDuration: 300,\n};\n\n// =============================================================================\n// Tool Execution Group (for compact mode)\n// =============================================================================\n\n/**\n * A group of consecutive tool calls that are displayed together\n * in compact mode. Text content before/after flows around the group.\n */\nexport interface ToolExecutionGroup {\n /** Unique ID for the group */\n id: string;\n\n /** Tool calls in this group (in order) */\n toolCalls: NormalizedToolCall[];\n\n /** Index of the currently active/latest tool call for status display */\n activeIndex: number;\n\n /** Whether all tool calls in this group have completed */\n isComplete: boolean;\n\n /** Overall status of the group */\n status: 'pending' | 'success' | 'partial_failure' | 'failed';\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";AAiVO,SAAS,mBAAmB,MAAA,EAAgD;AACjF,EAAA,OAAO,OAAO,MAAA,KAAW,aAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,eAAe,MAAA,EAA4C;AACzE,EAAA,OAAO,OAAO,MAAA,KAAW,QAAA;AAC3B;AAEO,SAAS,aAAa,MAAA,EAA0C;AACrE,EAAA,OAAO,OAAO,MAAA,KAAW,MAAA;AAC3B;AAEO,SAAS,iBAAiB,MAAA,EAA8C;AAC7E,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,gBAAgB,MAAA,EAA6C;AAC3E,EAAA,OAAO,OAAO,MAAA,KAAW,UAAA;AAC3B;AAEO,SAAS,oBAAoB,MAAA,EAAiD;AACnF,EAAA,OAAO,OAAO,MAAA,KAAW,cAAA;AAC3B;AAEO,SAAS,kBAAkB,MAAA,EAA+C;AAC/E,EAAA,OAAO,OAAO,MAAA,KAAW,YAAA;AAC3B;AAEO,SAAS,gBAAgB,KAAA,EAAoD;AAClF,EAAA,OAAO,MAAM,IAAA,KAAS,WAAA;AACxB;AAEO,SAAS,aAAa,KAAA,EAAiD;AAC5E,EAAA,OAAO,MAAM,IAAA,KAAS,OAAA;AACxB;AAEO,SAAS,cAAc,KAAA,EAAkD;AAC9E,EAAA,OAAO,MAAM,IAAA,KAAS,QAAA;AACxB;AAsIO,IAAM,sBAAA,GAA4C;AAAA,EACvD,IAAA,EAAM,QAAA;AAAA,EACN,oBAAA,EAAsB,CAAA;AAAA,EACtB,eAAA,EAAiB,KAAA;AAAA,EACjB,iBAAA,EAAmB;AACrB","file":"types.js","sourcesContent":["/**\n * @ash-cloud/ash-ui - Types\n *\n * Normalized types for structured tool call display in agentic UIs.\n * These types provide a unified representation for displaying tool calls\n * with their arguments and results together.\n */\n\nimport type { ReactNode } from 'react';\n\n// =============================================================================\n// Tool Status\n// =============================================================================\n\n/**\n * Status of a tool call execution\n */\nexport type ToolStatus = 'pending' | 'success' | 'failed';\n\n// =============================================================================\n// Action-Specific Result Types\n// =============================================================================\n\n/**\n * Result from a command/bash execution\n */\nexport interface CommandRunResult {\n exitCode?: number;\n success?: boolean;\n output?: string;\n}\n\n/**\n * Generic tool result that can be markdown or structured JSON\n */\nexport interface ToolResult {\n type: 'markdown' | 'json';\n value: unknown;\n}\n\n// =============================================================================\n// Action Types (Discriminated Union)\n// =============================================================================\n\n/**\n * Bash/command execution action\n */\nexport interface CommandRunAction {\n action: 'command_run';\n command: string;\n description?: string;\n result?: CommandRunResult;\n}\n\n/**\n * File read action\n */\nexport interface FileReadAction {\n action: 'file_read';\n path: string;\n offset?: number;\n limit?: number;\n}\n\n/**\n * File edit action\n */\nexport interface FileEditAction {\n action: 'file_edit';\n path: string;\n oldString?: string;\n newString?: string;\n replaceAll?: boolean;\n}\n\n/**\n * File write action\n */\nexport interface FileWriteAction {\n action: 'file_write';\n path: string;\n content?: string;\n}\n\n/**\n * Search/grep action\n */\nexport interface SearchAction {\n action: 'search';\n pattern: string;\n path?: string;\n glob?: string;\n type?: string;\n}\n\n/**\n * Glob/file pattern matching action\n */\nexport interface GlobAction {\n action: 'glob';\n pattern: string;\n path?: string;\n}\n\n/**\n * Web fetch action\n */\nexport interface WebFetchAction {\n action: 'web_fetch';\n url: string;\n prompt?: string;\n}\n\n/**\n * Web search action\n */\nexport interface WebSearchAction {\n action: 'web_search';\n query: string;\n}\n\n/**\n * MCP (Model Context Protocol) tool action\n */\nexport interface McpToolAction {\n action: 'mcp_tool';\n serverName: string;\n toolName: string;\n arguments?: unknown;\n result?: ToolResult;\n}\n\n/**\n * Generic/unknown tool action\n */\nexport interface GenericToolAction {\n action: 'generic_tool';\n toolName: string;\n arguments?: unknown;\n result?: ToolResult;\n}\n\n// =============================================================================\n// Todo Types\n// =============================================================================\n\n/**\n * Status of a todo item\n */\nexport type TodoStatus = 'pending' | 'in_progress' | 'completed';\n\n/**\n * A single todo item from TodoWrite tool\n */\nexport interface TodoItem {\n /** Task content - imperative form (e.g., \"Run tests\") */\n content: string;\n /** Current status of the todo */\n status: TodoStatus;\n /** Active form shown during execution (e.g., \"Running tests\") */\n activeForm: string;\n}\n\n/**\n * TodoWrite tool action - tracks task progress\n */\nexport interface TodoWriteAction {\n action: 'todo_write';\n /** All todos in the current list */\n todos: TodoItem[];\n /** Summary statistics */\n stats?: {\n total: number;\n completed: number;\n inProgress: number;\n pending: number;\n };\n}\n\n/**\n * Discriminated union of all action types\n */\nexport type ActionType =\n | CommandRunAction\n | FileReadAction\n | FileEditAction\n | FileWriteAction\n | SearchAction\n | GlobAction\n | WebFetchAction\n | WebSearchAction\n | McpToolAction\n | GenericToolAction\n | TodoWriteAction;\n\n// =============================================================================\n// Normalized Tool Call\n// =============================================================================\n\n/**\n * A normalized tool call that combines tool_use and tool_result data\n */\nexport interface NormalizedToolCall {\n /** Unique ID from the tool_use block */\n id: string;\n\n /** Original tool name (e.g., 'Bash', 'Read', 'mcp__server__tool') */\n toolName: string;\n\n /** Parsed action type with structured arguments and result */\n actionType: ActionType;\n\n /** Current execution status */\n status: ToolStatus;\n\n /** Human-readable one-liner summary */\n summary: string;\n\n /** When the tool call started */\n startedAt?: string;\n\n /** When the tool call completed */\n completedAt?: string;\n\n /** Whether this tool call resulted in an error */\n isError?: boolean;\n}\n\n// =============================================================================\n// Normalized Entry Types\n// =============================================================================\n\n/**\n * User message entry\n */\nexport interface UserMessageEntry {\n type: 'user_message';\n}\n\n/**\n * Assistant message entry\n */\nexport interface AssistantMessageEntry {\n type: 'assistant_message';\n}\n\n/**\n * Thinking/reasoning entry (extended thinking)\n */\nexport interface ThinkingEntry {\n type: 'thinking';\n}\n\n/**\n * Tool call entry with full tool call data\n */\nexport interface ToolCallEntry {\n type: 'tool_call';\n toolCall: NormalizedToolCall;\n}\n\n/**\n * Error entry\n */\nexport interface ErrorEntry {\n type: 'error';\n message: string;\n code?: string;\n}\n\n/**\n * Custom widget entry - rendered via consumer-provided render function\n *\n * Use this for interactive UI components like:\n * - Image grid selectors\n * - Product carousels\n * - Form inputs\n * - Data visualizations\n * - Any custom interactive widget\n *\n * @example\n * ```tsx\n * const entry: NormalizedEntry = {\n * id: 'widget-1',\n * entryType: {\n * type: 'widget',\n * widgetType: 'image-grid',\n * widgetData: { images: [...], selected: null },\n * },\n * content: 'Select an image',\n * };\n * ```\n */\nexport interface WidgetEntry {\n type: 'widget';\n /** Widget type identifier (e.g., 'image-grid', 'product-selector') */\n widgetType: string;\n /** Widget-specific data passed to the render function */\n widgetData: unknown;\n}\n\n/**\n * Discriminated union of all entry types\n */\nexport type NormalizedEntryType =\n | UserMessageEntry\n | AssistantMessageEntry\n | ThinkingEntry\n | ToolCallEntry\n | ErrorEntry\n | WidgetEntry;\n\n// =============================================================================\n// Normalized Entry\n// =============================================================================\n\n/**\n * A normalized conversation entry for display\n */\nexport interface NormalizedEntry {\n /** Unique entry ID */\n id: string;\n\n /** ISO timestamp */\n timestamp?: string;\n\n /** Entry type with type-specific data */\n entryType: NormalizedEntryType;\n\n /** Text content for display */\n content: string;\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\nexport function isCommandRunAction(action: ActionType): action is CommandRunAction {\n return action.action === 'command_run';\n}\n\nexport function isFileReadAction(action: ActionType): action is FileReadAction {\n return action.action === 'file_read';\n}\n\nexport function isFileEditAction(action: ActionType): action is FileEditAction {\n return action.action === 'file_edit';\n}\n\nexport function isFileWriteAction(action: ActionType): action is FileWriteAction {\n return action.action === 'file_write';\n}\n\nexport function isSearchAction(action: ActionType): action is SearchAction {\n return action.action === 'search';\n}\n\nexport function isGlobAction(action: ActionType): action is GlobAction {\n return action.action === 'glob';\n}\n\nexport function isWebFetchAction(action: ActionType): action is WebFetchAction {\n return action.action === 'web_fetch';\n}\n\nexport function isWebSearchAction(action: ActionType): action is WebSearchAction {\n return action.action === 'web_search';\n}\n\nexport function isMcpToolAction(action: ActionType): action is McpToolAction {\n return action.action === 'mcp_tool';\n}\n\nexport function isGenericToolAction(action: ActionType): action is GenericToolAction {\n return action.action === 'generic_tool';\n}\n\nexport function isTodoWriteAction(action: ActionType): action is TodoWriteAction {\n return action.action === 'todo_write';\n}\n\nexport function isToolCallEntry(entry: NormalizedEntryType): entry is ToolCallEntry {\n return entry.type === 'tool_call';\n}\n\nexport function isErrorEntry(entry: NormalizedEntryType): entry is ErrorEntry {\n return entry.type === 'error';\n}\n\nexport function isWidgetEntry(entry: NormalizedEntryType): entry is WidgetEntry {\n return entry.type === 'widget';\n}\n\n// =============================================================================\n// Widget Rendering\n// =============================================================================\n\n/**\n * Props passed to the widget render function\n */\nexport interface WidgetRenderProps<T = unknown> {\n /** The widget entry being rendered */\n entry: NormalizedEntry;\n /** Widget type identifier */\n widgetType: string;\n /** Widget-specific data */\n widgetData: T;\n /** Callback for widget interactions (e.g., selection, submit) */\n onAction?: (action: WidgetAction) => void;\n}\n\n/**\n * Action dispatched from a widget interaction\n */\nexport interface WidgetAction {\n /** Action type (e.g., 'select', 'submit', 'cancel') */\n type: string;\n /** Widget type that dispatched the action */\n widgetType: string;\n /** Entry ID of the widget */\n entryId: string;\n /** Action-specific payload */\n payload?: unknown;\n}\n\n/**\n * Function type for rendering custom widgets\n *\n * @example\n * ```tsx\n * const renderWidget: WidgetRenderFunction = ({ widgetType, widgetData, onAction }) => {\n * switch (widgetType) {\n * case 'image-grid':\n * return (\n * <ImageGrid\n * images={widgetData.images}\n * onSelect={(id) => onAction?.({ type: 'select', widgetType, entryId, payload: { id } })}\n * />\n * );\n * case 'product-selector':\n * return <ProductSelector data={widgetData} onAction={onAction} />;\n * default:\n * return null;\n * }\n * };\n *\n * <MessageList entries={entries} renderWidget={renderWidget} />\n * ```\n */\nexport type WidgetRenderFunction = (props: WidgetRenderProps) => ReactNode;\n\n// =============================================================================\n// Log Types (for SandboxLogsPanel)\n// =============================================================================\n\nexport type LogLevel = 'info' | 'warn' | 'error' | 'debug';\nexport type LogCategory = 'setup' | 'skills' | 'execution' | 'process' | 'startup';\n\nexport interface LogEntry {\n timestamp: string;\n level: LogLevel;\n category: LogCategory;\n message: string;\n data?: Record<string, unknown>;\n}\n\n// =============================================================================\n// File Attachment\n// =============================================================================\n\nexport interface FileAttachment {\n name: string;\n type: string;\n size: number;\n base64: string;\n}\n\n// =============================================================================\n// Display Mode Configuration\n// =============================================================================\n\n/**\n * Display mode for tool calls in the chat interface\n *\n * - 'inline': Each tool call rendered inline as expandable cards (current behavior)\n * - 'compact': Single animated status line that updates with each tool call,\n * with accordion to expand and see execution details. Text streams unbroken.\n * - 'accordion': Simpler step-based accordion list that accumulates tool calls\n * with icons, labels, and durations (like Vidra's ThinkingIndicator).\n */\nexport type ToolDisplayMode = 'inline' | 'compact' | 'accordion';\n\n/**\n * Configuration for tool display behavior\n */\nexport interface ToolDisplayConfig {\n /**\n * Display mode for tool calls\n * @default 'inline'\n */\n mode: ToolDisplayMode;\n\n /**\n * For 'compact' mode: break into a new group every N tool calls\n * Set to 0 or undefined to never break (all tool calls in single group)\n * @default 0\n */\n breakEveryNToolCalls?: number;\n\n /**\n * Whether tool call groups start expanded\n * @default false\n */\n defaultExpanded?: boolean;\n\n /**\n * Animation duration for status line transitions (ms)\n * @default 300\n */\n animationDuration?: number;\n}\n\n/**\n * Default display configuration\n */\nexport const DEFAULT_DISPLAY_CONFIG: ToolDisplayConfig = {\n mode: 'inline',\n breakEveryNToolCalls: 0,\n defaultExpanded: false,\n animationDuration: 300,\n};\n\n// =============================================================================\n// Tool Execution Group (for compact mode)\n// =============================================================================\n\n/**\n * A group of consecutive tool calls that are displayed together\n * in compact mode. Text content before/after flows around the group.\n */\nexport interface ToolExecutionGroup {\n /** Unique ID for the group */\n id: string;\n\n /** Tool calls in this group (in order) */\n toolCalls: NormalizedToolCall[];\n\n /** Index of the currently active/latest tool call for status display */\n activeIndex: number;\n\n /** Whether all tool calls in this group have completed */\n isComplete: boolean;\n\n /** Overall status of the group */\n status: 'pending' | 'success' | 'partial_failure' | 'failed';\n}\n"]}
package/dist/utils.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ActionType, ToolResult, CommandRunResult, NormalizedToolCall, NormalizedEntry, ToolDisplayConfig } from './types.cjs';
2
+ import 'react';
2
3
 
3
4
  /**
4
5
  * @ash-cloud/ash-ui - Utilities
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ActionType, ToolResult, CommandRunResult, NormalizedToolCall, NormalizedEntry, ToolDisplayConfig } from './types.js';
2
+ import 'react';
2
3
 
3
4
  /**
4
5
  * @ash-cloud/ash-ui - Utilities
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ash-cloud/ash-ui",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "React UI components for building agentic interfaces - tool calls, streaming, status displays, and more",
5
5
  "repository": {
6
6
  "type": "git",