@rainbow-robotics/muscat-plugin-kit 0.1.2-dev.44 → 0.1.2-dev.45

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 (238) hide show
  1. package/README.md +1 -1
  2. package/cli/README.md +184 -0
  3. package/cli/bin/muscat-pk.mjs +13 -0
  4. package/cli/prepack.mjs +10 -0
  5. package/cli/src/build.mjs +2 -29
  6. package/cli/src/dev.mjs +10 -2
  7. package/cli/src/devBack.mjs +72 -9
  8. package/cli/src/devUi.mjs +100 -34
  9. package/cli/src/manifest.mjs +15 -0
  10. package/cli/src/mcp.mjs +523 -0
  11. package/cli/src/pluginDevServer.mjs +113 -0
  12. package/cli/src/ports.mjs +160 -0
  13. package/cli/src/sdk.mjs +11 -9
  14. package/cli/src/storybook.mjs +168 -0
  15. package/cli/src/templates-embedded.mjs +1 -1
  16. package/cli/storybook-dist/_design-tokens.css +4957 -0
  17. package/cli/storybook-dist/_stories-src/NxAvatar.stories.tsx +27 -0
  18. package/cli/storybook-dist/_stories-src/NxPagination.stories.tsx +28 -0
  19. package/cli/storybook-dist/_stories-src/RBAccordion/RBAccordion.stories.tsx +46 -0
  20. package/cli/storybook-dist/_stories-src/RBAccordion/RBAccordionGroup.stories.tsx +73 -0
  21. package/cli/storybook-dist/_stories-src/RBBadge/RBBadge.stories.tsx +93 -0
  22. package/cli/storybook-dist/_stories-src/RBBattery/RBBattery.stories.tsx +74 -0
  23. package/cli/storybook-dist/_stories-src/RBButton/RBCheckIconButton.stories.tsx +28 -0
  24. package/cli/storybook-dist/_stories-src/RBButton/RBCheckLabelButton.stories.tsx +84 -0
  25. package/cli/storybook-dist/_stories-src/RBButton/RBIconButton.stories.tsx +57 -0
  26. package/cli/storybook-dist/_stories-src/RBButton/RBInlineLabelButton.stories.tsx +41 -0
  27. package/cli/storybook-dist/_stories-src/RBButton/RBLabelButton.stories.tsx +60 -0
  28. package/cli/storybook-dist/_stories-src/RBDatePicker/RBDateInput.stories.tsx +44 -0
  29. package/cli/storybook-dist/_stories-src/RBDatePicker/RBRangeDateInput.stories.tsx +44 -0
  30. package/cli/storybook-dist/_stories-src/RBDialog/RBAlert.stories.tsx +51 -0
  31. package/cli/storybook-dist/_stories-src/RBDialog/RBConfirm.stories.tsx +55 -0
  32. package/cli/storybook-dist/_stories-src/RBDialog/RBPrompt.stories.tsx +52 -0
  33. package/cli/storybook-dist/_stories-src/RBDivider/RBDivider.stories.tsx +93 -0
  34. package/cli/storybook-dist/_stories-src/RBEmptyView/RBEmptyView.stories.tsx +49 -0
  35. package/cli/storybook-dist/_stories-src/RBIcons/RBColorIcons.stories.tsx +108 -0
  36. package/cli/storybook-dist/_stories-src/RBIcons/RBIcons.stories.tsx +106 -0
  37. package/cli/storybook-dist/_stories-src/RBIcons/RBMenuTreeIcons.stories.tsx +108 -0
  38. package/cli/storybook-dist/_stories-src/RBIcons/RBProgramIcons.stories.tsx +116 -0
  39. package/cli/storybook-dist/_stories-src/RBInput/RBCheckBox.stories.tsx +89 -0
  40. package/cli/storybook-dist/_stories-src/RBInput/RBMultiRangeInput.stories.tsx +64 -0
  41. package/cli/storybook-dist/_stories-src/RBInput/RBRadioBox.stories.tsx +65 -0
  42. package/cli/storybook-dist/_stories-src/RBInput/RBRadioButton.stories.tsx +68 -0
  43. package/cli/storybook-dist/_stories-src/RBInput/RBSelectBox.stories.tsx +119 -0
  44. package/cli/storybook-dist/_stories-src/RBInput/RBSideNumberInput.stories.tsx +90 -0
  45. package/cli/storybook-dist/_stories-src/RBInput/RBText/RBTextArea.stories.tsx +45 -0
  46. package/cli/storybook-dist/_stories-src/RBInput/RBText/RBTextInput.stories.tsx +50 -0
  47. package/cli/storybook-dist/_stories-src/RBInput/RBTextField.stories.tsx +102 -0
  48. package/cli/storybook-dist/_stories-src/RBJoyStick/RBJoyStick.stories.tsx +31 -0
  49. package/cli/storybook-dist/_stories-src/RBLight/RBLight.stories.tsx +36 -0
  50. package/cli/storybook-dist/_stories-src/RBPagination/RBPagination.stories.tsx +49 -0
  51. package/cli/storybook-dist/_stories-src/RBShadcn/RBCard/RBCard.stories.tsx +89 -0
  52. package/cli/storybook-dist/_stories-src/RBShadcn/RBCommand/RBCommand.stories.tsx +116 -0
  53. package/cli/storybook-dist/_stories-src/RBShadcn/RBDialog/RBDialog.stories.tsx +74 -0
  54. package/cli/storybook-dist/_stories-src/RBShadcn/RBDrawer/RBDrawer.stories.tsx +99 -0
  55. package/cli/storybook-dist/_stories-src/RBShadcn/RBDropdownMenu/RBDropdownMenu.stories.tsx +123 -0
  56. package/cli/storybook-dist/_stories-src/RBShadcn/RBMenubar/RBMenubar.stories.tsx +135 -0
  57. package/cli/storybook-dist/_stories-src/RBShadcn/RBPopover/RBPopover.stories.tsx +69 -0
  58. package/cli/storybook-dist/_stories-src/RBShadcn/RBResizable/RBResizable.stories.tsx +49 -0
  59. package/cli/storybook-dist/_stories-src/RBShadcn/RBSheet/RBSheet.stories.tsx +91 -0
  60. package/cli/storybook-dist/_stories-src/RBShadcn/RBSlider/RBSlider.stories.tsx +38 -0
  61. package/cli/storybook-dist/_stories-src/RBShadcn/RBSwitch/RBSwitch.stories.tsx +112 -0
  62. package/cli/storybook-dist/_stories-src/RBShadcn/RBTabs/RBTabs.stories.tsx +75 -0
  63. package/cli/storybook-dist/_stories-src/RBShadcn/RBToggle/RBToggle.stories.tsx +51 -0
  64. package/cli/storybook-dist/_stories-src/RBShadcn/RBToggleGroup/RBToggleGroup.stories.tsx +84 -0
  65. package/cli/storybook-dist/_stories-src/RBTab/RBChipTab.stories.tsx +102 -0
  66. package/cli/storybook-dist/_stories-src/RBTab/RBChipsBoxTab.stories.tsx +78 -0
  67. package/cli/storybook-dist/_stories-src/RBTab/RBTab.stories.tsx +57 -0
  68. package/cli/storybook-dist/_stories-src/RBTable/RBTable.stories.tsx +177 -0
  69. package/cli/storybook-dist/_stories-src/RBTable/RBTableRow.stories.tsx +64 -0
  70. package/cli/storybook-dist/_stories-src/RBToast/RBToast.stories.tsx +117 -0
  71. package/cli/storybook-dist/_stories-src/RBTooltip/RBTooltip.stories.tsx +50 -0
  72. package/cli/storybook-dist/_stories-src/loading/RBSpinner.stories.tsx +30 -0
  73. package/cli/storybook-dist/_stories-src/nx-button/NxButton.stories.tsx +54 -0
  74. package/cli/storybook-dist/_stories-src/nx-button/NxPointerHoldButton.stories.tsx +57 -0
  75. package/cli/storybook-dist/_stories-src/nx-icons/NxIcons.stories.tsx +48 -0
  76. package/cli/storybook-dist/_stories-src/nx-inputs/NxNumberInput.stories.tsx +103 -0
  77. package/cli/storybook-dist/_stories-src/nx-inputs/NxRangeInput.stories.tsx +27 -0
  78. package/cli/storybook-dist/_stories-src/nx-inputs/NxSelectBox.stories.tsx +67 -0
  79. package/cli/storybook-dist/_stories-src/nx-inputs/NxSlideRange.stories.tsx +45 -0
  80. package/cli/storybook-dist/_stories-src/nx-inputs/NxSwitch.stories.tsx +27 -0
  81. package/cli/storybook-dist/_stories-src/nx-inputs/NxTextArea.stories.tsx +48 -0
  82. package/cli/storybook-dist/_stories-src/nx-inputs/NxTextInput.stories.tsx +46 -0
  83. package/cli/storybook-dist/assets/Color-YHDXOIA2-BjuzF3Je.js +1 -0
  84. package/cli/storybook-dist/assets/Docs-BAFZYTMR.js +12 -0
  85. package/cli/storybook-dist/assets/Docs-BQesYW-Q.js +8 -0
  86. package/cli/storybook-dist/assets/Docs-BsMEe093.js +7 -0
  87. package/cli/storybook-dist/assets/Docs-By6k6vcM.js +20 -0
  88. package/cli/storybook-dist/assets/Docs-D1J63cJc.js +7 -0
  89. package/cli/storybook-dist/assets/Docs-GoNbntAU.js +8 -0
  90. package/cli/storybook-dist/assets/DocsRenderer-CFRXHY34-BwY_WiM7.js +2 -0
  91. package/cli/storybook-dist/assets/NxAvatar.stories-CvzBHfYa.js +13 -0
  92. package/cli/storybook-dist/assets/NxButton.stories-B83PesgN.js +20 -0
  93. package/cli/storybook-dist/assets/NxIcons.stories-Ca7qpAaO.js +3 -0
  94. package/cli/storybook-dist/assets/NxNumberInput.stories-DpNcCG6B.js +26 -0
  95. package/cli/storybook-dist/assets/NxPagination.stories-Xnvd3xhH.js +11 -0
  96. package/cli/storybook-dist/assets/NxPointerHoldButton.stories-C3YSIpM0.js +14 -0
  97. package/cli/storybook-dist/assets/NxRangeInput.stories-DIhaNZig.js +17 -0
  98. package/cli/storybook-dist/assets/NxSelectBox.stories-BGwO2mYJ.js +17 -0
  99. package/cli/storybook-dist/assets/NxSlideRange.stories-BXlt5Bgt.js +14 -0
  100. package/cli/storybook-dist/assets/NxSwitch.stories-C5ZqIRtw.js +11 -0
  101. package/cli/storybook-dist/assets/NxTextArea.stories-hm_ycALo.js +11 -0
  102. package/cli/storybook-dist/assets/NxTextInput.stories-DkZAySr_.js +11 -0
  103. package/cli/storybook-dist/assets/PretendardVariable-CJuje-Rk.woff2 +0 -0
  104. package/cli/storybook-dist/assets/RBAccordion.stories--bY36GZY.js +17 -0
  105. package/cli/storybook-dist/assets/RBAccordionGroup.stories-BVr1ccI4.js +33 -0
  106. package/cli/storybook-dist/assets/RBAlert.stories-CkjFBEkv.js +17 -0
  107. package/cli/storybook-dist/assets/RBBadge.stories-CNXILDPh.js +1 -0
  108. package/cli/storybook-dist/assets/RBBattery.stories-AokMv8ZY.js +10 -0
  109. package/cli/storybook-dist/assets/RBCard.stories-CX1sLKB2.js +45 -0
  110. package/cli/storybook-dist/assets/RBCheckBox.stories-By3QHBFm.js +1 -0
  111. package/cli/storybook-dist/assets/RBCheckIconButton.stories-Dud1uK3X.js +1 -0
  112. package/cli/storybook-dist/assets/RBCheckLabelButton.stories-C8iBkZxY.js +24 -0
  113. package/cli/storybook-dist/assets/RBChipTab.stories-DsgbiS2U.js +21 -0
  114. package/cli/storybook-dist/assets/RBChipsBoxTab.stories-C3DZGmq0.js +1 -0
  115. package/cli/storybook-dist/assets/RBColorIcons.stories-CusR20qk.js +3 -0
  116. package/cli/storybook-dist/assets/RBCommand.stories-DhJNgaLZ.js +73 -0
  117. package/cli/storybook-dist/assets/RBConfirm.stories-B6LKpCDa.js +20 -0
  118. package/cli/storybook-dist/assets/RBDateInput.stories-PEEhQ1wJ.js +15 -0
  119. package/cli/storybook-dist/assets/RBDialog.stories-CAtOdRen.js +38 -0
  120. package/cli/storybook-dist/assets/RBDivider.stories-0zpIUlXT.js +1 -0
  121. package/cli/storybook-dist/assets/RBDrawer.stories-CWMG4glY.js +14 -0
  122. package/cli/storybook-dist/assets/RBDropdownMenu.stories-6fbEYZfk.js +86 -0
  123. package/cli/storybook-dist/assets/RBEmptyView.stories-BRDZHjn4.js +12 -0
  124. package/cli/storybook-dist/assets/RBIconButton.stories-sYrRLYob.js +1 -0
  125. package/cli/storybook-dist/assets/RBIcons.stories-DFe8O1_g.js +3 -0
  126. package/cli/storybook-dist/assets/RBInlineLabelButton.stories-DX4VdUfk.js +1 -0
  127. package/cli/storybook-dist/assets/RBJoyStick.stories-SA2Foelf.js +11 -0
  128. package/cli/storybook-dist/assets/RBLabelButton.stories-CicBns_Y.js +1 -0
  129. package/cli/storybook-dist/assets/RBLight.stories-WlP3oEmY.js +1 -0
  130. package/cli/storybook-dist/assets/RBMenuTreeIcons.stories-CrWjPfxj.js +3 -0
  131. package/cli/storybook-dist/assets/RBMenubar.stories-Di4phWw7.js +3 -0
  132. package/cli/storybook-dist/assets/RBMultiRangeInput.stories-DS3wrR3l.js +14 -0
  133. package/cli/storybook-dist/assets/RBPagination.stories-BDVPAUVD.js +17 -0
  134. package/cli/storybook-dist/assets/RBPopover.stories-DL9b_iX9.js +11 -0
  135. package/cli/storybook-dist/assets/RBProgramIcons.stories-ByRVx-on.js +3 -0
  136. package/cli/storybook-dist/assets/RBPrompt.stories-vTmKWyA5.js +20 -0
  137. package/cli/storybook-dist/assets/RBRadioBox.stories-C9WHt4jb.js +1 -0
  138. package/cli/storybook-dist/assets/RBRadioButton.stories-D8KYq63j.js +11 -0
  139. package/cli/storybook-dist/assets/RBRangeDateInput.stories-Bvcf4Su7.js +15 -0
  140. package/cli/storybook-dist/assets/RBResizable.stories-3O2OMuH_.js +20 -0
  141. package/cli/storybook-dist/assets/RBSelectBox.stories-CKZLmPzX.js +6 -0
  142. package/cli/storybook-dist/assets/RBSheet.stories-Dko0It1W.js +39 -0
  143. package/cli/storybook-dist/assets/RBSideNumberInput.stories-CUvqVtId.js +5 -0
  144. package/cli/storybook-dist/assets/RBSlider.stories-CcbaKRYo.js +5 -0
  145. package/cli/storybook-dist/assets/RBSpinner.stories-D15e_JlE.js +14 -0
  146. package/cli/storybook-dist/assets/RBSwitch.stories-C4JRsYJ6.js +65 -0
  147. package/cli/storybook-dist/assets/RBTab.stories-BPvzQSM-.js +1 -0
  148. package/cli/storybook-dist/assets/RBTable.stories-nr8OS1mV.js +62 -0
  149. package/cli/storybook-dist/assets/RBTableRow.stories-rI0rK8Ci.js +11 -0
  150. package/cli/storybook-dist/assets/RBTabs.stories-CxMtHGWA.js +21 -0
  151. package/cli/storybook-dist/assets/RBTextArea.stories-Bru4AhJ3.js +5 -0
  152. package/cli/storybook-dist/assets/RBTextField.stories-Ah3D9lto.js +45 -0
  153. package/cli/storybook-dist/assets/RBTextInput.stories-C3qAVngJ.js +5 -0
  154. package/cli/storybook-dist/assets/RBToast.stories-C1occsvf.js +11 -0
  155. package/cli/storybook-dist/assets/RBToggle.stories-BNrNERc7.js +12 -0
  156. package/cli/storybook-dist/assets/RBToggleGroup.stories-D_RRBwxY.js +17 -0
  157. package/cli/storybook-dist/assets/RBTooltip.stories-DuyOQqrB.js +9 -0
  158. package/cli/storybook-dist/assets/RainbowUiProvider-BYlbsa69.css +1 -0
  159. package/cli/storybook-dist/assets/RainbowUiProvider-B_piZBLb.js +31 -0
  160. package/cli/storybook-dist/assets/browserUtils-DeopUpDy.js +1 -0
  161. package/cli/storybook-dist/assets/chunk-XP5HYGXS-BHXC9YeQ.js +1 -0
  162. package/cli/storybook-dist/assets/client-DTf7SId2.js +1 -0
  163. package/cli/storybook-dist/assets/createConveyorBeltLayer-Cn41pFRH.js +6210 -0
  164. package/cli/storybook-dist/assets/createConveyorBeltLayer-Ds5AOper.css +21 -0
  165. package/cli/storybook-dist/assets/entry-preview-D-mLV0cS.js +2 -0
  166. package/cli/storybook-dist/assets/entry-preview-docs-b8bpVBXy.js +46 -0
  167. package/cli/storybook-dist/assets/iframe-DNru2eN7.js +211 -0
  168. package/cli/storybook-dist/assets/index-B4FGfHer.js +1 -0
  169. package/cli/storybook-dist/assets/index-BRq5TIsn.js +24 -0
  170. package/cli/storybook-dist/assets/index-C1OzuK6-.js +240 -0
  171. package/cli/storybook-dist/assets/index-CT3U1fyk.js +1 -0
  172. package/cli/storybook-dist/assets/index-ChsGqxH_.js +9 -0
  173. package/cli/storybook-dist/assets/index-Cwr2bQOB.js +575 -0
  174. package/cli/storybook-dist/assets/index-DKFBREX_.js +1 -0
  175. package/cli/storybook-dist/assets/index-DgH-xKnr.js +11 -0
  176. package/cli/storybook-dist/assets/index-Dmy2JGbm.js +1 -0
  177. package/cli/storybook-dist/assets/index-DrFu-skq.js +6 -0
  178. package/cli/storybook-dist/assets/jsx-runtime-BTJTZTIL.js +9 -0
  179. package/cli/storybook-dist/assets/keymapTileIndex.worker-BsNYNbqs.js +1 -0
  180. package/cli/storybook-dist/assets/preview-B8lJiyuQ.js +34 -0
  181. package/cli/storybook-dist/assets/preview-BBWR9nbA.js +1 -0
  182. package/cli/storybook-dist/assets/preview-BWzBA1C2.js +396 -0
  183. package/cli/storybook-dist/assets/preview-CILRoSnB.js +1 -0
  184. package/cli/storybook-dist/assets/preview-CVgpLj3b.js +1 -0
  185. package/cli/storybook-dist/assets/preview-CvbIS5ZJ.js +1 -0
  186. package/cli/storybook-dist/assets/preview-DD_OYowb.js +1 -0
  187. package/cli/storybook-dist/assets/preview-DGUiP6tS.js +7 -0
  188. package/cli/storybook-dist/assets/preview-DHQbi4pV.js +1 -0
  189. package/cli/storybook-dist/assets/preview-DUTcCPBe.css +1 -0
  190. package/cli/storybook-dist/assets/preview-QAsoD6Sa.js +2 -0
  191. package/cli/storybook-dist/assets/preview-rcRMbKPr.js +3 -0
  192. package/cli/storybook-dist/assets/react-18-hB3smqWJ.js +1 -0
  193. package/cli/storybook-dist/assets/react-resizable-panels.browser-CvAJUcrm.js +72 -0
  194. package/cli/storybook-dist/assets/test-utils-BQudk2xt.js +9 -0
  195. package/cli/storybook-dist/favicon.svg +1 -0
  196. package/cli/storybook-dist/iframe.html +666 -0
  197. package/cli/storybook-dist/index.html +190 -0
  198. package/cli/storybook-dist/index.json +1 -0
  199. package/cli/storybook-dist/nunito-sans-bold-italic.woff2 +0 -0
  200. package/cli/storybook-dist/nunito-sans-bold.woff2 +0 -0
  201. package/cli/storybook-dist/nunito-sans-italic.woff2 +0 -0
  202. package/cli/storybook-dist/nunito-sans-regular.woff2 +0 -0
  203. package/cli/storybook-dist/project.json +1 -0
  204. package/cli/storybook-dist/sb-addons/chromatic-com-storybook-10/manager-bundle.js +331 -0
  205. package/cli/storybook-dist/sb-addons/chromatic-com-storybook-10/manager-bundle.js.LEGAL.txt +51 -0
  206. package/cli/storybook-dist/sb-addons/essentials-actions-3/manager-bundle.js +3 -0
  207. package/cli/storybook-dist/sb-addons/essentials-backgrounds-5/manager-bundle.js +12 -0
  208. package/cli/storybook-dist/sb-addons/essentials-controls-2/manager-bundle.js +405 -0
  209. package/cli/storybook-dist/sb-addons/essentials-docs-4/manager-bundle.js +245 -0
  210. package/cli/storybook-dist/sb-addons/essentials-measure-8/manager-bundle.js +3 -0
  211. package/cli/storybook-dist/sb-addons/essentials-outline-9/manager-bundle.js +3 -0
  212. package/cli/storybook-dist/sb-addons/essentials-toolbars-7/manager-bundle.js +3 -0
  213. package/cli/storybook-dist/sb-addons/essentials-viewport-6/manager-bundle.js +3 -0
  214. package/cli/storybook-dist/sb-addons/links-1/manager-bundle.js +3 -0
  215. package/cli/storybook-dist/sb-addons/storybook-13/manager-bundle.js +3 -0
  216. package/cli/storybook-dist/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +3 -0
  217. package/cli/storybook-dist/sb-addons/storybook-experimental-addon-test-12/manager-bundle.js +223 -0
  218. package/cli/storybook-dist/sb-addons/themes-11/manager-bundle.js +3 -0
  219. package/cli/storybook-dist/sb-common-assets/favicon.svg +1 -0
  220. package/cli/storybook-dist/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  221. package/cli/storybook-dist/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  222. package/cli/storybook-dist/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  223. package/cli/storybook-dist/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  224. package/cli/storybook-dist/sb-manager/globals-module-info.js +1052 -0
  225. package/cli/storybook-dist/sb-manager/globals-runtime.js +41775 -0
  226. package/cli/storybook-dist/sb-manager/globals.js +48 -0
  227. package/cli/storybook-dist/sb-manager/runtime.js +12048 -0
  228. package/cli/templates/common/.mcp.json +8 -0
  229. package/cli/templates/common/README.md +467 -53
  230. package/cli/templates/common/assets/icon.svg +44 -2
  231. package/cli/templates/common/package.json +2 -0
  232. package/cli/templates/common/ui/content.tsx +209 -26
  233. package/cli/templates/common/ui/style.css +6 -0
  234. package/cli/templates/common/vite.config.ts +6 -34
  235. package/cli/templates/cpp/cpp/main.cpp +1 -0
  236. package/cli/vite.d.mts +25 -0
  237. package/cli/vite.mjs +271 -0
  238. package/package.json +31 -4
@@ -1,3 +1,45 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="1em" height="1em" fill="none">
2
- <path fill="currentColor" d="M16 3a13 13 0 1 0 0 26 13 13 0 0 0 0-26Zm0 4a3 3 0 0 1 3 3v2.18a3 3 0 0 1 0 5.64V20a3 3 0 1 1-6 0v-2.18a3 3 0 0 1 0-5.64V10a3 3 0 0 1 3-3Z"/>
1
+ <svg width="256" height="256" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <defs>
3
+ <linearGradient id="bg" x1="36" y1="28" x2="220" y2="228" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#8B5CF6"/>
5
+ <stop offset="1" stop-color="#5B21B6"/>
6
+ </linearGradient>
7
+ <linearGradient id="grape" x1="92" y1="74" x2="168" y2="178" gradientUnits="userSpaceOnUse">
8
+ <stop stop-color="#D8B4FE"/>
9
+ <stop offset="1" stop-color="#A855F7"/>
10
+ </linearGradient>
11
+ </defs>
12
+
13
+ <rect x="16" y="16" width="224" height="224" rx="52" fill="url(#bg)"/>
14
+
15
+ <!-- plugin brackets -->
16
+ <path d="M72 84H56C47.1634 84 40 91.1634 40 100V116" stroke="white" stroke-width="12" stroke-linecap="round"/>
17
+ <path d="M184 84H200C208.837 84 216 91.1634 216 100V116" stroke="white" stroke-width="12" stroke-linecap="round"/>
18
+ <path d="M72 172H56C47.1634 172 40 164.837 40 156V140" stroke="white" stroke-width="12" stroke-linecap="round"/>
19
+ <path d="M184 172H200C208.837 172 216 164.837 216 156V140" stroke="white" stroke-width="12" stroke-linecap="round"/>
20
+
21
+ <!-- grape stem + leaf -->
22
+ <path d="M128 73C128 59 137 48 151 44" stroke="#F3E8FF" stroke-width="10" stroke-linecap="round"/>
23
+ <path d="M142 51C151 39 169 39 179 50C165 60 151 62 142 51Z" fill="#C4B5FD"/>
24
+
25
+ <!-- muscat grape cluster -->
26
+ <circle cx="106" cy="91" r="18" fill="url(#grape)"/>
27
+ <circle cx="132" cy="88" r="18" fill="url(#grape)"/>
28
+ <circle cx="158" cy="91" r="18" fill="url(#grape)"/>
29
+ <circle cx="94" cy="119" r="18" fill="url(#grape)"/>
30
+ <circle cx="120" cy="116" r="18" fill="url(#grape)"/>
31
+ <circle cx="146" cy="116" r="18" fill="url(#grape)"/>
32
+ <circle cx="172" cy="119" r="18" fill="url(#grape)"/>
33
+ <circle cx="107" cy="145" r="18" fill="url(#grape)"/>
34
+ <circle cx="133" cy="144" r="18" fill="url(#grape)"/>
35
+ <circle cx="159" cy="145" r="18" fill="url(#grape)"/>
36
+ <circle cx="120" cy="170" r="18" fill="url(#grape)"/>
37
+ <circle cx="146" cy="170" r="18" fill="url(#grape)"/>
38
+ <circle cx="133" cy="193" r="18" fill="url(#grape)"/>
39
+
40
+ <!-- center plugin glyph -->
41
+ <path d="M122 119V109C122 103.477 126.477 99 132 99H136C141.523 99 146 103.477 146 109V119" stroke="white" stroke-width="8" stroke-linecap="round"/>
42
+ <rect x="116" y="118" width="36" height="34" rx="10" fill="white"/>
43
+ <path d="M127 152V163" stroke="white" stroke-width="8" stroke-linecap="round"/>
44
+ <path d="M141 152V163" stroke="white" stroke-width="8" stroke-linecap="round"/>
3
45
  </svg>
@@ -7,9 +7,11 @@
7
7
  "@rainbow-robotics/plugin-ui": "__RB_VERSION__"
8
8
  },
9
9
  "devDependencies": {
10
+ "@tailwindcss/vite": "^4.1.0",
10
11
  "@rainbow-robotics/muscat-plugin-kit": "__RB_VERSION__",
11
12
  "@rainbow-robotics/preview-host": "__RB_VERSION__",
12
13
  "@vitejs/plugin-react": "^4.0.0",
14
+ "tailwindcss": "^4.1.0",
13
15
  "typescript": "^5.8.0",
14
16
  "vite": "^6.0.0"
15
17
  }
@@ -1,33 +1,216 @@
1
- import { useState } from "react";
2
- import { connect } from "@rainbow-robotics/plugin-ui/connect";
3
- import { Slider, Button, Text, Switch } from "@rainbow-robotics/plugin-ui/react";
1
+ import { useMemo, useState } from "react";
2
+ import {
3
+ RBCheckBox,
4
+ RBLabelButton,
5
+ RBRadioBox,
6
+ RBSelectBox,
7
+ RBSlider,
8
+ RBSwitch,
9
+ RBTextArea,
10
+ RBTextField,
11
+ RBTextInput,
12
+ Option
13
+ } from "@rainbow-robotics/plugin-ui/react";
4
14
  import { useRb } from "@rainbow-robotics/plugin-ui/sdk";
5
15
 
6
- function App() {
16
+ type RunMode = "inspect" | "assist" | "auto";
17
+
18
+ const MODE_OPTIONS: Array<{ label: string; value: RunMode }> = [
19
+ { label: "Inspect", value: "inspect" },
20
+ { label: "Assist", value: "assist" },
21
+ { label: "Auto", value: "auto" },
22
+ ];
23
+
24
+ const TASK_OPTIONS = [
25
+ { label: "Publish status", value: "publish" },
26
+ { label: "Run grip action", value: "grip" },
27
+ { label: "Save snapshot", value: "snapshot" },
28
+ ];
29
+
30
+ // Export your UI as the default. The host mounts it (dev: with HMR).
31
+ export default function App() {
7
32
  const rb = useRb();
8
- const [width, setWidth] = useState(20);
9
- const [open, setOpen] = useState(false);
33
+ const [targetName, setTargetName] = useState("demo_target");
34
+ const [gripType, setGripType] = useState<string>();
35
+ const [gripWidth, setGripWidth] = useState(24);
36
+ const [speed, setSpeed] = useState(45);
37
+ const [mode, setMode] = useState<RunMode>("assist");
38
+ const [enabled, setEnabled] = useState(true);
39
+ const [tasks, setTasks] = useState<Array<string>>(["publish", "grip"]);
40
+ const [memo, setMemo] = useState("Use this area for operator notes.");
41
+
42
+ const payload = useMemo(
43
+ () => ({
44
+ targetName,
45
+ gripWidth,
46
+ speed,
47
+ mode,
48
+ enabled,
49
+ tasks,
50
+ memo,
51
+ }),
52
+ [targetName, gripWidth, speed, mode, enabled, tasks, memo],
53
+ );
54
+
55
+ const showRequestError = (error: unknown) => {
56
+ const message = error instanceof Error ? error.message : "Request failed";
57
+ rb.toast({ type: "danger", message });
58
+ };
59
+
60
+ const runAction = async () => {
61
+ try {
62
+ await rb.action("grip", payload);
63
+ rb.toast({ type: "success", message: `Sent ${targetName}` });
64
+ } catch (error) {
65
+ showRequestError(error);
66
+ }
67
+ };
68
+
69
+ const publishPreview = async () => {
70
+ try {
71
+ const isConfirm = await rb.confirm({
72
+ message: "Are you sure publish?",
73
+ buttonText: { yes: "confirm", no: "cancel" },
74
+ });
75
+
76
+ if (isConfirm) {
77
+ await rb.pub("event", payload);
78
+ }
79
+ } catch (error) {
80
+ showRequestError(error);
81
+ }
82
+ };
10
83
 
11
84
  return (
12
- <>
13
- <Text>__PLUGIN_NAME__ width: {width}</Text>
14
- <Slider
15
- value={width}
16
- min={0}
17
- max={100}
18
- onChange={(event: { detail?: number }) => setWidth(event.detail ?? 0)}
19
- />
20
- <Button label="Grip" onPress={() => rb.action("grip", { width })} />
21
- <Switch
22
- checked={open}
23
- onChange={(event: { detail?: boolean }) => {
24
- const next = event.detail ?? false;
25
- setOpen(next);
26
- rb.toast(next ? "opened" : "closed", "info");
27
- }}
28
- />
29
- </>
85
+ <div className="max-h-[70vh] w-[420px] p-4 max-w-full overflow-y-auto bg-bg-elevated text-fg-default">
86
+ <div className="flex flex-col gap-5">
87
+ <header>
88
+ <div className="flex items-center justify-between gap-12">
89
+ <div>
90
+ <h2 className="typo-heading-xs-semibold">Demo Control</h2>
91
+ <p className="typo-body-xs2-normal text-fg-subtle">
92
+ Input patterns for Muscat plugin UIs
93
+ </p>
94
+ </div>
95
+ <RBSwitch
96
+ checked={enabled}
97
+ onCheckedChange={(next: boolean) => {
98
+ setEnabled(next);
99
+ rb.toast({message: next ? "Plugin enabled" : "Plugin paused"});
100
+ }}
101
+ />
102
+ </div>
103
+ </header>
104
+
105
+ <section className="flex flex-col gap-4">
106
+ <RBTextField
107
+ label="Target name"
108
+ required
109
+ helperText="Used as the backend action target."
110
+ >
111
+ <RBTextInput
112
+ name="targetName"
113
+ value={targetName}
114
+ placeholder="target id"
115
+ handleChange={(value) => setTargetName(String(value))}
116
+ />
117
+ </RBTextField>
118
+
119
+ <RBTextField label="Select Grip">
120
+ <RBSelectBox className="w-full" value={gripType} handleChange={setGripType}>
121
+ <Option value="A">A Grip</Option>
122
+ <Option value="B">B Grip</Option>
123
+ </RBSelectBox>
124
+ </RBTextField>
125
+
126
+ <div className="flex gap-4">
127
+ <RBTextField className="flex-1" label="Grip width" helperText="0-100 mm">
128
+ <RBTextInput
129
+ className="w-full"
130
+ name="gripWidth"
131
+ type="number"
132
+ value={gripWidth}
133
+ validate={(value: number) =>
134
+ Math.max(0, Math.min(100, Number(value) || 0))
135
+ }
136
+ handleChange={(value) => setGripWidth(Number(value) || 0)}
137
+ />
138
+ </RBTextField>
139
+
140
+ <RBTextField className="flex-1" label="Speed" helperText={`${speed}%`}>
141
+ <div className="flex items-center px-2">
142
+ <RBSlider
143
+ value={[speed]}
144
+ min={0}
145
+ max={100}
146
+ step={5}
147
+ onValueChange={(values: number[]) =>
148
+ setSpeed(values[0] ?? 0)
149
+ }
150
+ />
151
+ </div>
152
+ </RBTextField>
153
+ </div>
154
+ </section>
155
+
156
+ <section className="mb-4">
157
+ <RBTextField label="Run mode">
158
+ <div className="flex justify-between border-1 border-border-subtle rounded-sm p-2">
159
+ {MODE_OPTIONS.map((item) => (
160
+ <RBRadioBox
161
+ key={item.value}
162
+ name="mode"
163
+ checkValue={item.value}
164
+ value={mode}
165
+ handleChange={(value) => setMode(value as RunMode)}
166
+ >
167
+ {item.label}
168
+ </RBRadioBox>
169
+ ))}
170
+ </div>
171
+ </RBTextField>
172
+ </section>
173
+
174
+ <section className="mb-4">
175
+ <RBTextField label="Tasks">
176
+ <div className="flex justify-between border-1 border-border-subtle rounded-sm p-2">
177
+ {TASK_OPTIONS.map((item) => (
178
+ <RBCheckBox
179
+ key={item.value}
180
+ name="tasks"
181
+ checkValue={item.value}
182
+ value={tasks}
183
+ handleChange={(value) =>
184
+ setTasks(Array.isArray(value) ? value.map(String) : [])
185
+ }
186
+ >
187
+ {item.label}
188
+ </RBCheckBox>
189
+ ))}
190
+ </div>
191
+ </RBTextField>
192
+
193
+ </section>
194
+
195
+ <RBTextField label="Memo">
196
+ <RBTextArea
197
+ name="memo"
198
+ value={memo}
199
+ maxLength={120}
200
+ rows={4}
201
+ handleChange={setMemo}
202
+ />
203
+ </RBTextField>
204
+
205
+ <footer className="grid grid-cols-2 gap-8 pt-4">
206
+ <RBLabelButton variant="outlined" onClick={publishPreview}>
207
+ Publish
208
+ </RBLabelButton>
209
+ <RBLabelButton onClick={runAction} disabled={!enabled}>
210
+ Run Action
211
+ </RBLabelButton>
212
+ </footer>
213
+ </div>
214
+ </div>
30
215
  );
31
216
  }
32
-
33
- connect(App);
@@ -0,0 +1,6 @@
1
+ @layer theme, utilities;
2
+
3
+ @import "tailwindcss/theme.css" layer(theme);
4
+ @import "tailwindcss/utilities.css" layer(utilities);
5
+
6
+ @source "./**/*.{ts,tsx}";
@@ -1,38 +1,10 @@
1
- import { readdirSync } from "fs";
2
- import { basename, extname, resolve } from "path";
3
- import react from "@vitejs/plugin-react";
4
1
  import { defineConfig } from "vite";
2
+ import tailwindcss from "@tailwindcss/vite";
3
+ import { muscat } from "@rainbow-robotics/muscat-plugin-kit/vite";
5
4
 
6
- // Plugin UI and React are provided by Muscat/preview-host via import map.
7
- // They must NOT be bundled into the plugin ZIP.
8
- const HOST_PROVIDED_EXTERNALS = [
9
- /^@rainbow-robotics\/plugin-ui(\/|$)/,
10
- /^react(\/|$)/,
11
- /^react-dom(\/|$)/,
12
- ];
13
-
14
- // All top-level .tsx/.ts files in ui/ become separate entry points.
15
- // Subdirectories (components/, hooks/, etc.) are imported by entries and bundled in.
16
- const uiEntries = Object.fromEntries(
17
- readdirSync("ui")
18
- .filter((f) => /\.(tsx?|jsx?)$/.test(f))
19
- .map((f) => [basename(f, extname(f)), resolve("ui", f)]),
20
- );
21
-
5
+ // The muscat() preset wires react-refresh, ui/ entry discovery, and marks the
6
+ // host-provided runtime (plugin-ui, react) as external. Add your own plugins or
7
+ // overrides here as needed.
22
8
  export default defineConfig({
23
- plugins: [react()],
24
- build: {
25
- outDir: "dist",
26
- emptyOutDir: false,
27
- rollupOptions: {
28
- input: uiEntries,
29
- external: HOST_PROVIDED_EXTERNALS,
30
- output: {
31
- format: "es",
32
- entryFileNames: "[name].js",
33
- chunkFileNames: "chunks/[name]-[hash].js",
34
- assetFileNames: "assets/[name]-[hash][extname]",
35
- },
36
- },
37
- },
9
+ plugins: [tailwindcss(), muscat()],
38
10
  });
@@ -8,6 +8,7 @@
8
8
  #include <chrono>
9
9
  #include <cstdlib>
10
10
  #include <iostream>
11
+ #include <string>
11
12
  #include <thread>
12
13
 
13
14
  int main() {
package/cli/vite.d.mts ADDED
@@ -0,0 +1,25 @@
1
+ export interface MuscatVitePlugin {
2
+ name: string;
3
+ }
4
+
5
+ export type MuscatVitePluginOption =
6
+ | MuscatVitePlugin
7
+ | false
8
+ | null
9
+ | undefined
10
+ | MuscatVitePluginOption[];
11
+
12
+ export interface MuscatReactOptions {
13
+ jsxImportSource?: string;
14
+ babel?: {
15
+ plugins?: unknown[];
16
+ [key: string]: unknown;
17
+ };
18
+ [key: string]: unknown;
19
+ }
20
+
21
+ export interface MuscatOptions {
22
+ react?: false | MuscatReactOptions;
23
+ }
24
+
25
+ export declare function muscat(options?: MuscatOptions): MuscatVitePluginOption[];
package/cli/vite.mjs ADDED
@@ -0,0 +1,271 @@
1
+ import react from "@vitejs/plugin-react";
2
+ import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";
3
+ import postcss from "postcss";
4
+ import { createRequire } from "node:module";
5
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
6
+ import { basename, extname, resolve } from "node:path";
7
+
8
+
9
+ const HOST_PROVIDED_EXTERNALS = [
10
+ /^react(\/.*)?$/,
11
+ /^react-dom(\/.*)?$/,
12
+ /^@rainbow-robotics\/plugin-ui(\/.*)?$/,
13
+ /^@repo\/rb-components(\/.*)?$/,
14
+ ];
15
+
16
+ const UI_ENTRY_PREFIX = "muscat-ui-entry:";
17
+ const RESOLVED_UI_ENTRY_PREFIX = "\0" + UI_ENTRY_PREFIX;
18
+ const SHARED_RUNTIME_PREFIX = "muscat-shared-runtime:";
19
+ const RESOLVED_SHARED_RUNTIME_PREFIX = "\0" + SHARED_RUNTIME_PREFIX;
20
+ const STYLE_EXTENSIONS = [".css", ".scss", ".sass", ".less"];
21
+ const SHARED_RUNTIME_FILES = {
22
+ react: "react",
23
+ "react/jsx-runtime": "react_jsx-runtime",
24
+ "react-dom": "react-dom",
25
+ "react-dom/client": "react-dom_client",
26
+ "@rainbow-robotics/plugin-ui/react": "plugin-ui_react",
27
+ "@rainbow-robotics/plugin-ui/sdk": "plugin-ui_sdk",
28
+ "@rainbow-robotics/plugin-ui/host-ui": "plugin-ui_host-ui",
29
+ "@rainbow-robotics/plugin-ui/ws": "plugin-ui_ws",
30
+ };
31
+
32
+ function cssString(value) {
33
+ return String(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\a ");
34
+ }
35
+
36
+ function readPluginId(root) {
37
+ try {
38
+ const manifest = JSON.parse(readFileSync(resolve(root, "manifest.json"), "utf8"));
39
+ return typeof manifest.id === "string" && manifest.id ? manifest.id : null;
40
+ } catch {
41
+ return null;
42
+ }
43
+ }
44
+
45
+ function pluginScopeSelector(pluginId) {
46
+ if (!pluginId) return ":where([data-muscat-plugin-root])";
47
+ return `:where([data-muscat-plugin-id="${cssString(pluginId)}"])`;
48
+ }
49
+
50
+ function discoverUiEntries(uiDir) {
51
+ return Object.fromEntries(
52
+ readdirSync(uiDir)
53
+ .filter((f) => /\.(tsx?|jsx?)$/.test(f))
54
+ .map((f) => [basename(f, extname(f)), resolve(uiDir, f)]),
55
+ );
56
+ }
57
+
58
+ function discoverUiStyles(uiDir, entryName) {
59
+ return STYLE_EXTENSIONS.flatMap((ext) => [
60
+ resolve(uiDir, `style${ext}`),
61
+ resolve(uiDir, `styles${ext}`),
62
+ resolve(uiDir, `${entryName}${ext}`),
63
+ ]).filter((file, index, files) => existsSync(file) && files.indexOf(file) === index);
64
+ }
65
+
66
+ function isKeyframesRule(rule) {
67
+ for (let node = rule.parent; node; node = node.parent) {
68
+ if (node.type === "atrule" && /keyframes$/i.test(node.name)) return true;
69
+ }
70
+ return false;
71
+ }
72
+
73
+ function scopeSelector(selector, rootSelector) {
74
+ const trimmed = selector.trim();
75
+ if (
76
+ !trimmed ||
77
+ trimmed.includes("[data-muscat-plugin-root]") ||
78
+ trimmed.includes("[data-muscat-plugin-id")
79
+ ) {
80
+ return selector;
81
+ }
82
+ if (/^(:root|:host)\b/.test(trimmed)) {
83
+ return trimmed.replace(/^(:root|:host)\b/, rootSelector);
84
+ }
85
+ if (/^(html|body)\b/.test(trimmed)) {
86
+ return trimmed.replace(/^(html|body)\b/, rootSelector);
87
+ }
88
+ return `${rootSelector} ${trimmed}`;
89
+ }
90
+
91
+ function scopePluginCss(css, rootSelector) {
92
+ if (!css.trim()) return css;
93
+ const root = postcss.parse(css);
94
+ root.walkRules((rule) => {
95
+ if (isKeyframesRule(rule)) return;
96
+ rule.selectors = rule.selectors.map((selector) => scopeSelector(selector, rootSelector));
97
+ });
98
+ return root.toString();
99
+ }
100
+
101
+ function createUiEntryPlugin(uiDir, entries) {
102
+ return {
103
+ name: "muscat-ui-entry",
104
+ enforce: "pre",
105
+ resolveId(id) {
106
+ if (id.startsWith(UI_ENTRY_PREFIX)) return "\0" + id;
107
+ },
108
+ load(id) {
109
+ if (!id.startsWith(RESOLVED_UI_ENTRY_PREFIX)) return;
110
+ const entryName = id.slice(RESOLVED_UI_ENTRY_PREFIX.length);
111
+ const entry = entries[entryName];
112
+ if (!entry) throw new Error(`Unknown Muscat UI entry: ${entryName}`);
113
+
114
+ const styleImports = discoverUiStyles(uiDir, entryName)
115
+ .map((file) => {
116
+ this.addWatchFile(file);
117
+ return `import ${JSON.stringify(file)};`;
118
+ })
119
+ .join("\n");
120
+
121
+ return `${styleImports}\nexport { default } from ${JSON.stringify(entry)};\n`;
122
+ },
123
+ };
124
+ }
125
+
126
+ function resolveFromPlugin(root, specifier) {
127
+ try {
128
+ return createRequire(resolve(root, "package.json")).resolve(specifier);
129
+ } catch {
130
+ return null;
131
+ }
132
+ }
133
+
134
+ function exactSpecifier(specifier) {
135
+ return new RegExp(`^${specifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`);
136
+ }
137
+
138
+ function reactAliases(root) {
139
+ return [
140
+ "react",
141
+ "react/jsx-runtime",
142
+ "react/jsx-dev-runtime",
143
+ "react-dom",
144
+ "react-dom/client",
145
+ ].flatMap((specifier) => {
146
+ const resolved = resolveFromPlugin(root, specifier);
147
+ return resolved ? [{ find: exactSpecifier(specifier), replacement: resolved }] : [];
148
+ });
149
+ }
150
+
151
+ function createSharedRuntimePlugin(baseUrl) {
152
+ const base = baseUrl.replace(/\/$/, "");
153
+
154
+ return {
155
+ name: "muscat-shared-runtime",
156
+ enforce: "pre",
157
+ resolveId(id) {
158
+ if (id in SHARED_RUNTIME_FILES) return "\0" + SHARED_RUNTIME_PREFIX + id;
159
+ },
160
+ load(id) {
161
+ if (!id.startsWith(RESOLVED_SHARED_RUNTIME_PREFIX)) return;
162
+ const specifier = id.slice(RESOLVED_SHARED_RUNTIME_PREFIX.length);
163
+ const file = SHARED_RUNTIME_FILES[specifier];
164
+ if (!file) throw new Error(`Unknown Muscat shared runtime module: ${specifier}`);
165
+
166
+ const url = JSON.stringify(`${base}/${file}.js`);
167
+ if (specifier === "react" || specifier === "react-dom") {
168
+ return `export * from ${url};\nimport sharedDefault from ${url};\nexport default sharedDefault;\n`;
169
+ }
170
+ return `export * from ${url};\n`;
171
+ },
172
+ };
173
+ }
174
+
175
+ const REACT_REFRESH_ACCEPT_MARKER =
176
+ "\nif (import.meta.hot && !inWebWorker) {\n RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {";
177
+
178
+ function createManualHmrBoundaryPlugin(uiDir) {
179
+ const normalizedUiDir = uiDir.replace(/\/$/, "");
180
+
181
+ return {
182
+ name: "muscat-manual-hmr-boundary",
183
+ apply: "serve",
184
+ enforce: "post",
185
+ transform(code, id) {
186
+ const [file] = id.split("?");
187
+ if (!file.startsWith(`${normalizedUiDir}/`) || !/\.[jt]sx?$/.test(file)) return null;
188
+
189
+ const markerIndex = code.lastIndexOf(REACT_REFRESH_ACCEPT_MARKER);
190
+ if (markerIndex === -1) return null;
191
+
192
+ // preview-host provides the same production ReactDOM as Nexus. Vite's
193
+ // React Fast Refresh receives updates but cannot drive that renderer, so
194
+ // let the bootstrap module handle HMR by re-rendering the updated entry.
195
+ return { code: code.slice(0, markerIndex), map: null };
196
+ },
197
+ };
198
+ }
199
+
200
+ export function muscat(options = {}) {
201
+ const pluginRoot = process.cwd();
202
+ const uiDir = resolve(pluginRoot, "ui");
203
+ const entries = discoverUiEntries(uiDir);
204
+ const rootSelector = pluginScopeSelector(readPluginId(pluginRoot));
205
+ const sharedRuntimeBase = process.env.MUSCAT_PLUGIN_SHARED_RUNTIME_BASE;
206
+ const wrappedEntries = Object.fromEntries(
207
+ Object.keys(entries).map((name) => [name, `${UI_ENTRY_PREFIX}${name}`]),
208
+ );
209
+ const reactPlugins = options.react === false ? [] : [react(options.react)];
210
+
211
+ return [
212
+ ...reactPlugins,
213
+ createUiEntryPlugin(uiDir, entries),
214
+ ...(sharedRuntimeBase ? [createSharedRuntimePlugin(sharedRuntimeBase)] : []),
215
+ ...(sharedRuntimeBase ? [createManualHmrBoundaryPlugin(uiDir)] : []),
216
+ cssInjectedByJsPlugin({
217
+ relativeCSSInjection: true,
218
+ preRenderCSSCode: (css) => scopePluginCss(css, rootSelector),
219
+ }),
220
+ {
221
+ name: "muscat-plugin-build",
222
+ apply: "build",
223
+ config: () => ({
224
+ build: {
225
+ target: "esnext",
226
+ outDir: "dist",
227
+ emptyOutDir: false,
228
+ rollupOptions: {
229
+ input: wrappedEntries,
230
+ external: HOST_PROVIDED_EXTERNALS,
231
+ // Entries only `export default App` (the host mounts it). Without
232
+ // this, Vite treats entries as self-executing apps and tree-shakes
233
+ // the unused default export away.
234
+ preserveEntrySignatures: "strict",
235
+ output: {
236
+ format: "es",
237
+ entryFileNames: "[name].js",
238
+ chunkFileNames: "chunks/[name]-[hash].js",
239
+ assetFileNames: "assets/[name]-[hash][extname]",
240
+ },
241
+ },
242
+ },
243
+ }),
244
+ },
245
+ {
246
+ name: "muscat-plugin-dev",
247
+ apply: "serve",
248
+ config: () => {
249
+ return {
250
+ resolve: {
251
+ alias: sharedRuntimeBase ? [] : reactAliases(pluginRoot),
252
+ dedupe: ["react", "react-dom"],
253
+ },
254
+ optimizeDeps: sharedRuntimeBase
255
+ ? { noDiscovery: true, include: [] }
256
+ : {
257
+ include: [
258
+ "react",
259
+ "react-dom",
260
+ "react-dom/client",
261
+ "@rainbow-robotics/plugin-ui/react",
262
+ "@rainbow-robotics/plugin-ui/sdk",
263
+ "@rainbow-robotics/plugin-ui/host-ui",
264
+ "@rainbow-robotics/plugin-ui/ws",
265
+ ],
266
+ },
267
+ };
268
+ },
269
+ },
270
+ ];
271
+ }