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

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 (240) 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 +54 -11
  8. package/cli/src/devUi.mjs +100 -34
  9. package/cli/src/manifest.mjs +15 -0
  10. package/cli/src/mcp.mjs +534 -0
  11. package/cli/src/new.mjs +16 -1
  12. package/cli/src/pluginDevServer.mjs +113 -0
  13. package/cli/src/ports.mjs +160 -0
  14. package/cli/src/sdk.mjs +11 -9
  15. package/cli/src/storybook.mjs +168 -0
  16. package/cli/src/templates-embedded.mjs +1 -1
  17. package/cli/src/util.mjs +29 -0
  18. package/cli/storybook-dist/_design-tokens.css +4957 -0
  19. package/cli/storybook-dist/_stories-src/NxAvatar.stories.tsx +27 -0
  20. package/cli/storybook-dist/_stories-src/NxPagination.stories.tsx +28 -0
  21. package/cli/storybook-dist/_stories-src/RBAccordion/RBAccordion.stories.tsx +46 -0
  22. package/cli/storybook-dist/_stories-src/RBAccordion/RBAccordionGroup.stories.tsx +73 -0
  23. package/cli/storybook-dist/_stories-src/RBBadge/RBBadge.stories.tsx +93 -0
  24. package/cli/storybook-dist/_stories-src/RBBattery/RBBattery.stories.tsx +74 -0
  25. package/cli/storybook-dist/_stories-src/RBButton/RBCheckIconButton.stories.tsx +28 -0
  26. package/cli/storybook-dist/_stories-src/RBButton/RBCheckLabelButton.stories.tsx +84 -0
  27. package/cli/storybook-dist/_stories-src/RBButton/RBIconButton.stories.tsx +57 -0
  28. package/cli/storybook-dist/_stories-src/RBButton/RBInlineLabelButton.stories.tsx +41 -0
  29. package/cli/storybook-dist/_stories-src/RBButton/RBLabelButton.stories.tsx +60 -0
  30. package/cli/storybook-dist/_stories-src/RBDatePicker/RBDateInput.stories.tsx +44 -0
  31. package/cli/storybook-dist/_stories-src/RBDatePicker/RBRangeDateInput.stories.tsx +44 -0
  32. package/cli/storybook-dist/_stories-src/RBDialog/RBAlert.stories.tsx +51 -0
  33. package/cli/storybook-dist/_stories-src/RBDialog/RBConfirm.stories.tsx +55 -0
  34. package/cli/storybook-dist/_stories-src/RBDialog/RBPrompt.stories.tsx +52 -0
  35. package/cli/storybook-dist/_stories-src/RBDivider/RBDivider.stories.tsx +93 -0
  36. package/cli/storybook-dist/_stories-src/RBEmptyView/RBEmptyView.stories.tsx +49 -0
  37. package/cli/storybook-dist/_stories-src/RBIcons/RBColorIcons.stories.tsx +108 -0
  38. package/cli/storybook-dist/_stories-src/RBIcons/RBIcons.stories.tsx +106 -0
  39. package/cli/storybook-dist/_stories-src/RBIcons/RBMenuTreeIcons.stories.tsx +108 -0
  40. package/cli/storybook-dist/_stories-src/RBIcons/RBProgramIcons.stories.tsx +116 -0
  41. package/cli/storybook-dist/_stories-src/RBInput/RBCheckBox.stories.tsx +89 -0
  42. package/cli/storybook-dist/_stories-src/RBInput/RBMultiRangeInput.stories.tsx +64 -0
  43. package/cli/storybook-dist/_stories-src/RBInput/RBRadioBox.stories.tsx +65 -0
  44. package/cli/storybook-dist/_stories-src/RBInput/RBRadioButton.stories.tsx +68 -0
  45. package/cli/storybook-dist/_stories-src/RBInput/RBSelectBox.stories.tsx +119 -0
  46. package/cli/storybook-dist/_stories-src/RBInput/RBSideNumberInput.stories.tsx +90 -0
  47. package/cli/storybook-dist/_stories-src/RBInput/RBText/RBTextArea.stories.tsx +45 -0
  48. package/cli/storybook-dist/_stories-src/RBInput/RBText/RBTextInput.stories.tsx +50 -0
  49. package/cli/storybook-dist/_stories-src/RBInput/RBTextField.stories.tsx +102 -0
  50. package/cli/storybook-dist/_stories-src/RBJoyStick/RBJoyStick.stories.tsx +31 -0
  51. package/cli/storybook-dist/_stories-src/RBLight/RBLight.stories.tsx +36 -0
  52. package/cli/storybook-dist/_stories-src/RBPagination/RBPagination.stories.tsx +49 -0
  53. package/cli/storybook-dist/_stories-src/RBShadcn/RBCard/RBCard.stories.tsx +89 -0
  54. package/cli/storybook-dist/_stories-src/RBShadcn/RBCommand/RBCommand.stories.tsx +116 -0
  55. package/cli/storybook-dist/_stories-src/RBShadcn/RBDialog/RBDialog.stories.tsx +74 -0
  56. package/cli/storybook-dist/_stories-src/RBShadcn/RBDrawer/RBDrawer.stories.tsx +99 -0
  57. package/cli/storybook-dist/_stories-src/RBShadcn/RBDropdownMenu/RBDropdownMenu.stories.tsx +123 -0
  58. package/cli/storybook-dist/_stories-src/RBShadcn/RBMenubar/RBMenubar.stories.tsx +135 -0
  59. package/cli/storybook-dist/_stories-src/RBShadcn/RBPopover/RBPopover.stories.tsx +69 -0
  60. package/cli/storybook-dist/_stories-src/RBShadcn/RBResizable/RBResizable.stories.tsx +49 -0
  61. package/cli/storybook-dist/_stories-src/RBShadcn/RBSheet/RBSheet.stories.tsx +91 -0
  62. package/cli/storybook-dist/_stories-src/RBShadcn/RBSlider/RBSlider.stories.tsx +38 -0
  63. package/cli/storybook-dist/_stories-src/RBShadcn/RBSwitch/RBSwitch.stories.tsx +112 -0
  64. package/cli/storybook-dist/_stories-src/RBShadcn/RBTabs/RBTabs.stories.tsx +75 -0
  65. package/cli/storybook-dist/_stories-src/RBShadcn/RBToggle/RBToggle.stories.tsx +51 -0
  66. package/cli/storybook-dist/_stories-src/RBShadcn/RBToggleGroup/RBToggleGroup.stories.tsx +84 -0
  67. package/cli/storybook-dist/_stories-src/RBTab/RBChipTab.stories.tsx +102 -0
  68. package/cli/storybook-dist/_stories-src/RBTab/RBChipsBoxTab.stories.tsx +78 -0
  69. package/cli/storybook-dist/_stories-src/RBTab/RBTab.stories.tsx +57 -0
  70. package/cli/storybook-dist/_stories-src/RBTable/RBTable.stories.tsx +177 -0
  71. package/cli/storybook-dist/_stories-src/RBTable/RBTableRow.stories.tsx +64 -0
  72. package/cli/storybook-dist/_stories-src/RBToast/RBToast.stories.tsx +117 -0
  73. package/cli/storybook-dist/_stories-src/RBTooltip/RBTooltip.stories.tsx +50 -0
  74. package/cli/storybook-dist/_stories-src/loading/RBSpinner.stories.tsx +30 -0
  75. package/cli/storybook-dist/_stories-src/nx-button/NxButton.stories.tsx +54 -0
  76. package/cli/storybook-dist/_stories-src/nx-button/NxPointerHoldButton.stories.tsx +57 -0
  77. package/cli/storybook-dist/_stories-src/nx-icons/NxIcons.stories.tsx +48 -0
  78. package/cli/storybook-dist/_stories-src/nx-inputs/NxNumberInput.stories.tsx +103 -0
  79. package/cli/storybook-dist/_stories-src/nx-inputs/NxRangeInput.stories.tsx +27 -0
  80. package/cli/storybook-dist/_stories-src/nx-inputs/NxSelectBox.stories.tsx +67 -0
  81. package/cli/storybook-dist/_stories-src/nx-inputs/NxSlideRange.stories.tsx +45 -0
  82. package/cli/storybook-dist/_stories-src/nx-inputs/NxSwitch.stories.tsx +27 -0
  83. package/cli/storybook-dist/_stories-src/nx-inputs/NxTextArea.stories.tsx +48 -0
  84. package/cli/storybook-dist/_stories-src/nx-inputs/NxTextInput.stories.tsx +46 -0
  85. package/cli/storybook-dist/assets/Color-YHDXOIA2-BjuzF3Je.js +1 -0
  86. package/cli/storybook-dist/assets/Docs-BAFZYTMR.js +12 -0
  87. package/cli/storybook-dist/assets/Docs-BQesYW-Q.js +8 -0
  88. package/cli/storybook-dist/assets/Docs-BsMEe093.js +7 -0
  89. package/cli/storybook-dist/assets/Docs-By6k6vcM.js +20 -0
  90. package/cli/storybook-dist/assets/Docs-D1J63cJc.js +7 -0
  91. package/cli/storybook-dist/assets/Docs-GoNbntAU.js +8 -0
  92. package/cli/storybook-dist/assets/DocsRenderer-CFRXHY34-BwY_WiM7.js +2 -0
  93. package/cli/storybook-dist/assets/NxAvatar.stories-CvzBHfYa.js +13 -0
  94. package/cli/storybook-dist/assets/NxButton.stories-B83PesgN.js +20 -0
  95. package/cli/storybook-dist/assets/NxIcons.stories-Ca7qpAaO.js +3 -0
  96. package/cli/storybook-dist/assets/NxNumberInput.stories-DpNcCG6B.js +26 -0
  97. package/cli/storybook-dist/assets/NxPagination.stories-Xnvd3xhH.js +11 -0
  98. package/cli/storybook-dist/assets/NxPointerHoldButton.stories-C3YSIpM0.js +14 -0
  99. package/cli/storybook-dist/assets/NxRangeInput.stories-DIhaNZig.js +17 -0
  100. package/cli/storybook-dist/assets/NxSelectBox.stories-BGwO2mYJ.js +17 -0
  101. package/cli/storybook-dist/assets/NxSlideRange.stories-BXlt5Bgt.js +14 -0
  102. package/cli/storybook-dist/assets/NxSwitch.stories-C5ZqIRtw.js +11 -0
  103. package/cli/storybook-dist/assets/NxTextArea.stories-hm_ycALo.js +11 -0
  104. package/cli/storybook-dist/assets/NxTextInput.stories-DkZAySr_.js +11 -0
  105. package/cli/storybook-dist/assets/PretendardVariable-CJuje-Rk.woff2 +0 -0
  106. package/cli/storybook-dist/assets/RBAccordion.stories--bY36GZY.js +17 -0
  107. package/cli/storybook-dist/assets/RBAccordionGroup.stories-BVr1ccI4.js +33 -0
  108. package/cli/storybook-dist/assets/RBAlert.stories-CkjFBEkv.js +17 -0
  109. package/cli/storybook-dist/assets/RBBadge.stories-CNXILDPh.js +1 -0
  110. package/cli/storybook-dist/assets/RBBattery.stories-AokMv8ZY.js +10 -0
  111. package/cli/storybook-dist/assets/RBCard.stories-CX1sLKB2.js +45 -0
  112. package/cli/storybook-dist/assets/RBCheckBox.stories-By3QHBFm.js +1 -0
  113. package/cli/storybook-dist/assets/RBCheckIconButton.stories-Dud1uK3X.js +1 -0
  114. package/cli/storybook-dist/assets/RBCheckLabelButton.stories-C8iBkZxY.js +24 -0
  115. package/cli/storybook-dist/assets/RBChipTab.stories-DsgbiS2U.js +21 -0
  116. package/cli/storybook-dist/assets/RBChipsBoxTab.stories-C3DZGmq0.js +1 -0
  117. package/cli/storybook-dist/assets/RBColorIcons.stories-CusR20qk.js +3 -0
  118. package/cli/storybook-dist/assets/RBCommand.stories-DhJNgaLZ.js +73 -0
  119. package/cli/storybook-dist/assets/RBConfirm.stories-B6LKpCDa.js +20 -0
  120. package/cli/storybook-dist/assets/RBDateInput.stories-PEEhQ1wJ.js +15 -0
  121. package/cli/storybook-dist/assets/RBDialog.stories-CAtOdRen.js +38 -0
  122. package/cli/storybook-dist/assets/RBDivider.stories-0zpIUlXT.js +1 -0
  123. package/cli/storybook-dist/assets/RBDrawer.stories-CWMG4glY.js +14 -0
  124. package/cli/storybook-dist/assets/RBDropdownMenu.stories-6fbEYZfk.js +86 -0
  125. package/cli/storybook-dist/assets/RBEmptyView.stories-BRDZHjn4.js +12 -0
  126. package/cli/storybook-dist/assets/RBIconButton.stories-sYrRLYob.js +1 -0
  127. package/cli/storybook-dist/assets/RBIcons.stories-DFe8O1_g.js +3 -0
  128. package/cli/storybook-dist/assets/RBInlineLabelButton.stories-DX4VdUfk.js +1 -0
  129. package/cli/storybook-dist/assets/RBJoyStick.stories-SA2Foelf.js +11 -0
  130. package/cli/storybook-dist/assets/RBLabelButton.stories-CicBns_Y.js +1 -0
  131. package/cli/storybook-dist/assets/RBLight.stories-WlP3oEmY.js +1 -0
  132. package/cli/storybook-dist/assets/RBMenuTreeIcons.stories-CrWjPfxj.js +3 -0
  133. package/cli/storybook-dist/assets/RBMenubar.stories-Di4phWw7.js +3 -0
  134. package/cli/storybook-dist/assets/RBMultiRangeInput.stories-DS3wrR3l.js +14 -0
  135. package/cli/storybook-dist/assets/RBPagination.stories-BDVPAUVD.js +17 -0
  136. package/cli/storybook-dist/assets/RBPopover.stories-DL9b_iX9.js +11 -0
  137. package/cli/storybook-dist/assets/RBProgramIcons.stories-ByRVx-on.js +3 -0
  138. package/cli/storybook-dist/assets/RBPrompt.stories-vTmKWyA5.js +20 -0
  139. package/cli/storybook-dist/assets/RBRadioBox.stories-C9WHt4jb.js +1 -0
  140. package/cli/storybook-dist/assets/RBRadioButton.stories-D8KYq63j.js +11 -0
  141. package/cli/storybook-dist/assets/RBRangeDateInput.stories-Bvcf4Su7.js +15 -0
  142. package/cli/storybook-dist/assets/RBResizable.stories-3O2OMuH_.js +20 -0
  143. package/cli/storybook-dist/assets/RBSelectBox.stories-CKZLmPzX.js +6 -0
  144. package/cli/storybook-dist/assets/RBSheet.stories-Dko0It1W.js +39 -0
  145. package/cli/storybook-dist/assets/RBSideNumberInput.stories-CUvqVtId.js +5 -0
  146. package/cli/storybook-dist/assets/RBSlider.stories-CcbaKRYo.js +5 -0
  147. package/cli/storybook-dist/assets/RBSpinner.stories-D15e_JlE.js +14 -0
  148. package/cli/storybook-dist/assets/RBSwitch.stories-C4JRsYJ6.js +65 -0
  149. package/cli/storybook-dist/assets/RBTab.stories-BPvzQSM-.js +1 -0
  150. package/cli/storybook-dist/assets/RBTable.stories-nr8OS1mV.js +62 -0
  151. package/cli/storybook-dist/assets/RBTableRow.stories-rI0rK8Ci.js +11 -0
  152. package/cli/storybook-dist/assets/RBTabs.stories-CxMtHGWA.js +21 -0
  153. package/cli/storybook-dist/assets/RBTextArea.stories-Bru4AhJ3.js +5 -0
  154. package/cli/storybook-dist/assets/RBTextField.stories-Ah3D9lto.js +45 -0
  155. package/cli/storybook-dist/assets/RBTextInput.stories-C3qAVngJ.js +5 -0
  156. package/cli/storybook-dist/assets/RBToast.stories-C1occsvf.js +11 -0
  157. package/cli/storybook-dist/assets/RBToggle.stories-BNrNERc7.js +12 -0
  158. package/cli/storybook-dist/assets/RBToggleGroup.stories-D_RRBwxY.js +17 -0
  159. package/cli/storybook-dist/assets/RBTooltip.stories-DuyOQqrB.js +9 -0
  160. package/cli/storybook-dist/assets/RainbowUiProvider-BYlbsa69.css +1 -0
  161. package/cli/storybook-dist/assets/RainbowUiProvider-B_piZBLb.js +31 -0
  162. package/cli/storybook-dist/assets/browserUtils-DeopUpDy.js +1 -0
  163. package/cli/storybook-dist/assets/chunk-XP5HYGXS-BHXC9YeQ.js +1 -0
  164. package/cli/storybook-dist/assets/client-DTf7SId2.js +1 -0
  165. package/cli/storybook-dist/assets/createConveyorBeltLayer-Cn41pFRH.js +6210 -0
  166. package/cli/storybook-dist/assets/createConveyorBeltLayer-Ds5AOper.css +21 -0
  167. package/cli/storybook-dist/assets/entry-preview-D-mLV0cS.js +2 -0
  168. package/cli/storybook-dist/assets/entry-preview-docs-b8bpVBXy.js +46 -0
  169. package/cli/storybook-dist/assets/iframe-DNru2eN7.js +211 -0
  170. package/cli/storybook-dist/assets/index-B4FGfHer.js +1 -0
  171. package/cli/storybook-dist/assets/index-BRq5TIsn.js +24 -0
  172. package/cli/storybook-dist/assets/index-C1OzuK6-.js +240 -0
  173. package/cli/storybook-dist/assets/index-CT3U1fyk.js +1 -0
  174. package/cli/storybook-dist/assets/index-ChsGqxH_.js +9 -0
  175. package/cli/storybook-dist/assets/index-Cwr2bQOB.js +575 -0
  176. package/cli/storybook-dist/assets/index-DKFBREX_.js +1 -0
  177. package/cli/storybook-dist/assets/index-DgH-xKnr.js +11 -0
  178. package/cli/storybook-dist/assets/index-Dmy2JGbm.js +1 -0
  179. package/cli/storybook-dist/assets/index-DrFu-skq.js +6 -0
  180. package/cli/storybook-dist/assets/jsx-runtime-BTJTZTIL.js +9 -0
  181. package/cli/storybook-dist/assets/keymapTileIndex.worker-BsNYNbqs.js +1 -0
  182. package/cli/storybook-dist/assets/preview-B8lJiyuQ.js +34 -0
  183. package/cli/storybook-dist/assets/preview-BBWR9nbA.js +1 -0
  184. package/cli/storybook-dist/assets/preview-BWzBA1C2.js +396 -0
  185. package/cli/storybook-dist/assets/preview-CILRoSnB.js +1 -0
  186. package/cli/storybook-dist/assets/preview-CVgpLj3b.js +1 -0
  187. package/cli/storybook-dist/assets/preview-CvbIS5ZJ.js +1 -0
  188. package/cli/storybook-dist/assets/preview-DD_OYowb.js +1 -0
  189. package/cli/storybook-dist/assets/preview-DGUiP6tS.js +7 -0
  190. package/cli/storybook-dist/assets/preview-DHQbi4pV.js +1 -0
  191. package/cli/storybook-dist/assets/preview-DUTcCPBe.css +1 -0
  192. package/cli/storybook-dist/assets/preview-QAsoD6Sa.js +2 -0
  193. package/cli/storybook-dist/assets/preview-rcRMbKPr.js +3 -0
  194. package/cli/storybook-dist/assets/react-18-hB3smqWJ.js +1 -0
  195. package/cli/storybook-dist/assets/react-resizable-panels.browser-CvAJUcrm.js +72 -0
  196. package/cli/storybook-dist/assets/test-utils-BQudk2xt.js +9 -0
  197. package/cli/storybook-dist/favicon.svg +1 -0
  198. package/cli/storybook-dist/iframe.html +666 -0
  199. package/cli/storybook-dist/index.html +190 -0
  200. package/cli/storybook-dist/index.json +1 -0
  201. package/cli/storybook-dist/nunito-sans-bold-italic.woff2 +0 -0
  202. package/cli/storybook-dist/nunito-sans-bold.woff2 +0 -0
  203. package/cli/storybook-dist/nunito-sans-italic.woff2 +0 -0
  204. package/cli/storybook-dist/nunito-sans-regular.woff2 +0 -0
  205. package/cli/storybook-dist/project.json +1 -0
  206. package/cli/storybook-dist/sb-addons/chromatic-com-storybook-10/manager-bundle.js +331 -0
  207. package/cli/storybook-dist/sb-addons/chromatic-com-storybook-10/manager-bundle.js.LEGAL.txt +51 -0
  208. package/cli/storybook-dist/sb-addons/essentials-actions-3/manager-bundle.js +3 -0
  209. package/cli/storybook-dist/sb-addons/essentials-backgrounds-5/manager-bundle.js +12 -0
  210. package/cli/storybook-dist/sb-addons/essentials-controls-2/manager-bundle.js +405 -0
  211. package/cli/storybook-dist/sb-addons/essentials-docs-4/manager-bundle.js +245 -0
  212. package/cli/storybook-dist/sb-addons/essentials-measure-8/manager-bundle.js +3 -0
  213. package/cli/storybook-dist/sb-addons/essentials-outline-9/manager-bundle.js +3 -0
  214. package/cli/storybook-dist/sb-addons/essentials-toolbars-7/manager-bundle.js +3 -0
  215. package/cli/storybook-dist/sb-addons/essentials-viewport-6/manager-bundle.js +3 -0
  216. package/cli/storybook-dist/sb-addons/links-1/manager-bundle.js +3 -0
  217. package/cli/storybook-dist/sb-addons/storybook-13/manager-bundle.js +3 -0
  218. package/cli/storybook-dist/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +3 -0
  219. package/cli/storybook-dist/sb-addons/storybook-experimental-addon-test-12/manager-bundle.js +223 -0
  220. package/cli/storybook-dist/sb-addons/themes-11/manager-bundle.js +3 -0
  221. package/cli/storybook-dist/sb-common-assets/favicon.svg +1 -0
  222. package/cli/storybook-dist/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  223. package/cli/storybook-dist/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  224. package/cli/storybook-dist/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  225. package/cli/storybook-dist/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  226. package/cli/storybook-dist/sb-manager/globals-module-info.js +1052 -0
  227. package/cli/storybook-dist/sb-manager/globals-runtime.js +41775 -0
  228. package/cli/storybook-dist/sb-manager/globals.js +48 -0
  229. package/cli/storybook-dist/sb-manager/runtime.js +12048 -0
  230. package/cli/templates/common/.mcp.json +8 -0
  231. package/cli/templates/common/README.md +467 -53
  232. package/cli/templates/common/assets/icon.svg +44 -2
  233. package/cli/templates/common/package.json +4 -0
  234. package/cli/templates/common/ui/content.tsx +209 -26
  235. package/cli/templates/common/ui/style.css +6 -0
  236. package/cli/templates/common/vite.config.ts +6 -34
  237. package/cli/templates/cpp/cpp/main.cpp +1 -0
  238. package/cli/vite.d.mts +25 -0
  239. package/cli/vite.mjs +271 -0
  240. package/package.json +31 -4
package/cli/src/devUi.mjs CHANGED
@@ -1,20 +1,35 @@
1
- // muscat-pk dev:ui — preview the plugin inside a mini-Muscat (preview-host).
2
- // UI bundling: vite build --watch (uses plugin project's own node_modules/vite).
3
- // Falls back gracefully if Node.js or vite is not available.
1
+
4
2
  import { spawn, spawnSync } from "node:child_process";
3
+ import { createServer as createNetServer } from "node:net";
5
4
  import { createRequire } from "node:module";
6
- import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
5
+ import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, rmSync, watch } from "node:fs";
7
6
  import { homedir } from "node:os";
8
7
  import { dirname, resolve } from "node:path";
9
- import { SANDBOX_HTML } from "./build.mjs";
8
+ import { fileURLToPath } from "node:url";
10
9
  import { checkKitUpdate, findPluginRoot, hasBin, kitRoot, log, parseArgs, prompt } from "./util.mjs";
11
10
 
11
+
12
+ const DEV_PLUGIN_PORT = 4181;
13
+
14
+ function getFreePort(preferred) {
15
+ return new Promise((res) => {
16
+ const srv = createNetServer();
17
+ srv.once("error", () => {
18
+ const s2 = createNetServer();
19
+ s2.listen(0, () => {
20
+ const { port } = s2.address();
21
+ s2.close(() => res(port));
22
+ });
23
+ });
24
+ srv.listen(preferred, () => srv.close(() => res(preferred)));
25
+ });
26
+ }
27
+
12
28
  const PREVIEW_PKG = "@rainbow-robotics/preview-host";
13
29
  const CACHE_DIR = resolve(homedir(), ".muscat-pk");
14
30
  const CACHE_ROOT = resolve(CACHE_DIR, "node_modules", "@rainbow-robotics", "preview-host");
15
31
 
16
- // Dev builds go to a throwaway dir, not dist/ — dist/ is reserved for
17
- // build/pack output (the shippable artifact).
32
+
18
33
  const DEV_OUT = ".muscat-dev";
19
34
 
20
35
  function findNodeBin() {
@@ -56,17 +71,28 @@ function findPreviewHostRoot() {
56
71
  return CACHE_ROOT;
57
72
  }
58
73
 
59
- // Write sandbox.html + copy manifest into the dev out dir (vite doesn't generate these).
74
+ function syncAssets(pluginRoot, outDir) {
75
+ const assetsSrc = resolve(pluginRoot, "assets");
76
+ if (existsSync(assetsSrc)) cpSync(assetsSrc, resolve(outDir, "assets"), { recursive: true });
77
+ }
78
+
79
+
60
80
  function stageDevAssets(pluginRoot) {
61
81
  const outDir = resolve(pluginRoot, DEV_OUT);
62
82
  mkdirSync(outDir, { recursive: true });
63
- writeFileSync(resolve(outDir, "sandbox.html"), SANDBOX_HTML, "utf8");
64
83
  const manifestSrc = resolve(pluginRoot, "manifest.json");
65
84
  if (existsSync(manifestSrc)) copyFileSync(manifestSrc, resolve(outDir, "manifest.json"));
85
+ syncAssets(pluginRoot, outDir);
66
86
  return outDir;
67
87
  }
68
88
 
69
- // Resolve vite bin path from the plugin root, hoisting-aware.
89
+ function watchAssets(pluginRoot, outDir) {
90
+ const assetsSrc = resolve(pluginRoot, "assets");
91
+ if (!existsSync(assetsSrc)) return;
92
+ watch(assetsSrc, { recursive: true }, () => syncAssets(pluginRoot, outDir));
93
+ }
94
+
95
+
70
96
  function findViteBin(pluginRoot) {
71
97
  try {
72
98
  const req = createRequire(resolve(pluginRoot, "package.json"));
@@ -77,53 +103,86 @@ function findViteBin(pluginRoot) {
77
103
  }
78
104
  }
79
105
 
80
- // Spawn vite build --watch as a background process.
81
- // Returns the child process, or null if vite/node not available.
82
- function spawnViteWatch(pluginRoot, node, { robotIp = "" } = {}) {
83
- const viteBin = findViteBin(pluginRoot);
84
- if (!node || !viteBin || !existsSync(viteBin)) return null;
85
106
 
86
- log.step(`vite build --watch (ui/content.tsx → ${DEV_OUT}/content.js)`);
87
- return spawn(node, [viteBin, "build", "--watch", "--mode", "development", "--outDir", DEV_OUT], {
107
+ function spawnPluginDevServer(pluginRoot, node, port, readyFile, sharedRuntimeBase) {
108
+ if (!node || !findViteBin(pluginRoot)) return null;
109
+ const runner = fileURLToPath(new URL("./pluginDevServer.mjs", import.meta.url));
110
+
111
+ rmSync(resolve(pluginRoot, "node_modules", ".vite"), { recursive: true, force: true });
112
+ log.step(`vite dev server (HMR) starting at :${port} — ui/*.tsx`);
113
+
114
+ return spawn(node, [runner, pluginRoot, String(port), readyFile], {
88
115
  cwd: pluginRoot,
89
116
  stdio: "inherit",
90
- env: { ...process.env, VITE_PLUGIN_PREVIEW: "true", ...(robotIp ? { VITE_RRS_PY_HOST: robotIp } : {}) },
117
+ env: {
118
+ ...process.env,
119
+ VITE_PLUGIN_PREVIEW: "true",
120
+ MUSCAT_PLUGIN_SHARED_RUNTIME_BASE: sharedRuntimeBase,
121
+ },
91
122
  });
92
123
  }
93
124
 
94
- // Wait until dist/content.js exists (vite initial build completes).
95
- function waitForInitialBuild(distDir, timeoutMs = 30_000) {
125
+ function waitForPluginDevPort(readyFile, proc, timeoutMs = 15_000) {
126
+ const start = Date.now();
96
127
  return new Promise((res, rej) => {
97
- const contentJs = resolve(distDir, "content.js");
98
- const start = Date.now();
99
- const check = () => {
100
- if (existsSync(contentJs)) return res();
101
- if (Date.now() - start > timeoutMs) return rej(new Error("vite initial build timed out"));
102
- setTimeout(check, 300);
128
+ let exited = false;
129
+ proc.once("exit", (code) => {
130
+ exited = true;
131
+ rej(new Error(`plugin dev server exited before ready (code ${code ?? 0})`));
132
+ });
133
+
134
+ const tick = () => {
135
+ if (existsSync(readyFile)) {
136
+ try {
137
+ const { port } = JSON.parse(readFileSync(readyFile, "utf8"));
138
+ if (Number.isInteger(port)) return res(port);
139
+ } catch {
140
+ }
141
+ }
142
+ if (Date.now() - start > timeoutMs)
143
+ return rej(new Error("plugin dev server did not become ready in time"));
144
+ if (!exited) setTimeout(tick, 100);
103
145
  };
104
- check();
146
+ tick();
105
147
  });
106
148
  }
107
149
 
108
150
  export async function runDevUi(args = []) {
109
151
  const parsed = parseArgs(args);
110
- const port = parsed.port ?? "4180";
152
+ const requestedPort = Number(parsed.port ?? "4180");
111
153
  const robotIp = parsed["robot-ip"] ?? process.env.MUSCAT_ROBOT_HOST ?? await prompt(" Robot IP (skip if no robot): ");
112
154
 
113
155
  await checkKitUpdate();
114
156
  const pluginRoot = findPluginRoot();
115
157
  const outDir = stageDevAssets(pluginRoot);
158
+ const port = await getFreePort(requestedPort);
159
+ if (port !== requestedPort)
160
+ log.warn(`preview-host port ${requestedPort} is in use — using ${port} instead.`);
116
161
 
117
162
  if (robotIp) log.info(`MUSCAT_API_ORIGIN → http://${robotIp}:*`);
118
163
 
164
+ watchAssets(pluginRoot, outDir);
165
+
119
166
  const node = findNodeBin();
120
- const viteProc = spawnViteWatch(pluginRoot, node, { robotIp });
167
+ const readyFile = resolve(outDir, "plugin-dev-port.json");
168
+ rmSync(readyFile, { force: true });
169
+ const sharedRuntimeBase = `http://localhost:${port}/plugin-shared`;
170
+ const viteProc = spawnPluginDevServer(
171
+ pluginRoot,
172
+ node,
173
+ DEV_PLUGIN_PORT,
174
+ readyFile,
175
+ sharedRuntimeBase,
176
+ );
177
+ let devPort = DEV_PLUGIN_PORT;
121
178
 
122
- if (viteProc) {
123
- log.step("waiting for initial vite build…");
124
- await waitForInitialBuild(outDir);
179
+ if (!viteProc) {
180
+ log.warn("vite not found — UI will not load. Run `npm install` in the plugin project.");
125
181
  } else {
126
- log.warn("vite not found — UI will not be bundled. Run `npm install` in the plugin project.");
182
+ devPort = await waitForPluginDevPort(readyFile, viteProc);
183
+ viteProc.on("exit", (code) => {
184
+ if (code) log.warn(`plugin dev server exited (code ${code}) — UI won't load (is :${devPort} free?).`);
185
+ });
127
186
  }
128
187
 
129
188
  const previewRoot = findPreviewHostRoot();
@@ -133,6 +192,7 @@ export async function runDevUi(args = []) {
133
192
  await new Promise((res, rej) => {
134
193
  const p = spawn(node ?? process.execPath, [resolve(previewRoot, "build.mjs")], {
135
194
  stdio: "inherit",
195
+ env: { ...process.env, VITE_PLUGIN_PREVIEW: "true" },
136
196
  });
137
197
  p.on("exit", (c) => (c === 0 ? res() : rej(new Error("preview-host build failed"))));
138
198
  });
@@ -141,7 +201,13 @@ export async function runDevUi(args = []) {
141
201
  log.step(`starting preview-host on :${port}`);
142
202
  const child = spawn(
143
203
  node ?? process.execPath,
144
- [serveEntry, "--plugin", outDir, "--port", String(port)],
204
+ [
205
+ serveEntry,
206
+ "--plugin", outDir,
207
+ "--port", String(port),
208
+ "--dev-server-url", `http://localhost:${devPort}`,
209
+ ...(robotIp ? ["--robot-host", robotIp] : []),
210
+ ],
145
211
  { stdio: "inherit" },
146
212
  );
147
213
 
@@ -1,6 +1,7 @@
1
1
  // manifest.mjs — manifest.json schema definition and validation
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  import { resolve } from "node:path";
4
+ import { manifestPortRanges, validatePorts } from "./ports.mjs";
4
5
 
5
6
  export const CONTRIBUTION_POINTS = ["program.command", "toolbar", "move.rnb"];
6
7
  const ICON_SIZES = ["16", "48", "128"];
@@ -171,6 +172,7 @@ export function validateManifest(manifest) {
171
172
  validateI18nLabel(manifest.description, "description", errors);
172
173
 
173
174
  validateIcons(manifest.icons, errors);
175
+ validatePorts(manifest.ports, errors);
174
176
  validateRuntime(manifest.runtime, errors);
175
177
  validateContributes(manifest.contributes, errors);
176
178
 
@@ -191,3 +193,16 @@ export function assertManifest(root) {
191
193
  throw new Error(`manifest.json errors:\n${errors.map((e) => ` • ${e}`).join("\n")}`);
192
194
  return manifest;
193
195
  }
196
+
197
+ export function assertManifestPorts(root) {
198
+ const manifest = readManifest(root);
199
+ if (manifest === null)
200
+ throw new Error("manifest.json parse failed — check JSON syntax");
201
+ if (Object.keys(manifest).length === 0)
202
+ return [];
203
+ const errors = [];
204
+ validatePorts(manifest.ports, errors);
205
+ if (errors.length > 0)
206
+ throw new Error(`manifest.json port errors:\n${errors.map((e) => ` • ${e}`).join("\n")}`);
207
+ return manifestPortRanges(manifest);
208
+ }