@alexkroman1/aai-ui 5.11.0 → 5.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/_colors-CcAi2FOU.js +44 -0
  2. package/dist/{chat-view-DFBmX5eX.js → chat-view-DadZOvJO.js} +11 -7
  3. package/dist/client-config.d.ts +29 -0
  4. package/dist/components/_colors.d.ts +35 -9
  5. package/dist/components/button.js +31 -15
  6. package/dist/components/chat-view.js +1 -1
  7. package/dist/components/controls.js +1 -1
  8. package/dist/components/message-list.js +1 -1
  9. package/dist/components/sidebar-layout.js +9 -8
  10. package/dist/components/start-screen.d.ts +1 -1
  11. package/dist/components/start-screen.js +2 -2
  12. package/dist/components/tool-call-block.js +1 -1
  13. package/dist/{controls-CoBO6sId.js → controls-DzQEKq9c.js} +8 -7
  14. package/dist/default-client/assets/{audio-DJF-gC7e.js → audio-BAAzYW28.js} +1 -1
  15. package/dist/default-client/assets/{capture-processor-D_A9RUeB.js → capture-processor-vx5IW_Rd.js} +1 -1
  16. package/dist/default-client/assets/index-Cn-zI5ic.js +293 -0
  17. package/dist/default-client/assets/index-Ctjrde3-.css +2 -0
  18. package/dist/default-client/assets/{playback-processor-GPTQTyza.js → playback-processor-2p9HLz_W.js} +1 -1
  19. package/dist/default-client/index.html +2 -2
  20. package/dist/define-client.js +3 -3
  21. package/dist/hooks.test-d.d.ts +14 -0
  22. package/dist/index.js +5 -5
  23. package/dist/{message-list-DkAHoB3A.js → message-list-YdLocGoT.js} +11 -9
  24. package/dist/{session-core-CS37WE1G.js → session-core-BoB7kTzL.js} +184 -43
  25. package/dist/session-core-handshake.d.ts +25 -0
  26. package/dist/session-core-reconnect.d.ts +8 -0
  27. package/dist/session-core.js +1 -1
  28. package/dist/{tool-call-block-BjemDFB9.js → tool-call-block-CAscLGFy.js} +6 -6
  29. package/package.json +2 -2
  30. package/dist/_colors-Bfh3-BVE.js +0 -29
  31. package/dist/default-client/assets/index-1JIz81CD.css +0 -2
  32. package/dist/default-client/assets/index-D_RNiTIh.js +0 -278
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-wide:.025em;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-aai:"Monument Grotesk", "ABC Monument Grotesk", ui-sans-serif, system-ui, -apple-system, sans-serif;--font-aai-serif:"Source Serif 4", "Source Serif Pro", Charter, "Iowan Old Style", Georgia, serif;--font-aai-mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--radius-aai:4px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}html,body{margin:0;padding:0}}@layer components;@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.order-last{order:9999}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-auto{margin-inline:auto}.my-0\.5{margin-block:calc(var(--spacing) * .5)}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.my-2\.5{margin-block:calc(var(--spacing) * 2.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.box-border{box-sizing:border-box}.block{display:block}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-4{height:calc(var(--spacing) * 4)}.h-9{height:calc(var(--spacing) * 9)}.h-11{height:calc(var(--spacing) * 11)}.h-\[7px\]{height:7px}.h-screen{height:100vh}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-\[40vh\]{max-height:40vh}.min-h-0{min-height:0}.min-h-5{min-height:calc(var(--spacing) * 5)}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-\[7px\]{width:7px}.w-fit{width:fit-content}.w-full{width:100%}.max-w-75{max-width:calc(var(--spacing) * 75)}.max-w-105{max-width:calc(var(--spacing) * 105)}.max-w-190{max-width:calc(var(--spacing) * 190)}.max-w-\[82\%\]{max-width:82%}.max-w-\[min\(78\%\,64ch\)\]{max-width:min(78%,64ch)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.basis-full{flex-basis:100%}.border-collapse{border-collapse:collapse}.rotate-90{rotate:90deg}.cursor-pointer{cursor:pointer}.resize{resize:both}.\[scrollbar-width\:none\]{scrollbar-width:none}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded-aai{border-radius:var(--radius-aai)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-none{--tw-border-style:none;border-style:none}.border-\(--aai-btn-bd\){border-color:var(--aai-btn-bd)}.bg-\(--aai-btn-bg\){background-color:var(--aai-btn-bg)}.bg-transparent{background-color:#0000}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-7{padding:calc(var(--spacing) * 7)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-10{padding-inline:calc(var(--spacing) * 10)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.font-aai{font-family:var(--font-aai)}.font-aai-mono{font-family:var(--font-aai-mono)}.font-aai-serif{font-family:var(--font-aai-serif)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12\.5px\]{font-size:12.5px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.text-\[22px\]{font-size:22px}.text-\[32px\]{font-size:32px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-\[1\.2\]{--tw-leading:1.2;line-height:1.2}.leading-\[1\.15\]{--tw-leading:1.15;line-height:1.15}.leading-\[22px\]{--tw-leading:22px;line-height:22px}.leading-\[23px\]{--tw-leading:23px;line-height:23px}.leading-\[130\%\]{--tw-leading:130%;line-height:130%}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.2px\]{--tw-tracking:-.2px;letter-spacing:-.2px}.tracking-\[1\.2px\]{--tw-tracking:1.2px;letter-spacing:1.2px}.tracking-\[1\.4px\]{--tw-tracking:1.4px;letter-spacing:1.4px}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-balance{text-wrap:balance}.wrap-break-word{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\(--aai-btn-fg\){color:var(--aai-btn-fg)}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.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{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.first\:mt-0:first-child{margin-top:0}.last\:mb-0:last-child{margin-bottom:0}.focus-visible\:\[outline\:2px_solid\]:focus-visible{outline:2px solid}.focus-visible\:\[outline-offset\:2px\]:focus-visible{outline-offset:2px}@media (hover:hover){.enabled\:hover\:border-\(--aai-btn-bd-hover\):enabled:hover{border-color:var(--aai-btn-bd-hover)}.enabled\:hover\:bg-\(--aai-btn-bg-hover\):enabled:hover{background-color:var(--aai-btn-bg-hover)}.enabled\:hover\:text-\(--aai-btn-fg-hover\):enabled:hover{color:var(--aai-btn-fg-hover)}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=40rem){.sm\:ml-auto{margin-left:auto}.sm\:max-w-\[60\%\]{max-width:60%}.sm\:basis-auto{flex-basis:auto}.sm\:px-16{padding-inline:calc(var(--spacing) * 16)}.sm\:py-14{padding-block:calc(var(--spacing) * 14)}}@media (width>=48rem){.md\:order-none{order:0}.md\:h-screen{height:100vh}.md\:max-h-none{max-height:none}.md\:w-\(--aai-sidebar-w\){width:var(--aai-sidebar-w)}.md\:flex-row{flex-direction:row}.md\:border-t-0{border-top-style:var(--tw-border-style);border-top-width:0}.md\:border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.md\:border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.md\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}}}@keyframes aai-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.82)}}@keyframes aai-bounce{0%,80%,to{opacity:.3;transform:scale(.8)}40%{opacity:1;transform:scale(1)}}@keyframes aai-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.tool-shimmer{-webkit-text-fill-color:transparent;background:linear-gradient(90deg,currentColor 25%,#0000 50%,currentColor 75%) 0 0/200% 100%;-webkit-background-clip:text;background-clip:text;animation:2s infinite aai-shimmer}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}
@@ -1,4 +1,4 @@
1
- import{i as e}from"./index-D_RNiTIh.js";import{t}from"./_module-url-BX0RuRU2.js";var n=t(`
1
+ import{i as e}from"./index-Cn-zI5ic.js";import{t}from"./_module-url-BX0RuRU2.js";var n=t(`
2
2
  class PlaybackProcessor extends AudioWorkletProcessor {
3
3
  constructor(options) {
4
4
  super();
@@ -6,8 +6,8 @@
6
6
  <title>aai</title>
7
7
  <link rel="icon" href="./favicon.ico" />
8
8
  <style>html, body { background: #FBF8F2; margin: 0; }</style>
9
- <script type="module" crossorigin src="./assets/index-D_RNiTIh.js"></script>
10
- <link rel="stylesheet" crossorigin href="./assets/index-1JIz81CD.css">
9
+ <script type="module" crossorigin src="./assets/index-Cn-zI5ic.js"></script>
10
+ <link rel="stylesheet" crossorigin href="./assets/index-Ctjrde3-.css">
11
11
  </head>
12
12
  <body>
13
13
  <main id="app"></main>
@@ -1,8 +1,8 @@
1
- import { r as fetchClientConfig, t as createSessionCore } from "./session-core-CS37WE1G.js";
1
+ import { r as fetchClientConfig, t as createSessionCore } from "./session-core-BoB7kTzL.js";
2
2
  import { SessionProvider, ThemeProvider } from "./context.js";
3
- import { t as ChatView } from "./chat-view-DFBmX5eX.js";
3
+ import { t as ChatView } from "./chat-view-DadZOvJO.js";
4
4
  import { t as pageBaseUrl } from "./_utils-CsqbIVGI.js";
5
- import { n as ToolConfigContext } from "./tool-call-block-BjemDFB9.js";
5
+ import { n as ToolConfigContext } from "./tool-call-block-CAscLGFy.js";
6
6
  import { SidebarLayout } from "./components/sidebar-layout.js";
7
7
  import { StartScreen } from "./components/start-screen.js";
8
8
  import { createElement, useEffect, useState } from "react";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Type-level contract for the four `aai-ui` hooks a custom client is written
3
+ * against. All four are generic, all four are typed BY THE CALLER, and every
4
+ * one of them was unpinned — the root guide claimed `aai-ui` (`.`) had
5
+ * type-level coverage and no `.test-d.ts` existed in this package at all.
6
+ *
7
+ * The reason these need a type test rather than a runtime one: nothing here
8
+ * has runtime behaviour to observe. `useAgentState` is one `useSessionSelector`
9
+ * call plus a cast, and `useToolResult`'s two overloads erase to the same
10
+ * `(...args: unknown[])` implementation. What a consumer actually depends on
11
+ * is the SIGNATURE, and a signature is exactly what a runtime suite cannot
12
+ * assert.
13
+ */
14
+ export {};
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import { i as loadClientConfig, n as buildAgentUrl, r as fetchClientConfig, t as createSessionCore } from "./session-core-CS37WE1G.js";
1
+ import { i as loadClientConfig, n as buildAgentUrl, r as fetchClientConfig, t as createSessionCore } from "./session-core-BoB7kTzL.js";
2
2
  import { SessionProvider, ThemeProvider, useSession, useSessionSelector, useTheme } from "./context.js";
3
3
  import { Button } from "./components/button.js";
4
- import { t as ChatView } from "./chat-view-DFBmX5eX.js";
5
- import { i as UiUrlChip, n as ApiUrlChip, r as SessionUrlChips, t as Controls } from "./controls-CoBO6sId.js";
6
- import { n as Markdown, t as MessageList } from "./message-list-DkAHoB3A.js";
7
- import { n as ToolConfigContext, r as ToolCallRow } from "./tool-call-block-BjemDFB9.js";
4
+ import { t as ChatView } from "./chat-view-DadZOvJO.js";
5
+ import { i as UiUrlChip, n as ApiUrlChip, r as SessionUrlChips, t as Controls } from "./controls-DzQEKq9c.js";
6
+ import { n as Markdown, t as MessageList } from "./message-list-YdLocGoT.js";
7
+ import { n as ToolConfigContext, r as ToolCallRow } from "./tool-call-block-CAscLGFy.js";
8
8
  import { SidebarLayout } from "./components/sidebar-layout.js";
9
9
  import { StartScreen } from "./components/start-screen.js";
10
10
  import { VOICE_CAPTURE_CONSTRAINTS } from "./types.js";
@@ -1,6 +1,6 @@
1
1
  import { useSessionSelector, useTheme } from "./context.js";
2
- import { i as TEXT_MUTED, n as SURFACE_TINT, o as primaryTint, r as TEXT_FAINT } from "./_colors-Bfh3-BVE.js";
3
- import { t as ToolCallBlock } from "./tool-call-block-BjemDFB9.js";
2
+ import { i as primaryTint, r as inkTint } from "./_colors-CcAi2FOU.js";
3
+ import { t as ToolCallBlock } from "./tool-call-block-CAscLGFy.js";
4
4
  import clsx from "clsx";
5
5
  import { memo, useMemo } from "react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -120,7 +120,7 @@ const Markdown = memo(function Markdown({ text, variant = "default" }) {
120
120
  className: clsx("rounded-sm border px-1 py-0.5 font-aai-mono", scale.code),
121
121
  style: {
122
122
  borderColor: theme.border,
123
- background: SURFACE_TINT,
123
+ background: inkTint(theme.text, theme.surface, 3),
124
124
  ...style
125
125
  },
126
126
  ...rest,
@@ -131,7 +131,7 @@ const Markdown = memo(function Markdown({ text, variant = "default" }) {
131
131
  className: "my-1.5 overflow-x-auto rounded-md border p-2.5 whitespace-pre-wrap wrap-break-word",
132
132
  style: {
133
133
  borderColor: theme.border,
134
- background: SURFACE_TINT,
134
+ background: inkTint(theme.text, theme.surface, 3),
135
135
  ...style
136
136
  },
137
137
  ...props
@@ -140,7 +140,7 @@ const Markdown = memo(function Markdown({ text, variant = "default" }) {
140
140
  className: "my-1.5 border-l-2 pl-3",
141
141
  style: {
142
142
  borderColor: theme.border,
143
- color: TEXT_MUTED,
143
+ color: inkTint(theme.text, theme.surface, 75),
144
144
  ...style
145
145
  },
146
146
  ...props
@@ -193,14 +193,16 @@ const DOT_STYLES = [
193
193
  }));
194
194
  /** Animated three-dot "thinking" indicator. @internal */
195
195
  function ThinkingDots() {
196
+ const theme = useTheme();
197
+ const muted = inkTint(theme.text, theme.surface, 75);
196
198
  return /* @__PURE__ */ jsx("div", {
197
199
  className: "flex items-center gap-2 text-sm font-medium min-h-5",
198
- style: { color: TEXT_MUTED },
200
+ style: { color: muted },
199
201
  children: DOT_STYLES.map((style, i) => /* @__PURE__ */ jsx("div", {
200
202
  className: "w-1.5 h-1.5 rounded-full",
201
203
  style: {
202
204
  ...style,
203
- background: TEXT_MUTED
205
+ background: muted
204
206
  }
205
207
  }, i))
206
208
  });
@@ -243,7 +245,7 @@ const MessageBubble = memo(function MessageBubble({ message, theme }) {
243
245
  className: "flex flex-col gap-1 max-w-[82%]",
244
246
  children: [/* @__PURE__ */ jsx("span", {
245
247
  className: "text-[10px] font-medium tracking-[1.2px] uppercase leading-none",
246
- style: { color: TEXT_FAINT },
248
+ style: { color: inkTint(theme.text, theme.surface, 65) },
247
249
  children: "Agent"
248
250
  }), /* @__PURE__ */ jsx("div", {
249
251
  className: "wrap-break-word text-[15px] font-normal leading-[23px]",
@@ -347,7 +349,7 @@ const MessageList = memo(function MessageList({ className }) {
347
349
  }),
348
350
  userTranscript !== null && /* @__PURE__ */ jsx(UserBubble, {
349
351
  theme,
350
- color: "#6F6A60",
352
+ color: inkTint(theme.text, theme.surface, 65),
351
353
  children: userTranscript ? userTranscript : /* @__PURE__ */ jsx(ThinkingDots, {})
352
354
  }),
353
355
  showThinking && /* @__PURE__ */ jsx(ThinkingDots, {})
@@ -28,6 +28,35 @@ function buildAgentUrl(platformUrl, endpointPath) {
28
28
  }
29
29
  const AGENT_DEFAULT = {};
30
30
  /**
31
+ * Per-attempt deadline for the `client-config` lookup.
32
+ *
33
+ * A request issued while the platform is restarting or saturated can HANG
34
+ * rather than fail — the proxy holds the socket open — and a browser fetch
35
+ * has no timeout of its own. Every other failure here is already handled
36
+ * (`null`, then the same-origin fallback), but a hang is not a failure: the
37
+ * promise simply never settles.
38
+ *
39
+ * That is unrecoverable rather than merely slow, because this lookup runs
40
+ * inside the session's WebSocket URL *provider*. partysocket awaits the
41
+ * provider under `_connectLock` and arms its own `connectionTimeout` only
42
+ * AFTER the URL resolves, so a hung lookup means no socket is ever
43
+ * constructed, no `error`/`close` ever fires, and none of the 10 reconnect
44
+ * attempts ever happen — the session sits on "connecting" forever, and stays
45
+ * there long after the server is back. Reproduced: zero sockets opened.
46
+ *
47
+ * A timed-out attempt therefore degrades exactly like any other failed one —
48
+ * `null`, so `serverIsBroker` stays unlatched and the attempt falls through
49
+ * to the same-origin `websocket` path, whose failure re-enters the normal
50
+ * backoff and re-fetches this on the next attempt.
51
+ *
52
+ * Sized well above the real work (one same-origin JSON GET that reads the
53
+ * agent's row) and well under a user's patience — the same 10s the studio's
54
+ * gating reads use for the identical hazard.
55
+ *
56
+ * @internal
57
+ */
58
+ const CLIENT_CONFIG_ATTEMPT_TIMEOUT_MS = 1e4;
59
+ /**
31
60
  * Fetch the agent's client config, reporting `null` when the lookup did not
32
61
  * produce an answer (network error, non-2xx, unparsable body).
33
62
  *
@@ -46,7 +75,7 @@ const AGENT_DEFAULT = {};
46
75
  async function loadClientConfig(platformUrl, fetchFn) {
47
76
  const doFetch = fetchFn ?? ((input, init) => globalThis.fetch(input, init));
48
77
  try {
49
- const resp = await doFetch(buildAgentUrl(platformUrl, CLIENT_CONFIG_PATH).href);
78
+ const resp = await doFetch(buildAgentUrl(platformUrl, CLIENT_CONFIG_PATH).href, { signal: AbortSignal.timeout(CLIENT_CONFIG_ATTEMPT_TIMEOUT_MS) });
50
79
  if (!resp.ok) return null;
51
80
  const parsed = ClientConfigResponseSchema.safeParse(await resp.json());
52
81
  return parsed.success ? parsed.data : null;
@@ -174,6 +203,129 @@ async function initAudioCapture(conn, msg, deps) {
174
203
  }
175
204
  }
176
205
  //#endregion
206
+ //#region session-core-reconnect.ts
207
+ /**
208
+ * Automatic reconnection for the browser session socket, built on
209
+ * partysocket's `ReconnectingWebSocket`. Kept out of `session-core.ts` so
210
+ * the state machine there reads as protocol logic, not socket plumbing.
211
+ */
212
+ /**
213
+ * Backoff for automatic reconnects after an unexpected close (partysocket):
214
+ * exponential from 1s, capped at 15s, giving up after 10 attempts. Applies
215
+ * only to the default socket implementation — an injected
216
+ * `options.WebSocket` (tests) never reconnects on its own.
217
+ */
218
+ const RECONNECT_OPTIONS = {
219
+ minReconnectionDelay: 1e3,
220
+ maxReconnectionDelay: 15e3,
221
+ reconnectionDelayGrowFactor: 2,
222
+ maxRetries: 10
223
+ };
224
+ /**
225
+ * Open partysocket's reconnecting WebSocket. The URL is a *provider*,
226
+ * re-evaluated on every attempt (async supported), so each retry picks up
227
+ * the current broker-named endpoint and resume URL rather than the ones the
228
+ * session started with.
229
+ */
230
+ function openReconnectingSocket(urlProvider) {
231
+ return new ReconnectingWebSocket(urlProvider, void 0, RECONNECT_OPTIONS);
232
+ }
233
+ /**
234
+ * True while `socket` is a reconnecting socket that will retry after the
235
+ * close event currently being handled. partysocket schedules the retry
236
+ * *before* dispatching `close`, so `retryCount` already names the attempt
237
+ * just scheduled — at `maxRetries` it has given up.
238
+ */
239
+ /**
240
+ * Force a fresh connection attempt on a reconnecting socket, reporting
241
+ * whether it was one. Used for a failure partysocket cannot see: a socket it
242
+ * considers open and healthy, whose peer never completed OUR handshake.
243
+ * Returns false for an injected `options.WebSocket` (tests), which has no
244
+ * reconnect machinery — the caller then treats the failure as terminal.
245
+ */
246
+ function forceReconnect(socket) {
247
+ if (!(socket instanceof ReconnectingWebSocket)) return false;
248
+ socket.reconnect();
249
+ return true;
250
+ }
251
+ function reconnectPending(socket) {
252
+ return socket instanceof ReconnectingWebSocket && socket.shouldReconnect && socket.retryCount < RECONNECT_OPTIONS.maxRetries;
253
+ }
254
+ //#endregion
255
+ //#region session-core-handshake.ts
256
+ /**
257
+ * The deadline on a socket that opened but never became a session.
258
+ *
259
+ * A completed WebSocket handshake is not a session. The server builds the
260
+ * session synchronously from its own upgrade callback and sends `config` at
261
+ * zero RTT (`aai/host/ws-handler.ts`), so a socket that has been open for
262
+ * seconds with nothing on it is not slow — its peer is not a healthy agent
263
+ * server. That happens: a tunnel or proxy answers the `101` while the guest
264
+ * behind it is wedged, or the host dies between accepting and building the
265
+ * session.
266
+ *
267
+ * Nothing else catches it. partysocket's `connectionTimeout` covers only the
268
+ * handshake and is cleared the moment `open` fires, so the session reached
269
+ * `state: "ready"` — painted with the same live indicator the UI gives
270
+ * "listening" — and stayed there permanently: no `config` means
271
+ * `initAudioCapture` never runs, so there is no mic, no error, no retry, and
272
+ * nothing on screen to say so. Measured against a server that accepts and
273
+ * then says nothing: `ready` at 34ms, still `ready` and errorless when the
274
+ * probe gave up.
275
+ */
276
+ /** What the session reports once the budget below is spent. */
277
+ const HANDSHAKE_ERROR = {
278
+ code: "connection",
279
+ message: "Agent did not complete the session handshake"
280
+ };
281
+ /** How long an OPEN socket may go without a `config` frame. */
282
+ const HANDSHAKE_TIMEOUT_MS = 1e4;
283
+ /**
284
+ * How many consecutive handshake timeouts to ride out before giving up.
285
+ *
286
+ * `forceReconnect` restarts partysocket's own retry budget, so this is the
287
+ * budget for this failure mode — without one, a permanently wedged peer would
288
+ * be re-dialed every ~10s forever, which is the unbounded retry loop
289
+ * `RECONNECT_OPTIONS.maxRetries` exists to prevent.
290
+ */
291
+ const MAX_HANDSHAKE_TIMEOUTS = 3;
292
+ /**
293
+ * Watch one connection's handshake.
294
+ *
295
+ * `onRetry` fires when a timed-out attempt has been re-dialed (the sandbox
296
+ * behind the endpoint may have been replaced, and the URL provider re-brokers
297
+ * on the next attempt); `onExhausted` when the budget is spent, or when the
298
+ * socket has no reconnect machinery at all (an injected `options.WebSocket`).
299
+ *
300
+ * @internal
301
+ */
302
+ function createHandshakeGuard(opts) {
303
+ let timer;
304
+ let timeouts = 0;
305
+ function disarm() {
306
+ if (timer === void 0) return;
307
+ clearTimeout(timer);
308
+ timer = void 0;
309
+ }
310
+ function fire() {
311
+ timer = void 0;
312
+ timeouts += 1;
313
+ if (timeouts < MAX_HANDSHAKE_TIMEOUTS && forceReconnect(opts.socket)) {
314
+ opts.onRetry();
315
+ return;
316
+ }
317
+ opts.onExhausted();
318
+ }
319
+ opts.signal.addEventListener("abort", disarm);
320
+ return {
321
+ arm() {
322
+ disarm();
323
+ timer = setTimeout(fire, HANDSHAKE_TIMEOUT_MS);
324
+ },
325
+ disarm
326
+ };
327
+ }
328
+ //#endregion
177
329
  //#region session-core-messages.ts
178
330
  /**
179
331
  * Incoming-message handling for the voice session core.
@@ -465,43 +617,6 @@ function createMessageHandlers(deps) {
465
617
  };
466
618
  }
467
619
  //#endregion
468
- //#region session-core-reconnect.ts
469
- /**
470
- * Automatic reconnection for the browser session socket, built on
471
- * partysocket's `ReconnectingWebSocket`. Kept out of `session-core.ts` so
472
- * the state machine there reads as protocol logic, not socket plumbing.
473
- */
474
- /**
475
- * Backoff for automatic reconnects after an unexpected close (partysocket):
476
- * exponential from 1s, capped at 15s, giving up after 10 attempts. Applies
477
- * only to the default socket implementation — an injected
478
- * `options.WebSocket` (tests) never reconnects on its own.
479
- */
480
- const RECONNECT_OPTIONS = {
481
- minReconnectionDelay: 1e3,
482
- maxReconnectionDelay: 15e3,
483
- reconnectionDelayGrowFactor: 2,
484
- maxRetries: 10
485
- };
486
- /**
487
- * Open partysocket's reconnecting WebSocket. The URL is a *provider*,
488
- * re-evaluated on every attempt (async supported), so each retry picks up
489
- * the current broker-named endpoint and resume URL rather than the ones the
490
- * session started with.
491
- */
492
- function openReconnectingSocket(urlProvider) {
493
- return new ReconnectingWebSocket(urlProvider, void 0, RECONNECT_OPTIONS);
494
- }
495
- /**
496
- * True while `socket` is a reconnecting socket that will retry after the
497
- * close event currently being handled. partysocket schedules the retry
498
- * *before* dispatching `close`, so `retryCount` already names the attempt
499
- * just scheduled — at `maxRetries` it has given up.
500
- */
501
- function reconnectPending(socket) {
502
- return socket instanceof ReconnectingWebSocket && socket.shouldReconnect && socket.retryCount < RECONNECT_OPTIONS.maxRetries;
503
- }
504
- //#endregion
505
620
  //#region session-core-url.ts
506
621
  /** Build the session WebSocket URL from the platform URL and resume state. */
507
622
  function buildWsUrl(platformUrl, resume, sessionId) {
@@ -743,18 +858,46 @@ function createSessionCore(options) {
743
858
  socket.binaryType = "arraybuffer";
744
859
  conn.ws = socket;
745
860
  let socketErrored = false;
861
+ const handshake = createHandshakeGuard({
862
+ socket,
863
+ signal: sig,
864
+ onRetry: () => {
865
+ cleanupAudio();
866
+ conn.generation.bump();
867
+ updateState({
868
+ state: "connecting",
869
+ recording: false
870
+ });
871
+ },
872
+ onExhausted: () => {
873
+ cleanupAudio();
874
+ controller.abort();
875
+ socket.close();
876
+ conn.ws = null;
877
+ updateState({
878
+ state: "error",
879
+ error: HANDSHAKE_ERROR,
880
+ running: false,
881
+ recording: false
882
+ });
883
+ }
884
+ });
746
885
  socket.addEventListener("open", () => {
747
886
  updateState({ state: "ready" });
887
+ handshake.arm();
748
888
  }, { signal: sig });
749
889
  socket.addEventListener("message", (event) => {
750
890
  const config = handleMessage(event.data);
751
- if (config) onServerConfig(config);
891
+ if (!config) return;
892
+ handshake.disarm();
893
+ onServerConfig(config);
752
894
  }, { signal: sig });
753
895
  socket.addEventListener("error", () => {
754
896
  socketErrored = true;
755
897
  }, { signal: sig });
756
898
  socket.addEventListener("close", () => {
757
899
  if (sig.aborted) return;
900
+ handshake.disarm();
758
901
  cleanupAudio();
759
902
  if (!conn.retiredByServer && reconnectPending(socket)) {
760
903
  conn.generation.bump();
@@ -803,10 +946,8 @@ function createSessionCore(options) {
803
946
  sendJson({ type: "reset" });
804
947
  return;
805
948
  }
806
- resetState();
807
- disconnect();
808
- updateState({ running: true });
809
- connect();
949
+ end();
950
+ start();
810
951
  }
811
952
  function disconnect() {
812
953
  teardownConnection();
@@ -0,0 +1,25 @@
1
+ import type { SessionError } from "./types.ts";
2
+ /** What the session reports once the budget below is spent. */
3
+ export declare const HANDSHAKE_ERROR: SessionError;
4
+ export type HandshakeGuard = {
5
+ /** Start the deadline for the attempt that just opened. */
6
+ arm(): void;
7
+ /** Stop it — `config` arrived, or this socket is closing. */
8
+ disarm(): void;
9
+ };
10
+ /**
11
+ * Watch one connection's handshake.
12
+ *
13
+ * `onRetry` fires when a timed-out attempt has been re-dialed (the sandbox
14
+ * behind the endpoint may have been replaced, and the URL provider re-brokers
15
+ * on the next attempt); `onExhausted` when the budget is spent, or when the
16
+ * socket has no reconnect machinery at all (an injected `options.WebSocket`).
17
+ *
18
+ * @internal
19
+ */
20
+ export declare function createHandshakeGuard(opts: {
21
+ socket: unknown;
22
+ signal: AbortSignal;
23
+ onRetry: () => void;
24
+ onExhausted: () => void;
25
+ }): HandshakeGuard;
@@ -17,4 +17,12 @@ export declare function openReconnectingSocket(urlProvider: () => Promise<string
17
17
  * *before* dispatching `close`, so `retryCount` already names the attempt
18
18
  * just scheduled — at `maxRetries` it has given up.
19
19
  */
20
+ /**
21
+ * Force a fresh connection attempt on a reconnecting socket, reporting
22
+ * whether it was one. Used for a failure partysocket cannot see: a socket it
23
+ * considers open and healthy, whose peer never completed OUR handshake.
24
+ * Returns false for an injected `options.WebSocket` (tests), which has no
25
+ * reconnect machinery — the caller then treats the failure as terminal.
26
+ */
27
+ export declare function forceReconnect(socket: unknown): boolean;
20
28
  export declare function reconnectPending(socket: unknown): boolean;
@@ -1,2 +1,2 @@
1
- import { t as createSessionCore } from "./session-core-CS37WE1G.js";
1
+ import { t as createSessionCore } from "./session-core-BoB7kTzL.js";
2
2
  export { createSessionCore };
@@ -1,5 +1,5 @@
1
1
  import { useTheme } from "./context.js";
2
- import { r as TEXT_FAINT } from "./_colors-Bfh3-BVE.js";
2
+ import { r as inkTint } from "./_colors-CcAi2FOU.js";
3
3
  import { t as Eyebrow } from "./eyebrow-C6ZFuiz6.js";
4
4
  import { n as truncate, r as tryParseJSON } from "./_utils-CsqbIVGI.js";
5
5
  import clsx from "clsx";
@@ -60,22 +60,22 @@ function ToolCallRow({ title, detail, pending = false, icon, variant = "default"
60
60
  children: icon
61
61
  }) : /* @__PURE__ */ jsx(Eyebrow, {
62
62
  className: "shrink-0",
63
- style: { color: TEXT_FAINT },
63
+ style: { color: inkTint(theme.text, theme.bg, 65) },
64
64
  children: "Tool"
65
65
  }),
66
66
  /* @__PURE__ */ jsx("span", {
67
- className: clsx("shrink-0 font-aai-mono font-medium", sizes.title, pending && "tool-shimmer"),
67
+ className: clsx("min-w-0 truncate font-aai-mono font-medium", sizes.title, pending && "tool-shimmer"),
68
68
  style: { color: theme.text },
69
69
  children: title
70
70
  }),
71
71
  /* @__PURE__ */ jsx("span", {
72
72
  className: clsx("font-aai-mono truncate flex-1 min-w-0", sizes.title),
73
- style: { color: TEXT_FAINT },
73
+ style: { color: inkTint(theme.text, theme.bg, 65) },
74
74
  children: detail
75
75
  }),
76
76
  canExpand && /* @__PURE__ */ jsx("span", {
77
77
  className: clsx("shrink-0 transition-transform duration-150", sizes.chevron, isOpen && "rotate-90"),
78
- style: { color: "#6F6A60" },
78
+ style: { color: inkTint(theme.text, theme.bg, 65) },
79
79
  children: "▶"
80
80
  })
81
81
  ]
@@ -167,7 +167,7 @@ const ToolCallBlock = memo(function ToolCallBlock({ toolCall, className }) {
167
167
  children: String(toolCall.args.code)
168
168
  }), formatted && /* @__PURE__ */ jsx("pre", {
169
169
  className: "font-aai-mono text-xs px-3.5 py-3 m-0 whitespace-pre-wrap wrap-break-word",
170
- style: { color: "#57534B" },
170
+ style: { color: inkTint(theme.text, theme.surface, 75) },
171
171
  children: formatted
172
172
  })] }) : void 0
173
173
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexkroman1/aai-ui",
3
- "version": "5.11.0",
3
+ "version": "5.13.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -28,7 +28,7 @@
28
28
  "remark-gfm": "^4.0.1",
29
29
  "use-stick-to-bottom": "^1.1.6",
30
30
  "use-sync-external-store": "^1.6.0",
31
- "@alexkroman1/aai": "5.11.0"
31
+ "@alexkroman1/aai": "5.13.0"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": "^19.0.0",
@@ -1,29 +0,0 @@
1
- //#region components/_colors.ts
2
- /**
3
- * Shared tints used by the default components (AssemblyAI design system,
4
- * "website refresh": warm neutrals over the cream/white surfaces).
5
- *
6
- * These sit on top of the {@link ClientTheme} colors (which own the opaque
7
- * palette) and are intentionally not themeable: they are the warm-gray text
8
- * steps and ink alpha layers the refresh uses over any light surface.
9
- */
10
- /** Muted text — subtitles, secondary labels, thinking dots (fg-muted). */
11
- const TEXT_MUTED = "#57534B";
12
- /** Faint text — live transcripts, state indicator, start-screen subtitle (warm-500). */
13
- const TEXT_FAINT = "#6F6A60";
14
- /** Subtle surface tint — message bubbles, tool-call blocks. */
15
- const SURFACE_TINT = "rgba(20,18,12,0.03)";
16
- /** Error red tuned for warm light surfaces. */
17
- const ERROR_COLOR = "#B3261E";
18
- /** Amber used by the "thinking" state indicator. */
19
- const THINKING_COLOR = "#B98900";
20
- /**
21
- * Derive the user-bubble fill/edge from the theme primary (the mock's
22
- * indigo-50 background with an indigo-100 border), so custom themes keep a
23
- * coherent tinted bubble instead of a hardcoded indigo.
24
- */
25
- function primaryTint(primary, surface, pct) {
26
- return `color-mix(in srgb, ${primary} ${pct}%, ${surface})`;
27
- }
28
- //#endregion
29
- export { THINKING_COLOR as a, TEXT_MUTED as i, SURFACE_TINT as n, primaryTint as o, TEXT_FAINT as r, ERROR_COLOR as t };
@@ -1,2 +0,0 @@
1
- /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-wide:.025em;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-aai:"Monument Grotesk", "ABC Monument Grotesk", ui-sans-serif, system-ui, -apple-system, sans-serif;--font-aai-serif:"Source Serif 4", "Source Serif Pro", Charter, "Iowan Old Style", Georgia, serif;--font-aai-mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--radius-aai:4px}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}html,body{margin:0;padding:0}}@layer components;@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:0}.mx-auto{margin-inline:auto}.my-0\.5{margin-block:calc(var(--spacing) * .5)}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.my-2\.5{margin-block:calc(var(--spacing) * 2.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.ml-auto{margin-left:auto}.box-border{box-sizing:border-box}.block{display:block}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-4{height:calc(var(--spacing) * 4)}.h-9{height:calc(var(--spacing) * 9)}.h-11{height:calc(var(--spacing) * 11)}.h-\[7px\]{height:7px}.h-screen{height:100vh}.max-h-64{max-height:calc(var(--spacing) * 64)}.min-h-0{min-height:0}.min-h-5{min-height:calc(var(--spacing) * 5)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-4{width:calc(var(--spacing) * 4)}.w-\[7px\]{width:7px}.w-fit{width:fit-content}.w-full{width:100%}.max-w-75{max-width:calc(var(--spacing) * 75)}.max-w-105{max-width:calc(var(--spacing) * 105)}.max-w-190{max-width:calc(var(--spacing) * 190)}.max-w-\[60\%\]{max-width:60%}.max-w-\[82\%\]{max-width:82%}.max-w-\[min\(78\%\,64ch\)\]{max-width:min(78%,64ch)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.border-collapse{border-collapse:collapse}.rotate-90{rotate:90deg}.cursor-pointer{cursor:pointer}.resize{resize:both}.\[scrollbar-width\:none\]{scrollbar-width:none}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.flex-col{flex-direction:column}.items-center{align-items:center}.items-end{align-items:flex-end}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded-aai{border-radius:var(--radius-aai)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-none{--tw-border-style:none;border-style:none}.bg-transparent{background-color:#0000}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-7{padding:calc(var(--spacing) * 7)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-10{padding-inline:calc(var(--spacing) * 10)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.font-aai{font-family:var(--font-aai)}.font-aai-mono{font-family:var(--font-aai-mono)}.font-aai-serif{font-family:var(--font-aai-serif)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12\.5px\]{font-size:12.5px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[17px\]{font-size:17px}.text-\[22px\]{font-size:22px}.text-\[32px\]{font-size:32px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-\[1\.2\]{--tw-leading:1.2;line-height:1.2}.leading-\[1\.15\]{--tw-leading:1.15;line-height:1.15}.leading-\[22px\]{--tw-leading:22px;line-height:22px}.leading-\[23px\]{--tw-leading:23px;line-height:23px}.leading-\[130\%\]{--tw-leading:130%;line-height:130%}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.2px\]{--tw-tracking:-.2px;letter-spacing:-.2px}.tracking-\[1\.2px\]{--tw-tracking:1.2px;letter-spacing:1.2px}.tracking-\[1\.4px\]{--tw-tracking:1.4px;letter-spacing:1.4px}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-balance{text-wrap:balance}.wrap-break-word{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.uppercase{text-transform:uppercase}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.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{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.first\:mt-0:first-child{margin-top:0}.last\:mb-0:last-child{margin-bottom:0}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (width>=40rem){.sm\:px-16{padding-inline:calc(var(--spacing) * 16)}.sm\:py-14{padding-block:calc(var(--spacing) * 14)}}}@keyframes aai-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.82)}}@keyframes aai-bounce{0%,80%,to{opacity:.3;transform:scale(.8)}40%{opacity:1;transform:scale(1)}}@keyframes aai-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.tool-shimmer{-webkit-text-fill-color:transparent;background:linear-gradient(90deg,currentColor 25%,#0000 50%,currentColor 75%) 0 0/200% 100%;-webkit-background-clip:text;background-clip:text;animation:2s infinite aai-shimmer}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}