wizards 0.4.0 → 0.4.2

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 (124) hide show
  1. package/apps/runtime/dist/agents/studio-assistant.js +67 -20
  2. package/apps/runtime/dist/docs/dev/plugins/reference.md +7 -4
  3. package/apps/runtime/dist/docs/dev/plugins/reloading.md +3 -3
  4. package/apps/runtime/dist/docs/dev/plugins/runners.md +9 -12
  5. package/apps/runtime/dist/docs/dev/plugins/server.md +3 -1
  6. package/apps/runtime/dist/docs/dev/plugins/space.md +19 -1
  7. package/apps/runtime/dist/docs/dev/plugins/studio.md +43 -6
  8. package/apps/runtime/dist/docs/dev/plugins/styling.md +8 -1
  9. package/apps/runtime/dist/docs/user/space.md +4 -4
  10. package/apps/runtime/dist/docs/user/test-and-share.md +22 -58
  11. package/apps/runtime/dist/engine/steps.js +3 -2
  12. package/apps/runtime/dist/engine/template.js +14 -10
  13. package/apps/runtime/dist/film/project.js +15 -3
  14. package/apps/runtime/dist/plugins/loader.js +38 -2
  15. package/apps/runtime/dist/routes/studio.js +28 -1
  16. package/apps/runtime/dist/services/brand.js +61 -1
  17. package/apps/runtime/dist/services/projects.js +19 -10
  18. package/apps/runtime/dist/tools/plugin.js +11 -3
  19. package/apps/web/dist/assets/AboutDialog-CH1rQdia.js +1 -0
  20. package/apps/web/dist/assets/{ChangelogDialog-DynvQuuR.js → ChangelogDialog-78MQLHfA.js} +1 -1
  21. package/apps/web/dist/assets/ChatView-DLJfy69U.js +10 -0
  22. package/apps/web/dist/assets/EditorPage-BYrZokVk.js +3 -0
  23. package/apps/web/dist/assets/{FlowPreview-BZLnG7GV.js → FlowPreview-xIWPdOCV.js} +1 -1
  24. package/apps/web/dist/assets/{Harness-CNh3nbB_.js → Harness-CsDhNLSW.js} +2 -2
  25. package/apps/web/dist/assets/NewWizardChannels-JB3V6DCL.js +1 -0
  26. package/apps/web/dist/assets/NewWizardPage-Bkh-hjSe.js +7 -0
  27. package/apps/web/dist/assets/OnboardingPage-Diw1ILjC.js +1 -0
  28. package/apps/web/dist/assets/ProjectPage-FgoZDzPI.js +1 -0
  29. package/apps/web/dist/assets/PublicRunner-ClT6B7t5.js +1 -0
  30. package/apps/web/dist/assets/{ReadOnly-DTjv2Jzm.js → ReadOnly-DQPHmvS0.js} +1 -1
  31. package/apps/web/dist/assets/RunDrawer-DAwTEyjM.js +4 -0
  32. package/apps/web/dist/assets/{RunnerView-BPPmlv9z.js → RunnerView-B_tJroFM.js} +1 -1
  33. package/apps/web/dist/assets/SettingsPage-BsMN-XQs.js +1 -0
  34. package/apps/web/dist/assets/SetupPage-C7FuIpSt.js +1 -0
  35. package/apps/web/dist/assets/SharePage-CbFe83L9.js +1 -0
  36. package/apps/web/dist/assets/changelog-mYclku73.js +1 -0
  37. package/apps/web/dist/assets/{circle-alert-CVOH4wAv.js → circle-alert-DCBV7n5k.js} +1 -1
  38. package/apps/web/dist/assets/{esm-BfXdeWaI.js → esm-BhIeKBJY.js} +1 -1
  39. package/apps/web/dist/assets/index-CmxVazOf.css +1 -0
  40. package/apps/web/dist/assets/index-fflYi8P1.js +14 -0
  41. package/apps/web/dist/assets/{lock-DHBh62LA.js → lock-DlzTfwxP.js} +1 -1
  42. package/apps/web/dist/assets/{phone-Bt1cyWpY.js → phone-BFD815nc.js} +1 -1
  43. package/apps/web/dist/assets/{settings-menu-ace1vI3i.js → settings-menu-C5Y8SOhG.js} +1 -1
  44. package/apps/web/dist/assets/ui-DTuixH4y.js +134 -0
  45. package/apps/web/dist/assets/{upload-CCEq88l4.js → upload-BEf5-d6X.js} +1 -1
  46. package/apps/web/dist/index.html +4 -5
  47. package/apps/web/dist/mcp/flow.html +2 -2
  48. package/node_modules/@engenty-wizards/plugin-sdk/dist/index.d.ts +36 -2
  49. package/node_modules/@engenty-wizards/plugin-sdk/dist/studio.d.ts +44 -1
  50. package/node_modules/@engenty-wizards/shared/dist/feature-flags.d.ts +18 -0
  51. package/node_modules/@engenty-wizards/shared/dist/feature-flags.js +18 -0
  52. package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +22 -6
  53. package/node_modules/@engenty-wizards/shared/dist/projects.js +20 -0
  54. package/package.json +1 -1
  55. package/apps/web/dist/assets/AboutDialog-CPQiN7H9.js +0 -1
  56. package/apps/web/dist/assets/ChatView-CKo_9IZD.js +0 -10
  57. package/apps/web/dist/assets/EditorPage-CDIJXC4T.js +0 -3
  58. package/apps/web/dist/assets/NewWizardChannels-C1Ss9UMY.js +0 -1
  59. package/apps/web/dist/assets/NewWizardPage-2qLAbvDL.js +0 -7
  60. package/apps/web/dist/assets/OnboardingPage-C1FJwEsT.js +0 -1
  61. package/apps/web/dist/assets/ProjectPage-CGuLUuOs.js +0 -1
  62. package/apps/web/dist/assets/PublicRunner-BKw1lOW4.js +0 -1
  63. package/apps/web/dist/assets/RunDrawer-D1I5xqVf.js +0 -4
  64. package/apps/web/dist/assets/SettingsPage-zbomQfGy.js +0 -1
  65. package/apps/web/dist/assets/SetupPage-D3F7M6Pz.js +0 -1
  66. package/apps/web/dist/assets/SharePage-BY49IJgT.js +0 -1
  67. package/apps/web/dist/assets/changelog-DYZC2E6q.js +0 -1
  68. package/apps/web/dist/assets/index-B9xVkr2X.css +0 -1
  69. package/apps/web/dist/assets/index-BH0PYgov.js +0 -15
  70. package/apps/web/dist/assets/logo-C4V2_3Ar.js +0 -1
  71. package/apps/web/dist/assets/ui-D2SqIZeQ.js +0 -133
  72. package/modules/calls/dist/client.css +0 -3
  73. package/modules/calls/dist/client.js +0 -1
  74. package/modules/calls/engenty.plugin.json +0 -8
  75. package/modules/calls/migrations/0001_init.sql +0 -26
  76. package/modules/calls/package.json +0 -25
  77. package/modules/calls/src/openai.ts +0 -155
  78. package/modules/calls/src/plugin.ts +0 -407
  79. package/modules/calls/src/rules.ts +0 -226
  80. package/modules/calls/src/schema.ts +0 -39
  81. package/modules/calls/src/session.ts +0 -353
  82. package/modules/calls/src/store.ts +0 -124
  83. package/modules/calls/src/twilio.ts +0 -90
  84. package/modules/calls/tsconfig.json +0 -10
  85. package/modules/calls/ui/Settings.tsx +0 -137
  86. package/modules/calls/ui/app.ts +0 -50
  87. package/modules/calls/ui/messages.ts +0 -81
  88. package/modules/calls/ui/parts.tsx +0 -36
  89. package/modules/calls/ui/plugin.tsx +0 -15
  90. package/modules/sms/dist/client.css +0 -3
  91. package/modules/sms/dist/client.js +0 -1
  92. package/modules/sms/engenty.plugin.json +0 -8
  93. package/modules/sms/migrations/0001_init.sql +0 -26
  94. package/modules/sms/package.json +0 -24
  95. package/modules/sms/src/plugin.ts +0 -329
  96. package/modules/sms/src/schema.ts +0 -26
  97. package/modules/sms/src/store.ts +0 -140
  98. package/modules/sms/src/surface.ts +0 -70
  99. package/modules/sms/src/twilio.ts +0 -130
  100. package/modules/sms/tsconfig.json +0 -10
  101. package/modules/sms/ui/Settings.tsx +0 -113
  102. package/modules/sms/ui/Share.tsx +0 -60
  103. package/modules/sms/ui/app.ts +0 -51
  104. package/modules/sms/ui/messages.ts +0 -70
  105. package/modules/sms/ui/parts.tsx +0 -36
  106. package/modules/sms/ui/plugin.tsx +0 -20
  107. package/modules/whatsapp/dist/client.css +0 -3
  108. package/modules/whatsapp/dist/client.js +0 -1
  109. package/modules/whatsapp/engenty.plugin.json +0 -8
  110. package/modules/whatsapp/migrations/0001_init.sql +0 -30
  111. package/modules/whatsapp/package.json +0 -24
  112. package/modules/whatsapp/src/graph.ts +0 -271
  113. package/modules/whatsapp/src/inbound.ts +0 -143
  114. package/modules/whatsapp/src/plugin.ts +0 -374
  115. package/modules/whatsapp/src/schema.ts +0 -32
  116. package/modules/whatsapp/src/store.ts +0 -156
  117. package/modules/whatsapp/src/surface.ts +0 -127
  118. package/modules/whatsapp/tsconfig.json +0 -10
  119. package/modules/whatsapp/ui/Settings.tsx +0 -141
  120. package/modules/whatsapp/ui/Share.tsx +0 -60
  121. package/modules/whatsapp/ui/app.ts +0 -54
  122. package/modules/whatsapp/ui/messages.ts +0 -80
  123. package/modules/whatsapp/ui/parts.tsx +0 -36
  124. package/modules/whatsapp/ui/plugin.tsx +0 -20
@@ -1,3 +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-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-content:"";--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}}}@layer wizards-plugin{[data-plugin=calls] .pointer-events-none{pointer-events:none}[data-plugin=calls] .absolute{position:absolute}[data-plugin=calls] .fixed{position:fixed}[data-plugin=calls] .relative{position:relative}[data-plugin=calls] .-top-1\.5{top:-.375rem}[data-plugin=calls] .top-0\.5{top:.125rem}[data-plugin=calls] .top-1\/2{top:50%}[data-plugin=calls] .-right-1\.5{right:-.375rem}[data-plugin=calls] .right-2{right:.5rem}[data-plugin=calls] .right-3{right:.75rem}[data-plugin=calls] .bottom-0\.5{bottom:.125rem}[data-plugin=calls] .bottom-1{bottom:.25rem}[data-plugin=calls] .left-0{left:0}[data-plugin=calls] .left-1\/2{left:50%}[data-plugin=calls] .z-50{z-index:50}[data-plugin=calls] .m-auto{margin:auto}[data-plugin=calls] .-mx-1{margin-inline:-.25rem}[data-plugin=calls] .mx-auto{margin-inline:auto}[data-plugin=calls] .my-1\.5{margin-block:.375rem}[data-plugin=calls] .-mt-1\.5{margin-top:-.375rem}[data-plugin=calls] .-mt-2{margin-top:-.5rem}[data-plugin=calls] .mt-0\.5{margin-top:.125rem}[data-plugin=calls] .mt-2{margin-top:.5rem}[data-plugin=calls] .-mr-2{margin-right:-.5rem}[data-plugin=calls] .mr-0\.5{margin-right:.125rem}[data-plugin=calls] .mb-2{margin-bottom:.5rem}[data-plugin=calls] .mb-5{margin-bottom:1.25rem}[data-plugin=calls] .-ml-1\.5{margin-left:-.375rem}[data-plugin=calls] .ml-1{margin-left:.25rem}[data-plugin=calls] .flex{display:flex}[data-plugin=calls] .grid{display:grid}[data-plugin=calls] .hidden{display:none}[data-plugin=calls] .inline-block{display:inline-block}[data-plugin=calls] .inline-flex{display:inline-flex}[data-plugin=calls] .size-1{width:.25rem;height:.25rem}[data-plugin=calls] .size-1\.5{width:.375rem;height:.375rem}[data-plugin=calls] .size-3{width:.75rem;height:.75rem}[data-plugin=calls] .size-3\.5{width:.875rem;height:.875rem}[data-plugin=calls] .size-4{width:1rem;height:1rem}[data-plugin=calls] .size-5{width:1.25rem;height:1.25rem}[data-plugin=calls] .size-6{width:1.5rem;height:1.5rem}[data-plugin=calls] .size-7{width:1.75rem;height:1.75rem}[data-plugin=calls] .size-8{width:2rem;height:2rem}[data-plugin=calls] .size-9{width:2.25rem;height:2.25rem}[data-plugin=calls] .size-11{width:2.75rem;height:2.75rem}[data-plugin=calls] .size-16{width:4rem;height:4rem}[data-plugin=calls] .h-6{height:1.5rem}[data-plugin=calls] .h-8{height:2rem}[data-plugin=calls] .h-9{height:2.25rem}[data-plugin=calls] .h-10{height:2.5rem}[data-plugin=calls] .h-11{height:2.75rem}[data-plugin=calls] .h-12{height:3rem}[data-plugin=calls] .h-px{height:1px}[data-plugin=calls] .max-h-56{max-height:14rem}[data-plugin=calls] .max-h-\[200px\]{max-height:200px}[data-plugin=calls] .max-h-\[calc\(100dvh-32px\)\]{max-height:calc(100dvh - 32px)}[data-plugin=calls] .min-h-9{min-height:2.25rem}[data-plugin=calls] .w-5{width:1.25rem}[data-plugin=calls] .w-11{width:2.75rem}[data-plugin=calls] .w-14{width:3.5rem}[data-plugin=calls] .w-40{width:10rem}[data-plugin=calls] .w-72{width:18rem}[data-plugin=calls] .w-\[19rem\]{width:19rem}[data-plugin=calls] .w-\[calc\(100\%-32px\)\]{width:calc(100% - 32px)}[data-plugin=calls] .w-\[calc\(100\%-48px\)\]{width:calc(100% - 48px)}[data-plugin=calls] .w-full{width:100%}[data-plugin=calls] .w-px{width:1px}[data-plugin=calls] .max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}[data-plugin=calls] .max-w-\[calc\(100vw-16px\)\]{max-width:calc(100vw - 16px)}[data-plugin=calls] .max-w-full{max-width:100%}[data-plugin=calls] .min-w-0{min-width:0}[data-plugin=calls] .flex-1{flex:1}[data-plugin=calls] .shrink-0{flex-shrink:0}[data-plugin=calls] .-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}[data-plugin=calls] .translate-x-\[2px\]{--tw-translate-x:2px;translate:var(--tw-translate-x) var(--tw-translate-y)}[data-plugin=calls] .translate-x-\[22px\]{--tw-translate-x:22px;translate:var(--tw-translate-x) var(--tw-translate-y)}[data-plugin=calls] .-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}[data-plugin=calls] .rotate-180{rotate:180deg}[data-plugin=calls] .transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}[data-plugin=calls] .animate-spin{animation:1s linear infinite spin}[data-plugin=calls] .cursor-pointer{cursor:pointer}[data-plugin=calls] .touch-none{touch-action:none}[data-plugin=calls] .resize{resize:both}[data-plugin=calls] .resize-none{resize:none}[data-plugin=calls] .\[scrollbar-width\:none\]{scrollbar-width:none}[data-plugin=calls] .appearance-none{appearance:none}[data-plugin=calls] .grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}[data-plugin=calls] .flex-col{flex-direction:column}[data-plugin=calls] .flex-wrap{flex-wrap:wrap}[data-plugin=calls] .place-items-center{place-items:center}[data-plugin=calls] .items-center{align-items:center}[data-plugin=calls] .items-end{align-items:flex-end}[data-plugin=calls] .items-start{align-items:flex-start}[data-plugin=calls] .justify-between{justify-content:space-between}[data-plugin=calls] .justify-center{justify-content:center}[data-plugin=calls] .gap-0\.5{gap:.125rem}[data-plugin=calls] .gap-1{gap:.25rem}[data-plugin=calls] .gap-1\.5{gap:.375rem}[data-plugin=calls] .gap-2{gap:.5rem}[data-plugin=calls] .gap-2\.5{gap:.625rem}[data-plugin=calls] .gap-3{gap:.75rem}[data-plugin=calls] .gap-4{gap:1rem}[data-plugin=calls] .gap-y-0\.5{row-gap:.125rem}[data-plugin=calls] .self-stretch{align-self:stretch}[data-plugin=calls] .truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-plugin=calls] .overflow-visible{overflow:visible}[data-plugin=calls] .overflow-x-auto{overflow-x:auto}[data-plugin=calls] .overflow-y-auto{overflow-y:auto}[data-plugin=calls] .overscroll-contain{overscroll-behavior:contain}[data-plugin=calls] .rounded-2xl{border-radius:calc(var(--radius) * 2)}[data-plugin=calls] .rounded-\[1\.375rem\]{border-radius:1.375rem}[data-plugin=calls] .rounded-full{border-radius:2147483647px}[data-plugin=calls] .rounded-lg{border-radius:var(--radius)}[data-plugin=calls] .rounded-md{border-radius:calc(var(--radius) * .75)}[data-plugin=calls] .rounded-xl{border-radius:calc(var(--radius) * 1.5)}[data-plugin=calls] .border{border-style:var(--tw-border-style);border-width:1px}[data-plugin=calls] .border-t{border-top-style:var(--tw-border-style);border-top-width:1px}[data-plugin=calls] .border-border{border-color:var(--border)}[data-plugin=calls] .border-border-soft{border-color:var(--border-soft)}[data-plugin=calls] .border-ember{border-color:var(--ember-mark)}[data-plugin=calls] .border-focus{border-color:var(--focus-line)}[data-plugin=calls] .border-input{border-color:var(--input)}[data-plugin=calls] .bg-amber-tint{background-color:var(--amber-tint)}[data-plugin=calls] .bg-border-soft{background-color:var(--border-soft)}[data-plugin=calls] .bg-card{background-color:var(--card)}[data-plugin=calls] .bg-ember{background-color:var(--ember-mark)}[data-plugin=calls] .bg-ember-tint{background-color:var(--ember-tint)}[data-plugin=calls] .bg-ink{background-color:var(--ink)}[data-plugin=calls] .bg-moss{background-color:var(--moss)}[data-plugin=calls] .bg-moss-tint{background-color:var(--moss-tint)}[data-plugin=calls] .bg-paper-2{background-color:var(--paper-2)}[data-plugin=calls] .bg-paper-3{background-color:var(--paper-3)}[data-plugin=calls] .bg-primary{background-color:var(--primary)}[data-plugin=calls] .bg-rose-tint{background-color:var(--rose-tint)}[data-plugin=calls] .bg-transparent{background-color:#0000}[data-plugin=calls] .bg-white{background-color:#fff}[data-plugin=calls] .bg-linear-to-l{--tw-gradient-position:to left}@supports (background-image:linear-gradient(in lab, red, red)){[data-plugin=calls] .bg-linear-to-l{--tw-gradient-position:to left in oklab}}[data-plugin=calls] .bg-linear-to-l{background-image:linear-gradient(var(--tw-gradient-stops))}[data-plugin=calls] .bg-linear-to-r{--tw-gradient-position:to right}@supports (background-image:linear-gradient(in lab, red, red)){[data-plugin=calls] .bg-linear-to-r{--tw-gradient-position:to right in oklab}}[data-plugin=calls] .bg-linear-to-r{background-image:linear-gradient(var(--tw-gradient-stops))}[data-plugin=calls] .from-transparent{--tw-gradient-from:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}[data-plugin=calls] .from-50\%{--tw-gradient-from-position:50%}[data-plugin=calls] .to-ember-tint{--tw-gradient-to:var(--ember-tint);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}[data-plugin=calls] .to-50\%{--tw-gradient-to-position:50%}[data-plugin=calls] .fill-current{fill:currentColor}[data-plugin=calls] .object-cover{object-fit:cover}[data-plugin=calls] .p-0{padding:0}[data-plugin=calls] .p-0\.5{padding:.125rem}[data-plugin=calls] .p-1{padding:.25rem}[data-plugin=calls] .p-1\.5{padding:.375rem}[data-plugin=calls] .p-3{padding:.75rem}[data-plugin=calls] .p-5{padding:1.25rem}[data-plugin=calls] .px-1{padding-inline:.25rem}[data-plugin=calls] .px-2{padding-inline:.5rem}[data-plugin=calls] .px-2\.5{padding-inline:.625rem}[data-plugin=calls] .px-3{padding-inline:.75rem}[data-plugin=calls] .px-3\.5{padding-inline:.875rem}[data-plugin=calls] .px-4{padding-inline:1rem}[data-plugin=calls] .px-6{padding-inline:1.5rem}[data-plugin=calls] .py-1{padding-block:.25rem}[data-plugin=calls] .py-1\.5{padding-block:.375rem}[data-plugin=calls] .py-2{padding-block:.5rem}[data-plugin=calls] .py-2\.5{padding-block:.625rem}[data-plugin=calls] .py-16{padding-block:4rem}[data-plugin=calls] .pt-1\.5{padding-top:.375rem}[data-plugin=calls] .pt-2{padding-top:.5rem}[data-plugin=calls] .pr-1{padding-right:.25rem}[data-plugin=calls] .pr-9{padding-right:2.25rem}[data-plugin=calls] .pb-1{padding-bottom:.25rem}[data-plugin=calls] .pl-2{padding-left:.5rem}[data-plugin=calls] .pl-2\.5{padding-left:.625rem}[data-plugin=calls] .text-center{text-align:center}[data-plugin=calls] .text-left{text-align:left}[data-plugin=calls] .font-display{font-family:var(--f-display)}[data-plugin=calls] .font-mono{font-family:var(--f-mono)}[data-plugin=calls] .text-lg{font-size:1.125rem;line-height:var(--tw-leading,calc(1.75 / 1.125))}[data-plugin=calls] .text-sm{font-size:.875rem;line-height:var(--tw-leading,calc(1.25 / .875))}[data-plugin=calls] .text-xl{font-size:1.25rem;line-height:var(--tw-leading,calc(1.75 / 1.25))}[data-plugin=calls] .text-\[0\.75rem\]{font-size:.75rem}[data-plugin=calls] .text-\[0\.875rem\]{font-size:.875rem}[data-plugin=calls] .text-\[0\.6875rem\]{font-size:.6875rem}[data-plugin=calls] .text-\[0\.8125rem\]{font-size:.8125rem}[data-plugin=calls] .text-\[0\.9375rem\]{font-size:.9375rem}[data-plugin=calls] .text-\[14px\]{font-size:14px}[data-plugin=calls] .leading-5{--tw-leading:calc(.25rem * 5);line-height:1.25rem}[data-plugin=calls] .leading-\[1\.5\]{--tw-leading:1.5;line-height:1.5}[data-plugin=calls] .leading-tight{--tw-leading:1.25;line-height:1.25}[data-plugin=calls] .font-medium{--tw-font-weight:500;font-weight:500}[data-plugin=calls] .font-semibold{--tw-font-weight:600;font-weight:600}[data-plugin=calls] .tracking-wide{--tw-tracking:.025em;letter-spacing:.025em}[data-plugin=calls] .whitespace-nowrap{white-space:nowrap}[data-plugin=calls] .text-ember{color:var(--ember-mark)}[data-plugin=calls] .text-ember-strong{color:var(--ember-strong-mark)}[data-plugin=calls] .text-ink{color:var(--ink)}[data-plugin=calls] .text-ink-2{color:var(--ink-2)}[data-plugin=calls] .text-ink-3{color:var(--ink-3)}[data-plugin=calls] .text-ink-4{color:var(--ink-4)}[data-plugin=calls] .text-moss{color:var(--moss)}[data-plugin=calls] .text-paper{color:var(--paper)}[data-plugin=calls] .text-primary-foreground{color:var(--primary-foreground)}[data-plugin=calls] .text-rose{color:var(--rose)}[data-plugin=calls] .capitalize{text-transform:capitalize}[data-plugin=calls] .uppercase{text-transform:uppercase}[data-plugin=calls] .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,)}[data-plugin=calls] .line-through{text-decoration-line:line-through}[data-plugin=calls] .underline{text-decoration-line:underline}[data-plugin=calls] .underline-offset-2{text-underline-offset:2px}[data-plugin=calls] .opacity-0{opacity:0}[data-plugin=calls] .opacity-35{opacity:.35}[data-plugin=calls] .shadow-\[0_1px_0_oklch\(0\%_0_0\/0\.08\)\]{--tw-shadow:0 1px 0 var(--tw-shadow-color,oklch(0% 0 0/.08));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=calls] .shadow-\[inset_0_1px_0_oklch\(0\%_0_0\/0\.02\)\]{--tw-shadow:inset 0 1px 0 var(--tw-shadow-color,oklch(0% 0 0/.02));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=calls] .shadow-overlay{--tw-shadow:var(--shadow-ember-overlay);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=calls] .shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=calls] .shadow-soft{--tw-shadow:var(--shadow-ember-soft);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=calls] .ring-1{--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)}[data-plugin=calls] .ring-4{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=calls] .ring-border{--tw-ring-color:var(--border)}[data-plugin=calls] .ring-border-soft{--tw-ring-color:var(--border-soft)}[data-plugin=calls] .ring-focus-glow{--tw-ring-color:var(--focus-glow)}[data-plugin=calls] .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,cubic-bezier(.4, 0, .2, 1));transition-duration:var(--tw-duration,.15s)}[data-plugin=calls] .transition-\[background\,filter\,color\,transform\]{transition-property:background,filter,color,transform;transition-timing-function:var(--tw-ease,cubic-bezier(.4, 0, .2, 1));transition-duration:var(--tw-duration,.15s)}[data-plugin=calls] .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,cubic-bezier(.4, 0, .2, 1));transition-duration:var(--tw-duration,.15s)}[data-plugin=calls] .transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,cubic-bezier(.4, 0, .2, 1));transition-duration:var(--tw-duration,.15s)}[data-plugin=calls] .duration-150{--tw-duration:.15s;transition-duration:.15s}[data-plugin=calls] .duration-200{--tw-duration:.2s;transition-duration:.2s}[data-plugin=calls] .ease-out{--tw-ease:cubic-bezier(0, 0, .2, 1);transition-timing-function:cubic-bezier(0,0,.2,1)}[data-plugin=calls] .outline-none{--tw-outline-style:none;outline-style:none}[data-plugin=calls] .select-all{-webkit-user-select:all;user-select:all}[data-plugin=calls] .select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){[data-plugin=calls] .group-hover\:scale-110:is(:where(.group):hover *){--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x) var(--tw-scale-y)}[data-plugin=calls] .group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}[data-plugin=calls] .placeholder\:truncate::placeholder{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-plugin=calls] .placeholder\:text-ink-4::placeholder{color:var(--ink-4)}[data-plugin=calls] .backdrop\:bg-\[oklch\(20\%_0\.01_60\/0\.28\)\]::backdrop{background-color:oklch(20% .01 60/.28)}[data-plugin=calls] .backdrop\:backdrop-blur-\[2px\]::backdrop{--tw-backdrop-blur:blur(2px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}[data-plugin=calls] .before\:absolute:before{content:var(--tw-content);position:absolute}[data-plugin=calls] .before\:-inset-x-1:before{content:var(--tw-content);inset-inline:-.25rem}[data-plugin=calls] .before\:-inset-y-2\.5:before{content:var(--tw-content);inset-block:-.625rem}[data-plugin=calls] .before\:content-\[\'\'\]:before{--tw-content:"";content:var(--tw-content)}[data-plugin=calls] .focus-within\:ring-focus:focus-within{--tw-ring-color:var(--focus-line)}@media (hover:hover){[data-plugin=calls] .hover\:border-ink-4:hover{border-color:var(--ink-4)}[data-plugin=calls] .hover\:bg-accent:hover{background-color:var(--accent)}[data-plugin=calls] .hover\:bg-card:hover{background-color:var(--card)}[data-plugin=calls] .hover\:bg-paper-2:hover{background-color:var(--paper-2)}[data-plugin=calls] .hover\:bg-paper-3:hover{background-color:var(--paper-3)}[data-plugin=calls] .hover\:bg-rose-tint:hover{background-color:var(--rose-tint)}[data-plugin=calls] .hover\:text-ink:hover{color:var(--ink)}[data-plugin=calls] .hover\:text-ink-2:hover{color:var(--ink-2)}[data-plugin=calls] .hover\:text-rose:hover{color:var(--rose)}[data-plugin=calls] .hover\:brightness-\[1\.06\]:hover{--tw-brightness:brightness(1.06);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,)}}[data-plugin=calls] .focus\:border-focus:focus{border-color:var(--focus-line)}[data-plugin=calls] .focus\:ring-4:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=calls] .focus\:ring-focus-glow:focus{--tw-ring-color:var(--focus-glow)}[data-plugin=calls] .focus-visible\:border-focus:focus-visible{border-color:var(--focus-line)}[data-plugin=calls] .focus-visible\:opacity-100:focus-visible{opacity:1}[data-plugin=calls] .focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=calls] .focus-visible\:ring-4:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=calls] .focus-visible\:ring-focus:focus-visible{--tw-ring-color:var(--focus-line)}[data-plugin=calls] .focus-visible\:ring-focus-glow:focus-visible{--tw-ring-color:var(--focus-glow)}[data-plugin=calls] .active\:scale-\[0\.98\]:active{scale:.98}[data-plugin=calls] .active\:brightness-95:active{--tw-brightness:brightness(95%);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,)}[data-plugin=calls] .disabled\:pointer-events-none:disabled{pointer-events:none}[data-plugin=calls] .disabled\:line-through:disabled{text-decoration-line:line-through}[data-plugin=calls] .disabled\:opacity-40:disabled{opacity:.4}[data-plugin=calls] .disabled\:opacity-50:disabled{opacity:.5}[data-plugin=calls] .disabled\:opacity-60:disabled{opacity:.6}@media (prefers-reduced-motion:reduce){[data-plugin=calls] .motion-reduce\:transition-none{transition-property:none}}@media not all and (width>=48rem){[data-plugin=calls] .max-md\:hidden{display:none}}@media not all and (width>=40rem){[data-plugin=calls] .max-sm\:m-0{margin:0}[data-plugin=calls] .max-sm\:h-dvh{height:100dvh}[data-plugin=calls] .max-sm\:max-h-none{max-height:none}[data-plugin=calls] .max-sm\:w-full{width:100%}[data-plugin=calls] .max-sm\:max-w-none{max-width:none}[data-plugin=calls] .max-sm\:rounded-none{border-radius:0}[data-plugin=calls] .max-sm\:pt-\[env\(safe-area-inset-top\)\]{padding-top:env(safe-area-inset-top)}[data-plugin=calls] .max-sm\:pb-\[env\(safe-area-inset-bottom\)\]{padding-bottom:env(safe-area-inset-bottom)}}@media (width>=40rem){[data-plugin=calls] .sm\:h-\[min\(calc\(100dvh-32px\)\,56rem\)\]{height:min(100dvh - 32px,56rem)}[data-plugin=calls] .sm\:max-w-2xl{max-width:42rem}[data-plugin=calls] .sm\:max-w-4xl{max-width:56rem}[data-plugin=calls] .sm\:max-w-md{max-width:28rem}[data-plugin=calls] .sm\:p-7{padding:1.75rem}}@media (width>=48rem){[data-plugin=calls] .md\:hidden{display:none}}@media (pointer:coarse){[data-plugin=calls] .coarse\:size-10{width:2.5rem;height:2.5rem}[data-plugin=calls] .coarse\:size-11{width:2.75rem;height:2.75rem}[data-plugin=calls] .coarse\:h-9{height:2.25rem}[data-plugin=calls] .coarse\:h-11{height:2.75rem}[data-plugin=calls] .coarse\:min-h-11{min-height:2.75rem}[data-plugin=calls] .coarse\:px-4{padding-inline:1rem}[data-plugin=calls] .coarse\:py-3{padding-block:.75rem}}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@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}@keyframes spin{to{transform:rotate(360deg)}}
3
- /*$vite$:1*/
@@ -1 +0,0 @@
1
- var __wizardsPlugin_calls=(function(e,t,n,r,i){var a=e=>e?.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase();function o(e,t,n=[]){if(t==null)throw Error(`[lucide]: iconNode is required when icon name is used`);return{name:a(e),size:24,node:t,...n.length>0?{aliases:n}:{}}}var s=e=>{let t=``,n=!1;for(let r of e){if(r===`-`||r===`_`||r<=` `){n=t.length>0;continue}t.length===0?t+=r.toLowerCase():t+=n?r.toUpperCase():r,n=!1}return t},c=e=>{let t=s(e);return t.charAt(0).toUpperCase()+t.slice(1)},l=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),u={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":2,"stroke-linecap":`round`,"stroke-linejoin":`round`};function d(e){return e!=null}function f(e,t={}){let n=t.attributeNames??{},r=e=>n[e]??e,i=e.size??e.width??u.width,a=e.size??e.height??u.height,o=e.aliases?.filter(e=>typeof e==`string`&&e.trim()!==``).map(e=>`lucide-${e}`)??[],s=[...e.name?[`lucide-${e.name}`]:[],...o],c=t.className?.split(` `).filter(Boolean)??[],f=t.includeDefaultClasses===!1?l(...c):l(`lucide`,...s,...c),p=t.absoluteStrokeWidth?Number(t.strokeWidth??u[`stroke-width`])*Number(e.size??e.width??u.width)/Number(t.size??t.width??u.width):t.strokeWidth??u[`stroke-width`];return[`svg`,{...Object.entries(u).reduce((e,[t,n])=>(e[r(t)]=n,e),{}),...`color`in t&&t.color&&{[r(`stroke`)]:t.color},...`size`in t&&d(t.size)&&{[r(`width`)]:t.size,[r(`height`)]:t.size},...`width`in t&&d(t.width)&&{[r(`width`)]:t.width},...`height`in t&&d(t.height)&&{[r(`height`)]:t.height},[r(`stroke-width`)]:p,...f&&{[r(`class`)]:f},[r(`viewBox`)]:`0 0 ${i} ${a}`,...t.hasA11yProp===!1?{[r(`aria-hidden`)]:`true`}:{},...`attributes`in t&&t.attributes},e.node.map(e=>{let[n,i,a]=e,o=t.nonScalingStroke?{[r(`vector-effect`)]:`non-scaling-stroke`,...i}:i;return a?[n,o,a]:[n,o]})]}function p(e,t={}){return f(e,{...t,attributeNames:{...t.attributeNames,class:`className`,"stroke-width":`strokeWidth`,"stroke-linecap":`strokeLinecap`,"stroke-linejoin":`strokeLinejoin`,"vector-effect":`vectorEffect`}})}var m=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},h=(0,t.createContext)({}),g=()=>(0,t.useContext)(h),_=(0,t.forwardRef)(({color:e,size:n,width:r,height:i,strokeWidth:a,absoluteStrokeWidth:o,nonScalingStroke:s,className:c=``,children:u,iconNode:d=[],icon:f={node:d,aliases:[],size:24},...h},_)=>{let{size:v=24,strokeWidth:y=2,absoluteStrokeWidth:b=!1,nonScalingStroke:x=!1,color:S=`currentColor`,className:C=``}=g()??{},w=!!u||m(h),[T,E,D=[]]=p(f,{color:e??S,width:r??n??v,height:i??n??v,strokeWidth:a??y,absoluteStrokeWidth:o??b,nonScalingStroke:s??x,className:l(C,c),hasA11yProp:w,attributes:h});return(0,t.createElement)(T,{ref:_,...E},[...D.map(([e,n])=>(0,t.createElement)(e,n)),...Array.isArray(u)?u:[u]])});function v(e,n=[],r=[]){let i=typeof e==`string`?o(e,n,r):e,a=(0,t.forwardRef)(({className:e,...n},r)=>(0,t.createElement)(_,{ref:r,icon:i,className:e,...n}));return i.name&&(a.displayName=c(i.name)),a}var y={name:`check`,size:24,node:[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]};y.node;var b=v(y),x={name:`copy`,size:24,node:[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]};x.node;var S=v(x),C={name:`phone-call`,size:24,node:[[`path`,{d:`M13 2a9 9 0 0 1 9 9`,key:`1itnx2`}],[`path`,{d:`M13 6a5 5 0 0 1 5 5`,key:`11nki7`}],[`path`,{d:`M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384`,key:`9njp5v`}]]};C.node;var w=v(C),T={de:{title:`Anrufe`,intro:`Wizards laufen als Gespräch am Telefon: ein WhatsApp-Anruf auf die Business-Nummer oder ein Anruf auf eine Twilio-Nummer. Twilio trägt den Anruf, das Sprachmodell des OpenAI-Kontos (Einstellungen → Modelle) spricht; was eine Stimme nicht kann, kommt als Link per SMS.`,twilioSid:`Twilio Account SID`,twilioSidHint:`Aus der Twilio-Konsole, beginnt mit AC.`,twilioToken:`Twilio Auth Token`,twilioTokenHint:`Prüft auch jede Anfrage von Twilio auf ihre Signatur.`,kept:`Ist hinterlegt. Leer lassen, um ihn zu behalten.`,smsFrom:`SMS-Nummer`,smsFromHint:`Eine SMS-fähige Twilio-Nummer, von der die Links kommen, mit Ländervorwahl. Ohne sie gibt es keine Links.`,openaiProject:`OpenAI Project ID`,openaiProjectHint:`Das Projekt, dessen API Key unter Modelle hinterlegt ist: proj_…`,openaiSecret:`OpenAI Webhook Secret`,openaiSecretHint:`Aus dem Webhook im OpenAI-Dashboard für das Ereignis realtime.call.incoming: whsec_…`,region:`Region`,regionEu:`EU`,regionUs:`USA`,save:`Speichern`,saved:`Gespeichert.`,disconnect:`Trennen`,setup:`Eintragen`,copy:`Kopieren`,copied:`Kopiert`,voiceWebhook:`Twilio: Voice-Webhook`,voiceWebhookHint:`Bei der SIP-Domain (WhatsApp) und bei der Telefonnummer unter „A call comes in“, als Webhook mit HTTP POST.`,openaiWebhook:`OpenAI: Webhook`,openaiWebhookHint:`Im OpenAI-Dashboard als Webhook für realtime.call.incoming.`,sipUri:`Wohin Twilio den Anruf gibt`,meta:`Meta: SIP auf der WhatsApp-Nummer`,metaHint:`In den Calling-Einstellungen der WhatsApp-Nummer: SIP einschalten, als Server die Twilio-SIP-Domain (…sip.twilio.com) mit Port 5061. Die SIP-Domain in Twilio erlaubt Metas Adressen in ihrer Zugriffsliste.`,error_no_token:`Es braucht den Twilio Auth Token.`,error_no_secret:`Es braucht das OpenAI Webhook Secret.`,error_other:`{message}`},en:{title:`Calls`,intro:`Wizards run as a conversation on the phone: a WhatsApp call to the business number or a call to a Twilio number. Twilio carries the call, the speech model of the OpenAI account (Settings → Models) speaks; what a voice cannot do arrives as a link by text.`,twilioSid:`Twilio Account SID`,twilioSidHint:`From the Twilio console, starts with AC.`,twilioToken:`Twilio auth token`,twilioTokenHint:`Also checks every request from Twilio for its signature.`,kept:`Is set. Leave empty to keep it.`,smsFrom:`Texting number`,smsFromHint:`A Twilio number that can text, the links come from it, with the country code. Without it there are no links.`,openaiProject:`OpenAI project ID`,openaiProjectHint:`The project whose API key is set under Models: proj_…`,openaiSecret:`OpenAI webhook secret`,openaiSecretHint:`From the webhook in the OpenAI dashboard for the event realtime.call.incoming: whsec_…`,region:`Region`,regionEu:`EU`,regionUs:`US`,save:`Save`,saved:`Saved.`,disconnect:`Disconnect`,setup:`Enter`,copy:`Copy`,copied:`Copied`,voiceWebhook:`Twilio: voice webhook`,voiceWebhookHint:`On the SIP domain (WhatsApp) and on the phone number under “A call comes in”, as a webhook with HTTP POST.`,openaiWebhook:`OpenAI: webhook`,openaiWebhookHint:`In the OpenAI dashboard as the webhook for realtime.call.incoming.`,sipUri:`Where Twilio hands the call`,meta:`Meta: SIP on the WhatsApp number`,metaHint:`In the WhatsApp number's calling settings: switch SIP on, with the Twilio SIP domain (…sip.twilio.com) as the server on port 5061. The SIP domain in Twilio allows Meta's addresses in its access list.`,error_no_token:`Twilio's auth token is needed.`,error_no_secret:`OpenAI's webhook secret is needed.`,error_other:`{message}`}},E=null,D=null;function O(e){E=e,D=e.i18n.register(T)}function k(){if(!E)throw Error(`The calls plugin is not loaded.`);return E}var A=(e,t)=>D?.(e,t)??e,j=()=>k().api,M=`calls`;function N(e){let t=e?.body,n=t?.code,r=t?.error??(e instanceof Error?e.message:String(e));return n&&`error_${n}`in T.de?A(`error_${n}`,{message:r}):A(`error_other`,{message:r})}function P({text:e}){let[r,a]=(0,t.useState)(!1);return(0,i.jsx)(n.IconButton,{label:A(r?`copied`:`copy`),className:`size-8`,onClick:()=>{navigator.clipboard.writeText(e).then(()=>{a(!0),setTimeout(()=>a(!1),1500)})},children:r?(0,i.jsx)(b,{className:`size-4`}):(0,i.jsx)(S,{className:`size-4`})})}function F({label:e,value:t}){return(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,i.jsx)(`div`,{className:`text-[0.8125rem] text-ink-3`,children:e}),(0,i.jsx)(`div`,{className:`select-all truncate font-mono text-[0.8125rem]`,children:t})]}),(0,i.jsx)(P,{text:t})]})}function I(){let e=(0,r.useQueryClient)(),a=(0,r.useQuery)({queryKey:[M,`account`],queryFn:()=>j().get(`/account`)}),[o,s]=(0,t.useState)({twilioSid:``,twilioToken:``,smsFrom:``,openaiProject:``,openaiWebhookSecret:``,region:`eu`});(0,t.useEffect)(()=>{a.data&&s(e=>({...e,twilioSid:a.data.twilioSid,smsFrom:a.data.smsFrom,openaiProject:a.data.openaiProject,region:a.data.region}))},[a.data]);let c=()=>e.invalidateQueries({queryKey:[M]}),l=(0,r.useMutation)({mutationFn:()=>j().put(`/account`,{twilioSid:o.twilioSid,twilioToken:o.twilioToken||void 0,smsFrom:o.smsFrom||null,openaiProject:o.openaiProject,openaiWebhookSecret:o.openaiWebhookSecret||void 0,region:o.region}),onSuccess:async()=>{s(e=>({...e,twilioToken:``,openaiWebhookSecret:``})),await c()}}),u=(0,r.useMutation)({mutationFn:()=>j().del(`/account`),onSuccess:c}),d=e=>t=>s(n=>({...n,[e]:t.target.value})),f=a.data;return(0,i.jsxs)(`section`,{className:`flex flex-col gap-2.5`,children:[(0,i.jsx)(`h2`,{className:`px-1 font-display font-semibold text-lg leading-tight`,children:A(`title`)}),(0,i.jsxs)(n.Card,{className:`flex flex-col gap-4 p-5 text-[0.875rem]`,children:[(0,i.jsx)(`p`,{className:`text-[0.8125rem] text-ink-3`,children:A(`intro`)}),a.isLoading?(0,i.jsx)(n.Spinner,{className:`mx-auto`}):null,(0,i.jsxs)(`div`,{children:[(0,i.jsx)(n.Label,{hint:A(`twilioSidHint`),children:A(`twilioSid`)}),(0,i.jsx)(n.Input,{value:o.twilioSid,onChange:d(`twilioSid`),autoComplete:`off`})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(n.Label,{hint:f?.hasToken?A(`kept`):A(`twilioTokenHint`),children:A(`twilioToken`)}),(0,i.jsx)(n.Input,{type:`password`,value:o.twilioToken,onChange:d(`twilioToken`),placeholder:f?.hasToken?`••••••••`:``,autoComplete:`new-password`})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(n.Label,{hint:A(`smsFromHint`),children:A(`smsFrom`)}),(0,i.jsx)(n.Input,{value:o.smsFrom,onChange:d(`smsFrom`),inputMode:`tel`})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(n.Label,{hint:A(`openaiProjectHint`),children:A(`openaiProject`)}),(0,i.jsx)(n.Input,{value:o.openaiProject,onChange:d(`openaiProject`),autoComplete:`off`})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(n.Label,{hint:f?.hasSecret?A(`kept`):A(`openaiSecretHint`),children:A(`openaiSecret`)}),(0,i.jsx)(n.Input,{type:`password`,value:o.openaiWebhookSecret,onChange:d(`openaiWebhookSecret`),placeholder:f?.hasSecret?`••••••••`:``,autoComplete:`new-password`})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(n.Label,{children:A(`region`)}),(0,i.jsx)(n.Select,{className:`w-40`,value:o.region,onChange:e=>s(t=>({...t,region:e})),options:[{value:`eu`,label:A(`regionEu`)},{value:`us`,label:A(`regionUs`)}]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,i.jsx)(n.Button,{onClick:()=>l.mutate(),busy:l.isPending,children:A(`save`)}),f?.connected?(0,i.jsx)(n.Button,{variant:`ghost`,onClick:()=>u.mutate(),busy:u.isPending,children:A(`disconnect`)}):null,l.isSuccess?(0,i.jsx)(`span`,{className:`text-[0.8125rem] text-ink-3`,children:A(`saved`)}):null]}),l.error?(0,i.jsx)(`p`,{className:`text-[0.8125rem] text-rose`,children:N(l.error)}):null]}),f?.connected?(0,i.jsxs)(n.Card,{className:`flex flex-col gap-4 p-5 text-[0.875rem]`,children:[(0,i.jsx)(`div`,{className:`font-medium`,children:A(`setup`)}),(0,i.jsx)(F,{label:A(`voiceWebhook`),value:f.voiceWebhook}),(0,i.jsx)(`p`,{className:`-mt-2 text-[0.8125rem] text-ink-3`,children:A(`voiceWebhookHint`)}),(0,i.jsx)(F,{label:A(`openaiWebhook`),value:f.openaiWebhook}),(0,i.jsx)(`p`,{className:`-mt-2 text-[0.8125rem] text-ink-3`,children:A(`openaiWebhookHint`)}),f.sipUri?(0,i.jsx)(F,{label:A(`sipUri`),value:f.sipUri}):null,(0,i.jsx)(`div`,{className:`font-medium`,children:A(`meta`)}),(0,i.jsx)(`p`,{className:`-mt-2 text-[0.8125rem] text-ink-3`,children:A(`metaHint`)})]}):null]})}return(0,e.defineStudioPlugin)(e=>{O(e),e.registerSettingsSection({id:`calls`,label:()=>A(`title`),icon:w,component:I})})})(__WIZARDS_STUDIO__.sdk,__WIZARDS_STUDIO__.react,__WIZARDS_STUDIO__.ui,__WIZARDS_STUDIO__.query,__WIZARDS_STUDIO__.jsx);
@@ -1,8 +0,0 @@
1
- {
2
- "id": "calls",
3
- "name": "Calls",
4
- "version": "0.1.0",
5
- "description": "Runs wizards in a live voice call: a WhatsApp call to the tenant's business number or a phone call to its Twilio number is handed to the tenant's realtime speech model over SIP (Twilio carries the call, OpenAI speaks), and the wizard is filled from what the person says. What a voice cannot take (a photo, a signature) is texted as a link. Talks to Twilio and OpenAI with the tenant's own accounts; keeps the calls in the tenant's database.",
6
- "kind": "module",
7
- "provides": ["runner.call"]
8
- }
@@ -1,26 +0,0 @@
1
- -- The tenant's Twilio account and OpenAI project for calls. One row. Dates are milliseconds.
2
- CREATE TABLE calls_account (
3
- id INTEGER PRIMARY KEY CHECK (id = 1),
4
- twilio_sid TEXT NOT NULL,
5
- twilio_token TEXT NOT NULL,
6
- openai_project TEXT NOT NULL,
7
- openai_webhook_secret TEXT NOT NULL,
8
- region TEXT NOT NULL DEFAULT 'eu',
9
- sms_from TEXT,
10
- updated_at INTEGER NOT NULL
11
- );
12
-
13
- -- One row per call: who called, over which door, which run it drives, how it went.
14
- CREATE TABLE calls_call (
15
- token TEXT PRIMARY KEY,
16
- caller TEXT NOT NULL,
17
- channel TEXT NOT NULL,
18
- payload TEXT,
19
- twilio_call_sid TEXT,
20
- openai_call_id TEXT,
21
- run_id TEXT,
22
- status TEXT NOT NULL DEFAULT 'ringing',
23
- created_at INTEGER NOT NULL,
24
- updated_at INTEGER NOT NULL
25
- );
26
- CREATE INDEX calls_call_run ON calls_call (run_id);
@@ -1,25 +0,0 @@
1
- {
2
- "name": "@engenty-wizards/module-calls",
3
- "version": "0.1.0",
4
- "license": "FSL-1.1-MIT",
5
- "private": true,
6
- "type": "module",
7
- "scripts": {
8
- "build": "node ../../scripts/build-plugin.mjs .",
9
- "dev": "node ../../scripts/build-plugin.mjs . --watch",
10
- "typecheck": "tsc -p tsconfig.json --noEmit"
11
- },
12
- "devDependencies": {
13
- "@engenty-wizards/plugin-sdk": "workspace:*",
14
- "@engenty-wizards/web": "workspace:*",
15
- "@tanstack/react-query": "^5.104.0",
16
- "@types/node": "^26.6.4",
17
- "@types/react": "^19.3.0",
18
- "drizzle-orm": "^0.45.3",
19
- "lucide-react": "^1.49.0",
20
- "react": "19.3.0",
21
- "typescript": "~6.0.3",
22
- "uqr": "0.1.3",
23
- "zod": "4.6.5"
24
- }
25
- }
@@ -1,155 +0,0 @@
1
- import { createHmac, timingSafeEqual } from "node:crypto";
2
-
3
- /**
4
- * OpenAI speaks: a call reaches its SIP endpoint, it posts `realtime.call.incoming`, this
5
- * plugin accepts the call with the wizard's rules and tools, and drives the conversation over
6
- * a WebSocket to the same session. The audio never touches the runtime.
7
- */
8
-
9
- export const OPENAI = "https://api.openai.com/v1";
10
-
11
- /** Where Twilio sends the call: the project at OpenAI's SIP endpoint, in the EU or the US. */
12
- export function sipUri(project: string, region: "eu" | "us"): string {
13
- const host = region === "eu" ? "sip-eu.api.openai.com" : "sip.api.openai.com";
14
- return `sip:${project}@${host};transport=tls`;
15
- }
16
-
17
- /** Only a signature of five minutes or so counts; a replay from a kept body does not. */
18
- const WEBHOOK_TOLERANCE_SECONDS = 300;
19
-
20
- /**
21
- * Standard Webhooks, as OpenAI signs: `webhook-signature` holds `v1,<base64 HMAC-SHA256>` of
22
- * `<webhook-id>.<webhook-timestamp>.<body>`, the key being the secret after `whsec_`, base64.
23
- */
24
- export function webhookOk(
25
- secret: string,
26
- headers: { id: string | null; timestamp: string | null; signature: string | null },
27
- raw: string,
28
- now = Date.now(),
29
- ): boolean {
30
- if (!headers.id || !headers.timestamp || !headers.signature) {
31
- return false;
32
- }
33
- const at = Number(headers.timestamp);
34
- if (!Number.isFinite(at) || Math.abs(now / 1000 - at) > WEBHOOK_TOLERANCE_SECONDS) {
35
- return false;
36
- }
37
- const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
38
- const expected = Buffer.from(
39
- createHmac("sha256", key)
40
- .update(`${headers.id}.${headers.timestamp}.${raw}`, "utf8")
41
- .digest("base64"),
42
- );
43
- return headers.signature.split(" ").some((part) => {
44
- const [version, signature] = part.split(",");
45
- const given = Buffer.from(signature ?? "");
46
- return version === "v1" && given.length === expected.length && timingSafeEqual(given, expected);
47
- });
48
- }
49
-
50
- export interface IncomingCall {
51
- callId: string;
52
- headers: Map<string, string>;
53
- }
54
-
55
- /** The call OpenAI announces, with its SIP headers by lower-case name; null for any other event. */
56
- export function incomingCall(body: unknown): IncomingCall | null {
57
- const event = body as {
58
- type?: string;
59
- data?: { call_id?: string; sip_headers?: { name?: string; value?: string }[] };
60
- } | null;
61
- if (event?.type !== "realtime.call.incoming" || !event.data?.call_id) {
62
- return null;
63
- }
64
- const headers = new Map<string, string>();
65
- for (const h of event.data.sip_headers ?? []) {
66
- if (h.name && typeof h.value === "string") {
67
- headers.set(h.name.toLowerCase(), h.value);
68
- }
69
- }
70
- return { callId: event.data.call_id, headers };
71
- }
72
-
73
- export class OpenAIError extends Error {
74
- constructor(
75
- message: string,
76
- readonly status: number,
77
- ) {
78
- super(message);
79
- this.name = "OpenAIError";
80
- }
81
- }
82
-
83
- async function post(
84
- apiKey: string,
85
- path: string,
86
- body: unknown,
87
- fetchImpl: typeof fetch,
88
- ): Promise<void> {
89
- const res = await fetchImpl(`${OPENAI}${path}`, {
90
- method: "POST",
91
- headers: { authorization: `Bearer ${apiKey}`, "content-type": "application/json" },
92
- body: body === undefined ? undefined : JSON.stringify(body),
93
- signal: AbortSignal.timeout(15_000),
94
- });
95
- if (!res.ok) {
96
- const detail = (await res.text()).slice(0, 300);
97
- throw new OpenAIError(`OpenAI answered ${res.status}: ${detail}`, res.status);
98
- }
99
- }
100
-
101
- export interface CallSessionConfig {
102
- model: string;
103
- instructions: string;
104
- tools: unknown[];
105
- voice: string;
106
- }
107
-
108
- /** Picks the call up with the wizard's rules; the person hears the model from here on. */
109
- export function acceptCall(
110
- apiKey: string,
111
- callId: string,
112
- config: CallSessionConfig,
113
- fetchImpl: typeof fetch = (...args) => globalThis.fetch(...args),
114
- ): Promise<void> {
115
- return post(
116
- apiKey,
117
- `/realtime/calls/${encodeURIComponent(callId)}/accept`,
118
- {
119
- type: "realtime",
120
- model: config.model,
121
- instructions: config.instructions,
122
- tools: config.tools,
123
- tool_choice: "auto",
124
- audio: { output: { voice: config.voice } },
125
- },
126
- fetchImpl,
127
- );
128
- }
129
-
130
- export function rejectCall(
131
- apiKey: string,
132
- callId: string,
133
- fetchImpl: typeof fetch = (...args) => globalThis.fetch(...args),
134
- ): Promise<void> {
135
- return post(apiKey, `/realtime/calls/${encodeURIComponent(callId)}/reject`, {}, fetchImpl);
136
- }
137
-
138
- export function hangUp(
139
- apiKey: string,
140
- callId: string,
141
- fetchImpl: typeof fetch = (...args) => globalThis.fetch(...args),
142
- ): Promise<void> {
143
- return post(apiKey, `/realtime/calls/${encodeURIComponent(callId)}/hangup`, undefined, fetchImpl);
144
- }
145
-
146
- /**
147
- * The WebSocket to the accepted call. Node's own client takes no headers, so the key goes the
148
- * way a browser's does: as a sub-protocol.
149
- */
150
- export function openSocket(apiKey: string, callId: string): WebSocket {
151
- return new WebSocket(`wss://api.openai.com/v1/realtime?call_id=${encodeURIComponent(callId)}`, [
152
- "realtime",
153
- `openai-insecure-api-key.${apiKey}`,
154
- ]);
155
- }