@rainbow-robotics/muscat-plugin-kit 0.1.2-dev.9 → 0.10.1-dev.1

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 (276) hide show
  1. package/README.ko.md +1188 -0
  2. package/README.md +1139 -57
  3. package/cli/README.md +239 -7
  4. package/cli/bin/create-muscat-plugin.mjs +1 -1
  5. package/cli/bin/muscat-pk.mjs +123 -27
  6. package/cli/bundle-templates.mjs +31 -0
  7. package/cli/docker/Dockerfile.cpp +28 -0
  8. package/cli/docker/Dockerfile.dev +17 -0
  9. package/cli/docker/Dockerfile.python +21 -0
  10. package/cli/prepack.mjs +12 -0
  11. package/cli/program-commands.json +2079 -0
  12. package/cli/src/__pycache__/host_agent.cpython-37.pyc +0 -0
  13. package/cli/src/ai-rules.mjs +108 -0
  14. package/cli/src/build.mjs +333 -93
  15. package/cli/src/check-package.mjs +8 -23
  16. package/cli/src/completion.mjs +168 -0
  17. package/cli/src/cpp.mjs +78 -0
  18. package/cli/src/cppIde.mjs +76 -0
  19. package/cli/src/dev.mjs +195 -6
  20. package/cli/src/devBack.mjs +671 -60
  21. package/cli/src/devId.mjs +54 -0
  22. package/cli/src/devSession.mjs +67 -0
  23. package/cli/src/devUi.mjs +218 -25
  24. package/cli/src/esbuild.mjs +27 -10
  25. package/cli/src/host_agent.py +223 -0
  26. package/cli/src/manifest.mjs +288 -0
  27. package/cli/src/mcp.mjs +1232 -0
  28. package/cli/src/mcpProxy.mjs +110 -0
  29. package/cli/src/muscatLocal.mjs +292 -0
  30. package/cli/src/new.mjs +205 -68
  31. package/cli/src/pluginDevServer.mjs +111 -0
  32. package/cli/src/ports.mjs +193 -0
  33. package/cli/src/programCommands.mjs +327 -0
  34. package/cli/src/projectCheck.mjs +102 -0
  35. package/cli/src/python.mjs +112 -0
  36. package/cli/src/ros2.mjs +62 -18
  37. package/cli/src/sdk.mjs +74 -24
  38. package/cli/src/sim.mjs +177 -0
  39. package/cli/src/storybook.mjs +150 -0
  40. package/cli/src/templates-embedded.mjs +4 -0
  41. package/cli/src/type.mjs +93 -34
  42. package/cli/src/uninstall.mjs +81 -0
  43. package/cli/src/update.mjs +364 -35
  44. package/cli/src/util.mjs +341 -11
  45. package/cli/src/zenohDev.mjs +83 -0
  46. package/cli/src/zip.mjs +121 -0
  47. package/cli/storybook-dist/_design-tokens.css +4957 -0
  48. package/cli/storybook-dist/_stories-src/NxAvatar.stories.tsx +27 -0
  49. package/cli/storybook-dist/_stories-src/NxPagination.stories.tsx +28 -0
  50. package/cli/storybook-dist/_stories-src/RBAccordion/RBAccordion.stories.tsx +46 -0
  51. package/cli/storybook-dist/_stories-src/RBAccordion/RBAccordionGroup.stories.tsx +73 -0
  52. package/cli/storybook-dist/_stories-src/RBBadge/RBBadge.stories.tsx +93 -0
  53. package/cli/storybook-dist/_stories-src/RBBattery/RBBattery.stories.tsx +74 -0
  54. package/cli/storybook-dist/_stories-src/RBButton/RBCheckIconButton.stories.tsx +28 -0
  55. package/cli/storybook-dist/_stories-src/RBButton/RBCheckLabelButton.stories.tsx +84 -0
  56. package/cli/storybook-dist/_stories-src/RBButton/RBIconButton.stories.tsx +57 -0
  57. package/cli/storybook-dist/_stories-src/RBButton/RBInlineLabelButton.stories.tsx +41 -0
  58. package/cli/storybook-dist/_stories-src/RBButton/RBLabelButton.stories.tsx +60 -0
  59. package/cli/storybook-dist/_stories-src/RBDatePicker/RBDateInput.stories.tsx +44 -0
  60. package/cli/storybook-dist/_stories-src/RBDatePicker/RBRangeDateInput.stories.tsx +56 -0
  61. package/cli/storybook-dist/_stories-src/RBDialog/RBAlert.stories.tsx +51 -0
  62. package/cli/storybook-dist/_stories-src/RBDialog/RBConfirm.stories.tsx +55 -0
  63. package/cli/storybook-dist/_stories-src/RBDialog/RBPrompt.stories.tsx +52 -0
  64. package/cli/storybook-dist/_stories-src/RBDivider/RBDivider.stories.tsx +93 -0
  65. package/cli/storybook-dist/_stories-src/RBEmptyView/RBEmptyView.stories.tsx +49 -0
  66. package/cli/storybook-dist/_stories-src/RBIcons/RBColorIcons.stories.tsx +108 -0
  67. package/cli/storybook-dist/_stories-src/RBIcons/RBIcons.stories.tsx +106 -0
  68. package/cli/storybook-dist/_stories-src/RBInput/RBCheckBox.stories.tsx +89 -0
  69. package/cli/storybook-dist/_stories-src/RBInput/RBMultiRangeInput.stories.tsx +64 -0
  70. package/cli/storybook-dist/_stories-src/RBInput/RBRadioBox.stories.tsx +65 -0
  71. package/cli/storybook-dist/_stories-src/RBInput/RBRadioButton.stories.tsx +68 -0
  72. package/cli/storybook-dist/_stories-src/RBInput/RBSelectBox.stories.tsx +216 -0
  73. package/cli/storybook-dist/_stories-src/RBInput/RBSideNumberInput.stories.tsx +90 -0
  74. package/cli/storybook-dist/_stories-src/RBInput/RBText/RBTextArea.stories.tsx +45 -0
  75. package/cli/storybook-dist/_stories-src/RBInput/RBText/RBTextInput.stories.tsx +50 -0
  76. package/cli/storybook-dist/_stories-src/RBInput/RBTextField.stories.tsx +102 -0
  77. package/cli/storybook-dist/_stories-src/RBJoyStick/RBJoyStick.stories.tsx +31 -0
  78. package/cli/storybook-dist/_stories-src/RBLight/RBLight.stories.tsx +36 -0
  79. package/cli/storybook-dist/_stories-src/RBPagination/RBPagination.stories.tsx +49 -0
  80. package/cli/storybook-dist/_stories-src/RBShadcn/RBCard/RBCard.stories.tsx +89 -0
  81. package/cli/storybook-dist/_stories-src/RBShadcn/RBCommand/RBCommand.stories.tsx +116 -0
  82. package/cli/storybook-dist/_stories-src/RBShadcn/RBDialog/RBDialog.stories.tsx +74 -0
  83. package/cli/storybook-dist/_stories-src/RBShadcn/RBDrawer/RBDrawer.stories.tsx +99 -0
  84. package/cli/storybook-dist/_stories-src/RBShadcn/RBDropdownMenu/RBDropdownMenu.stories.tsx +123 -0
  85. package/cli/storybook-dist/_stories-src/RBShadcn/RBMenubar/RBMenubar.stories.tsx +135 -0
  86. package/cli/storybook-dist/_stories-src/RBShadcn/RBPopover/RBPopover.stories.tsx +69 -0
  87. package/cli/storybook-dist/_stories-src/RBShadcn/RBResizable/RBResizable.stories.tsx +49 -0
  88. package/cli/storybook-dist/_stories-src/RBShadcn/RBSheet/RBSheet.stories.tsx +91 -0
  89. package/cli/storybook-dist/_stories-src/RBShadcn/RBSlider/RBSlider.stories.tsx +38 -0
  90. package/cli/storybook-dist/_stories-src/RBShadcn/RBSwitch/RBSwitch.stories.tsx +112 -0
  91. package/cli/storybook-dist/_stories-src/RBShadcn/RBTabs/RBTabs.stories.tsx +75 -0
  92. package/cli/storybook-dist/_stories-src/RBShadcn/RBToggle/RBToggle.stories.tsx +51 -0
  93. package/cli/storybook-dist/_stories-src/RBShadcn/RBToggleGroup/RBToggleGroup.stories.tsx +84 -0
  94. package/cli/storybook-dist/_stories-src/RBTab/RBChipTab.stories.tsx +102 -0
  95. package/cli/storybook-dist/_stories-src/RBTab/RBChipsBoxTab.stories.tsx +78 -0
  96. package/cli/storybook-dist/_stories-src/RBTab/RBTab.stories.tsx +57 -0
  97. package/cli/storybook-dist/_stories-src/RBTable/RBTable.stories.tsx +177 -0
  98. package/cli/storybook-dist/_stories-src/RBTable/RBTableRow.stories.tsx +64 -0
  99. package/cli/storybook-dist/_stories-src/RBToast/RBToast.stories.tsx +117 -0
  100. package/cli/storybook-dist/_stories-src/RBTooltip/RBTooltip.stories.tsx +50 -0
  101. package/cli/storybook-dist/_stories-src/loading/RBSpinner.stories.tsx +30 -0
  102. package/cli/storybook-dist/_stories-src/nx-button/NxButton.stories.tsx +54 -0
  103. package/cli/storybook-dist/_stories-src/nx-button/NxPointerHoldButton.stories.tsx +57 -0
  104. package/cli/storybook-dist/_stories-src/nx-icons/NxIcons.stories.tsx +48 -0
  105. package/cli/storybook-dist/_stories-src/nx-inputs/NxNumberInput.stories.tsx +103 -0
  106. package/cli/storybook-dist/_stories-src/nx-inputs/NxRangeInput.stories.tsx +27 -0
  107. package/cli/storybook-dist/_stories-src/nx-inputs/NxSelectBox.stories.tsx +67 -0
  108. package/cli/storybook-dist/_stories-src/nx-inputs/NxSlideRange.stories.tsx +45 -0
  109. package/cli/storybook-dist/_stories-src/nx-inputs/NxSwitch.stories.tsx +27 -0
  110. package/cli/storybook-dist/_stories-src/nx-inputs/NxTextArea.stories.tsx +48 -0
  111. package/cli/storybook-dist/_stories-src/nx-inputs/NxTextInput.stories.tsx +46 -0
  112. package/cli/storybook-dist/assets/Color-YHDXOIA2-pCKrjUal.js +1 -0
  113. package/cli/storybook-dist/assets/Docs-B-Y7I1GA.js +7 -0
  114. package/cli/storybook-dist/assets/Docs-BFJcE_VS.js +8 -0
  115. package/cli/storybook-dist/assets/Docs-B_QaTtz8.js +8 -0
  116. package/cli/storybook-dist/assets/Docs-CryDGmfh.js +20 -0
  117. package/cli/storybook-dist/assets/Docs-Cw2AVNKx.js +7 -0
  118. package/cli/storybook-dist/assets/Docs-Q6r1fBeL.js +12 -0
  119. package/cli/storybook-dist/assets/DocsRenderer-CFRXHY34-_OmZBCn8.js +2 -0
  120. package/cli/storybook-dist/assets/NxAvatar.stories-Ctf5G2FQ.js +13 -0
  121. package/cli/storybook-dist/assets/NxButton.stories-DeLObVSj.js +20 -0
  122. package/cli/storybook-dist/assets/NxIcons.stories-DeqrVzVs.js +3 -0
  123. package/cli/storybook-dist/assets/NxNumberInput.stories-LqoY0ed1.js +26 -0
  124. package/cli/storybook-dist/assets/NxPagination.stories-DI6bXuJM.js +11 -0
  125. package/cli/storybook-dist/assets/NxPointerHoldButton.stories-3HSV1XmN.js +14 -0
  126. package/cli/storybook-dist/assets/NxRangeInput.stories-1pjgQVaG.js +17 -0
  127. package/cli/storybook-dist/assets/NxSelectBox.stories-bcQPZEuF.js +17 -0
  128. package/cli/storybook-dist/assets/NxSlideRange.stories-BosX4axk.js +14 -0
  129. package/cli/storybook-dist/assets/NxSwitch.stories-DxV6dS33.js +11 -0
  130. package/cli/storybook-dist/assets/NxTextArea.stories-CO545-LP.js +11 -0
  131. package/cli/storybook-dist/assets/NxTextInput.stories-BP0npai1.js +11 -0
  132. package/cli/storybook-dist/assets/PretendardVariable-CJuje-Rk.woff2 +0 -0
  133. package/cli/storybook-dist/assets/RBAccordion.stories-fVR4Va2a.js +17 -0
  134. package/cli/storybook-dist/assets/RBAccordionGroup.stories-Du5bsckD.js +33 -0
  135. package/cli/storybook-dist/assets/RBAlert.stories-DNkMXUu6.js +17 -0
  136. package/cli/storybook-dist/assets/RBBadge.stories-C44pXt8D.js +1 -0
  137. package/cli/storybook-dist/assets/RBBattery.stories-DE2JHvfL.js +10 -0
  138. package/cli/storybook-dist/assets/RBCard.stories-CuIda7NI.js +45 -0
  139. package/cli/storybook-dist/assets/RBCheckBox.stories-D1qM1ayr.js +1 -0
  140. package/cli/storybook-dist/assets/RBCheckIconButton.stories-e4gkliBO.js +1 -0
  141. package/cli/storybook-dist/assets/RBCheckLabelButton.stories-CDzCtsMI.js +24 -0
  142. package/cli/storybook-dist/assets/RBChipTab.stories-DBrc_3Mp.js +21 -0
  143. package/cli/storybook-dist/assets/RBChipsBoxTab.stories-hlrsHjKY.js +1 -0
  144. package/cli/storybook-dist/assets/RBColorIcons.stories-BHUvpkdu.js +3 -0
  145. package/cli/storybook-dist/assets/RBCommand.stories-azAF41NP.js +73 -0
  146. package/cli/storybook-dist/assets/RBConfirm.stories-BMNjwbmT.js +20 -0
  147. package/cli/storybook-dist/assets/RBDateInput.stories-D0VezDzv.js +15 -0
  148. package/cli/storybook-dist/assets/RBDialog.stories-AOJ975Fy.js +38 -0
  149. package/cli/storybook-dist/assets/RBDivider.stories-NSvnj43Z.js +1 -0
  150. package/cli/storybook-dist/assets/RBDrawer.stories-Du0oTvD1.js +14 -0
  151. package/cli/storybook-dist/assets/RBDropdownMenu.stories-Hsxve4PW.js +86 -0
  152. package/cli/storybook-dist/assets/RBEmptyView.stories-BlwHx3zp.js +12 -0
  153. package/cli/storybook-dist/assets/RBIconButton.stories-DAPDY63x.js +1 -0
  154. package/cli/storybook-dist/assets/RBIcons.stories-W5ZUV2L1.js +3 -0
  155. package/cli/storybook-dist/assets/RBInlineLabelButton.stories-C99j0Y3g.js +1 -0
  156. package/cli/storybook-dist/assets/RBJoyStick.stories-Du0H1iAS.js +11 -0
  157. package/cli/storybook-dist/assets/RBLabelButton.stories-BlvHaU_Z.js +1 -0
  158. package/cli/storybook-dist/assets/RBLight.stories-BY6DKrre.js +1 -0
  159. package/cli/storybook-dist/assets/RBMenubar.stories-D2PEGpM9.js +3 -0
  160. package/cli/storybook-dist/assets/RBMultiRangeInput.stories-Bm2qSmjq.js +14 -0
  161. package/cli/storybook-dist/assets/RBPagination.stories-DDleJa5N.js +17 -0
  162. package/cli/storybook-dist/assets/RBPopover.stories-27YxPSFG.js +11 -0
  163. package/cli/storybook-dist/assets/RBPrompt.stories-BFaIOctr.js +20 -0
  164. package/cli/storybook-dist/assets/RBRadioBox.stories-BroDar0t.js +1 -0
  165. package/cli/storybook-dist/assets/RBRadioButton.stories-M3O-wX7V.js +11 -0
  166. package/cli/storybook-dist/assets/RBRangeDateInput.stories-CWlM_D5X.js +15 -0
  167. package/cli/storybook-dist/assets/RBResizable.stories-ui8X1qnc.js +20 -0
  168. package/cli/storybook-dist/assets/RBSelectBox.stories-C8T6cfA0.js +74 -0
  169. package/cli/storybook-dist/assets/RBSheet.stories-BCOo_Zcc.js +39 -0
  170. package/cli/storybook-dist/assets/RBSideNumberInput.stories-CU2_MVlJ.js +5 -0
  171. package/cli/storybook-dist/assets/RBSlider.stories-DgOp1TFc.js +5 -0
  172. package/cli/storybook-dist/assets/RBSpinner.stories-qLScY3zZ.js +14 -0
  173. package/cli/storybook-dist/assets/RBSwitch.stories-SXSY1QMb.js +65 -0
  174. package/cli/storybook-dist/assets/RBTab.stories-BzXXTsXP.js +1 -0
  175. package/cli/storybook-dist/assets/RBTable.stories-DHTeRNVk.js +62 -0
  176. package/cli/storybook-dist/assets/RBTableRow.stories-DRNRsd15.js +11 -0
  177. package/cli/storybook-dist/assets/RBTabs.stories-DP0noBLp.js +21 -0
  178. package/cli/storybook-dist/assets/RBTextArea.stories-TkaejfxJ.js +5 -0
  179. package/cli/storybook-dist/assets/RBTextField.stories-B6VpCGyt.js +45 -0
  180. package/cli/storybook-dist/assets/RBTextInput.stories-D3hZ08e-.js +5 -0
  181. package/cli/storybook-dist/assets/RBToast.stories-BQ2wS2U0.js +11 -0
  182. package/cli/storybook-dist/assets/RBToggle.stories-GVOjGqo3.js +12 -0
  183. package/cli/storybook-dist/assets/RBToggleGroup.stories-pzx0btOD.js +17 -0
  184. package/cli/storybook-dist/assets/RBTooltip.stories-jufB6fa1.js +9 -0
  185. package/cli/storybook-dist/assets/SideNumberInput-BYlmNHEw.js +1109 -0
  186. package/cli/storybook-dist/assets/SideNumberInput-SAkhydsn.css +21 -0
  187. package/cli/storybook-dist/assets/browserUtils-CQM9Za7e.js +1 -0
  188. package/cli/storybook-dist/assets/chunk-XP5HYGXS-BHXC9YeQ.js +1 -0
  189. package/cli/storybook-dist/assets/client-DTf7SId2.js +1 -0
  190. package/cli/storybook-dist/assets/entry-preview-CAkU-e0D.js +2 -0
  191. package/cli/storybook-dist/assets/entry-preview-docs-b8bpVBXy.js +46 -0
  192. package/cli/storybook-dist/assets/iframe-B-BmTsxV.js +211 -0
  193. package/cli/storybook-dist/assets/index-B4FGfHer.js +1 -0
  194. package/cli/storybook-dist/assets/index-BRq5TIsn.js +24 -0
  195. package/cli/storybook-dist/assets/index-CT3U1fyk.js +1 -0
  196. package/cli/storybook-dist/assets/index-ChsGqxH_.js +9 -0
  197. package/cli/storybook-dist/assets/index-CkB0GfaI.js +575 -0
  198. package/cli/storybook-dist/assets/index-ClAc6FBW.js +240 -0
  199. package/cli/storybook-dist/assets/index-DKFBREX_.js +1 -0
  200. package/cli/storybook-dist/assets/index-DgH-xKnr.js +11 -0
  201. package/cli/storybook-dist/assets/index-Dmy2JGbm.js +1 -0
  202. package/cli/storybook-dist/assets/index-DrFu-skq.js +6 -0
  203. package/cli/storybook-dist/assets/jsx-runtime-BTJTZTIL.js +9 -0
  204. package/cli/storybook-dist/assets/preview-B8lJiyuQ.js +34 -0
  205. package/cli/storybook-dist/assets/preview-BBWR9nbA.js +1 -0
  206. package/cli/storybook-dist/assets/preview-BVJwlGUF.js +1 -0
  207. package/cli/storybook-dist/assets/preview-BWzBA1C2.js +396 -0
  208. package/cli/storybook-dist/assets/preview-CVgpLj3b.js +1 -0
  209. package/cli/storybook-dist/assets/preview-CvbIS5ZJ.js +1 -0
  210. package/cli/storybook-dist/assets/preview-CznQwwbo.js +3 -0
  211. package/cli/storybook-dist/assets/preview-DD_OYowb.js +1 -0
  212. package/cli/storybook-dist/assets/preview-DGUiP6tS.js +7 -0
  213. package/cli/storybook-dist/assets/preview-DHQbi4pV.js +1 -0
  214. package/cli/storybook-dist/assets/preview-M77JRg1A.js +2 -0
  215. package/cli/storybook-dist/assets/preview-kTZPgP6D.css +1 -0
  216. package/cli/storybook-dist/assets/react-18-hB3smqWJ.js +1 -0
  217. package/cli/storybook-dist/assets/react-resizable-panels-HsFbxPbn.css +1 -0
  218. package/cli/storybook-dist/assets/react-resizable-panels.browser-DuxpZLkF.js +120 -0
  219. package/cli/storybook-dist/assets/test-utils-BQudk2xt.js +9 -0
  220. package/cli/storybook-dist/favicon.svg +1 -0
  221. package/cli/storybook-dist/iframe.html +666 -0
  222. package/cli/storybook-dist/index.html +190 -0
  223. package/cli/storybook-dist/index.json +1 -0
  224. package/cli/storybook-dist/nunito-sans-bold-italic.woff2 +0 -0
  225. package/cli/storybook-dist/nunito-sans-bold.woff2 +0 -0
  226. package/cli/storybook-dist/nunito-sans-italic.woff2 +0 -0
  227. package/cli/storybook-dist/nunito-sans-regular.woff2 +0 -0
  228. package/cli/storybook-dist/project.json +1 -0
  229. package/cli/storybook-dist/sb-addons/chromatic-com-storybook-10/manager-bundle.js +331 -0
  230. package/cli/storybook-dist/sb-addons/chromatic-com-storybook-10/manager-bundle.js.LEGAL.txt +51 -0
  231. package/cli/storybook-dist/sb-addons/essentials-actions-3/manager-bundle.js +3 -0
  232. package/cli/storybook-dist/sb-addons/essentials-backgrounds-5/manager-bundle.js +12 -0
  233. package/cli/storybook-dist/sb-addons/essentials-controls-2/manager-bundle.js +405 -0
  234. package/cli/storybook-dist/sb-addons/essentials-docs-4/manager-bundle.js +245 -0
  235. package/cli/storybook-dist/sb-addons/essentials-measure-8/manager-bundle.js +3 -0
  236. package/cli/storybook-dist/sb-addons/essentials-outline-9/manager-bundle.js +3 -0
  237. package/cli/storybook-dist/sb-addons/essentials-toolbars-7/manager-bundle.js +3 -0
  238. package/cli/storybook-dist/sb-addons/essentials-viewport-6/manager-bundle.js +3 -0
  239. package/cli/storybook-dist/sb-addons/links-1/manager-bundle.js +3 -0
  240. package/cli/storybook-dist/sb-addons/storybook-13/manager-bundle.js +3 -0
  241. package/cli/storybook-dist/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +3 -0
  242. package/cli/storybook-dist/sb-addons/storybook-experimental-addon-test-12/manager-bundle.js +223 -0
  243. package/cli/storybook-dist/sb-addons/themes-11/manager-bundle.js +3 -0
  244. package/cli/storybook-dist/sb-common-assets/favicon.svg +1 -0
  245. package/cli/storybook-dist/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  246. package/cli/storybook-dist/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  247. package/cli/storybook-dist/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  248. package/cli/storybook-dist/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  249. package/cli/storybook-dist/sb-manager/globals-module-info.js +1052 -0
  250. package/cli/storybook-dist/sb-manager/globals-runtime.js +41775 -0
  251. package/cli/storybook-dist/sb-manager/globals.js +48 -0
  252. package/cli/storybook-dist/sb-manager/runtime.js +12048 -0
  253. package/cli/templates/common/README.md +1070 -83
  254. package/cli/templates/common/assets/icon.svg +44 -2
  255. package/cli/templates/common/manifest.json +14 -13
  256. package/cli/templates/common/package.json +11 -4
  257. package/cli/templates/common/py/main.py +125 -0
  258. package/cli/templates/common/requirements.txt +4 -3
  259. package/cli/templates/common/tsconfig.json +1 -1
  260. package/cli/templates/common/ui/content.tsx +216 -0
  261. package/cli/templates/common/ui/style.css +6 -0
  262. package/cli/templates/common/vite.config.ts +6 -25
  263. package/cli/templates/cpp/cpp/CMakeLists.txt +14 -0
  264. package/cli/templates/cpp/cpp/main.cpp +73 -0
  265. package/cli/templates/readme-cpp/README.md +1012 -0
  266. package/cli/templates/ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/node.py +12 -1
  267. package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/CMakeLists.txt +22 -0
  268. package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/package.xml +11 -0
  269. package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/src/node.cpp +41 -0
  270. package/cli/vite.d.mts +25 -0
  271. package/cli/vite.mjs +292 -0
  272. package/package.json +34 -7
  273. package/cli/src/pack.mjs +0 -61
  274. package/cli/src/preview.mjs +0 -91
  275. package/cli/templates/common/main.py +0 -114
  276. package/cli/templates/common/src/content.tsx +0 -33
package/cli/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @rainbow-robotics/muscat-plugin-kit (`muscat-pk`)
2
2
 
3
- CLI to scaffold, build, preview and pack Muscat plugins.
3
+ CLI to scaffold, build, and preview Muscat plugins.
4
4
 
5
5
  Install/use it the same way an external plugin author will:
6
6
 
@@ -10,16 +10,214 @@ muscat-pk new my-plugin
10
10
  ```
11
11
 
12
12
  ```bash
13
- muscat-pk new my-plugin [--type sdk|ros2|ui] [--pm npm|yarn|pnpm|bun] [--yes]
14
- muscat-pk build # src/content.tsx -> dist/content.js (+ manifest, sandbox, assets)
15
- muscat-pk pack # build (minified) + distributable ZIP with a size report
13
+ muscat-pk new my-plugin [--type python|cpp|ros2|ros2-cpp] [--pm npm|yarn|pnpm|bun] [--yes]
14
+ muscat-pk build # ui/content.tsx -> dist/ (minified) + distributable ZIP
16
15
  muscat-pk dev:ui # preview the plugin in a mini-Muscat (preview-host)
17
- muscat-pk dev:back # run the back end (.venv + python main.py)
16
+ muscat-pk dev:back # run the back end in a Docker container (python / cpp / ros2)
18
17
  muscat-pk dev # dev:ui + dev:back
19
- muscat-pk update # update @rainbow-robotics/muscat-plugin-kit and @rainbow-robotics/plugin-ui
18
+ muscat-pk storybook # browse the bundled rb-components Storybook subset
19
+ muscat-pk mcp # start an MCP server (stdio) exposing rb-components/design-token/SDK docs to AI agents
20
+ muscat-pk update # update @rainbow-robotics/muscat-plugin-kit, plugin-ui and preview-host; lists old-API UI code to fix
21
+ muscat-pk uninstall # remove muscat-pk itself (npm global or S3 binary)
20
22
  muscat-pk sdk list | sdk update [version] # manage rainbow-rb-sdk (python)
23
+ muscat-pk version # print the installed CLI version (-v / --version too)
24
+ muscat-pk completion zsh # print a shell completion script (bash | zsh | fish | powershell)
21
25
  ```
22
26
 
27
+ ## Backend ports
28
+
29
+ If a plugin backend opens a TCP server, declare it in `manifest.json`:
30
+
31
+ ```json
32
+ {
33
+ "ports": [28600, 28601]
34
+ }
35
+ ```
36
+
37
+ `ports` is optional and accepts only `number[]`; ranges or objects are not
38
+ accepted. External plugin backend ports are reserved for `28600-28999`.
39
+ `muscat-pk dev` and `muscat-pk dev:back` validate the manifest before start and
40
+ then watch the container: **any listening TCP port that is not declared stops
41
+ the backend**, whatever its number. Since a port outside `28600-28999` cannot be
42
+ declared, it cannot be opened either — otherwise it would slip past both this
43
+ check and the robot's install-time conflict check.
44
+
45
+ The kit's own dev ports (plugin gateway `10000`, the Zenoh dev peer port) are
46
+ excluded from that check.
47
+
48
+ Under `muscat-pk dev` the backend shares the local Muscat container's network, so
49
+ declared ports are published to `127.0.0.1` from that container. A declared port
50
+ that is already busy on the host is skipped with a warning.
51
+
52
+ Known robot/industrial/internal ports such as `502`, `4840`, `5170-5179`,
53
+ `8000-8999`, `10000`, `2222`, `30004`, `34964`, `44818`, `50000-50005`,
54
+ and `50051` are reserved and must not be used by external plugins.
55
+
56
+ ## Backend runtimes
57
+
58
+ `manifest.json` selects one runtime:
59
+
60
+ | runtime | source | notes |
61
+ |---|---|---|
62
+ | `{ "type": "none" }` | — | UI-only plugin; no backend container |
63
+ | `{ "type": "python", "entry": "main.py" }` | `py/` | Uses `rainbow.rb_sdk.RBPluginCall` for UI/backend messaging; `plugin.router` exposes external endpoints (`common/plugin/{id}/{path}`, needs sdk ≥ 0.0.9.dev5 on the robot; the dev bridge only registers routes — external calls need a running `common`) |
64
+ | `{ "type": "cpp", "entry": "<executable name>" }` | `cpp/` | Built with CMake in Docker against the C++ SDK (apt `rainbow-rb-sdk-dev`, `find_package(rb_sdk)`, dynamic link) |
65
+ | `{ "type": "ros2", "rosClient": "rclpy", ... }` | `ros2_ws/` | ROS2 Python node; may use Python SDK alongside ROS2 APIs |
66
+ | `{ "type": "ros2", "rosClient": "rclcpp", ... }` | `ros2_ws/` | ROS2 C++ node built with colcon/CMake, links the C++ SDK like `cpp` |
67
+
68
+ All non-`none` runtimes run in Docker during `muscat-pk dev:back`, `muscat-pk
69
+ dev`, and build/export flows so development matches the robot environment.
70
+
71
+ ## JavaScript dependencies
72
+
73
+ `muscat-pk build` runs the plugin project's own Vite build. Vite resolves imports
74
+ from installed `node_modules`; it does not care whether a package is listed under
75
+ `dependencies` or `devDependencies`, but the package must be installed.
76
+
77
+ Do not run a production-only install such as `npm install --omit=dev` before
78
+ building a plugin UI, because build tools like `vite`, `typescript`,
79
+ `tailwindcss`, `@tailwindcss/vite`, `sass`, or `less` are usually
80
+ `devDependencies`.
81
+
82
+ The scaffold keeps this split:
83
+
84
+ | package kind | examples | why |
85
+ |---|---|---|
86
+ | `dependencies` | `@rainbow-robotics/plugin-ui`, UI libraries imported by plugin source | Author-facing APIs used by `ui/*.tsx` |
87
+ | `devDependencies` | `vite`, `typescript`, `tailwindcss`, `@tailwindcss/vite`, `sass`, `less` | Build/dev tools needed before `dist/*.js` is produced |
88
+
89
+ The built plugin ZIP does not include `package.json` or `node_modules`. For
90
+ production, Muscat provides `@rainbow-robotics/plugin-ui`, React, and ReactDOM
91
+ through the host import map; plugin UI build output imports those as host
92
+ externals.
93
+
94
+ ## Plugin styles
95
+
96
+ `muscat()` auto-loads plugin styles from `ui/style.{css,scss,sass,less}` or
97
+ `ui/styles.{css,scss,sass,less}` for every UI entry, and from
98
+ `ui/{entry}.{css,scss,sass,less}` for a matching entry-specific file. Authors do
99
+ not need to import CSS from every `.tsx` entry.
100
+
101
+ The scaffold enables Tailwind in the plugin's own `vite.config.ts`; those
102
+ Tailwind dependencies live in the plugin package, while `muscat()` injects the
103
+ generated CSS into the plugin JS bundle so dynamic host imports do not need a
104
+ separate CSS file.
105
+
106
+ Built CSS selectors are scoped under the current plugin id
107
+ (`[data-muscat-plugin-id="..."]`), so Tailwind utilities or plugin styles do not
108
+ rewrite the host page or another plugin. CSS-in-JS libraries are allowed too,
109
+ but global styles (for example Emotion `Global`) remain the author's
110
+ responsibility to scope.
111
+
112
+ ### Tailwind
113
+
114
+ New plugins include Tailwind by default:
115
+
116
+ ```ts
117
+ import { defineConfig } from "vite";
118
+ import tailwindcss from "@tailwindcss/vite";
119
+ import { muscat } from "@rainbow-robotics/muscat-plugin-kit/vite";
120
+
121
+ export default defineConfig({
122
+ plugins: [tailwindcss(), muscat()],
123
+ });
124
+ ```
125
+
126
+ The default `ui/style.css` uses Tailwind theme/utilities only, not preflight:
127
+
128
+ ```css
129
+ @layer theme, utilities;
130
+
131
+ @import "tailwindcss/theme.css" layer(theme);
132
+ @import "tailwindcss/utilities.css" layer(utilities);
133
+
134
+ @source "./**/*.{ts,tsx}";
135
+ ```
136
+
137
+ ### SCSS, Sass, and Less
138
+
139
+ Install the preprocessor package in the plugin project, then create one of the
140
+ auto-loaded style files.
141
+
142
+ ```bash
143
+ npm i -D sass
144
+ ```
145
+
146
+ ```scss
147
+ /* ui/style.scss */
148
+ $accent: #3b82f6;
149
+
150
+ .panel {
151
+ border: 1px solid color-mix(in srgb, $accent 40%, transparent);
152
+
153
+ &__title {
154
+ color: $accent;
155
+ }
156
+ }
157
+ ```
158
+
159
+ For Less, install `less` and use `ui/style.less`.
160
+
161
+ ### Emotion
162
+
163
+ Emotion dependencies may be in `dependencies` or `devDependencies`; Vite can
164
+ bundle them when they are installed and imported by the plugin.
165
+
166
+ For `styled`, no Vite config change is needed:
167
+
168
+ ```bash
169
+ npm i @emotion/react @emotion/styled
170
+ ```
171
+
172
+ ```tsx
173
+ import styled from "@emotion/styled";
174
+
175
+ const Panel = styled.div({
176
+ display: "grid",
177
+ gap: 12,
178
+ });
179
+ ```
180
+
181
+ For Emotion's `css` prop, pass React plugin options through `muscat()` and add
182
+ `jsxImportSource` to `tsconfig.json`:
183
+
184
+ ```bash
185
+ npm i @emotion/react @emotion/styled
186
+ npm i -D @emotion/babel-plugin
187
+ ```
188
+
189
+ ```ts
190
+ // vite.config.ts
191
+ import { defineConfig } from "vite";
192
+ import tailwindcss from "@tailwindcss/vite";
193
+ import { muscat } from "@rainbow-robotics/muscat-plugin-kit/vite";
194
+
195
+ export default defineConfig({
196
+ plugins: [
197
+ tailwindcss(),
198
+ muscat({
199
+ react: {
200
+ jsxImportSource: "@emotion/react",
201
+ babel: {
202
+ plugins: ["@emotion/babel-plugin"],
203
+ },
204
+ },
205
+ }),
206
+ ],
207
+ });
208
+ ```
209
+
210
+ ```json
211
+ {
212
+ "compilerOptions": {
213
+ "jsxImportSource": "@emotion/react"
214
+ }
215
+ }
216
+ ```
217
+
218
+ Emotion `Global` writes global CSS at runtime, so scope it manually or avoid it
219
+ inside plugins.
220
+
23
221
  ## How it fits together
24
222
 
25
223
  - **Install/CLI package** is `@rainbow-robotics/muscat-plugin-kit`.
@@ -28,7 +226,15 @@ muscat-pk sdk list | sdk update [version] # manage rainbow-rb-sdk (python)
28
226
  - **`build`** bundles plugin code into ESM while externalizing
29
227
  `@rainbow-robotics/plugin-ui`, React, and ReactDOM.
30
228
  - **`dev:ui`** builds the plugin then serves it inside the bundled preview host
31
- at `/plugin-dev` — a real mini-Muscat shell with no robot/back end.
229
+ at `/plugin-dev` — a real mini-Muscat shell. Without a robot IP it needs a Muscat
230
+ on `localhost:3000` for program preview: `dev` / `dev:ui` reuse any container that
231
+ already publishes `:10000` (`muscat`, `muscat-dev`, …) and otherwise start
232
+ `muscat-pk-muscat` — the S3 runtime image (`muscat/main/muscat.zip`) running the
233
+ `common` service from `muscat/main/version.json`, cached under `~/.muscat-pk/muscat/`.
234
+ `dev --sim <model>` adds the services the model needs (log + manipulate / rby1), opens
235
+ common's Zenoh on the `muscat-pk` network, and starts simulators there (`cli/src/sim.mjs`).
236
+ It keeps running between runs (`docker rm -f muscat-pk-muscat` to stop);
237
+ `MUSCAT_PK_NO_LOCAL_MUSCAT=1` disables it.
32
238
 
33
239
  `create-muscat-plugin <dir>` is the bin alias for `muscat-pk new`.
34
240
 
@@ -41,4 +247,30 @@ offline.
41
247
  - `RB_REGISTRY` — registry base URL (default `https://registry.npmjs.org`).
42
248
  - `MUSCAT_PK_NO_UPDATE_CHECK=1` — skip the check.
43
249
 
250
+ ## Local vs global install
251
+
252
+ If the plugin project has its own `muscat-plugin-kit` in `node_modules`, the CLI
253
+ delegates to it — so the CLI, the `vite` preset, and `preview-host` are always
254
+ the one version the project pinned, no matter which `muscat-pk` you typed.
255
+
256
+ `muscat-pk update` follows the same rule: run from a project's local install it
257
+ updates only that project; add `--global` to also update the machine-wide CLI.
258
+ `muscat-pk version` prints whichever copy actually ran.
259
+
260
+ ## Docker images
261
+
262
+ Images are built only when missing, because `docker build` resolves the base
263
+ image tag over the network on every run — even with all layers cached — which
264
+ would break `dev` offline. Pre-seed an air-gapped machine with
265
+ `docker save … | gzip` + `docker load`, or force a rebuild with
266
+ `MUSCAT_PK_REBUILD_IMAGE=1`.
267
+
268
+ The C++ images (`Dockerfile.cpp`, `Dockerfile.dev`) install `rainbow-rb-sdk-dev`
269
+ from `https://rainbowrobotics.github.io/rb-sdk` (suite `dev`), pinned by the
270
+ `RB_SDK_VERSION` build arg. Set `MUSCAT_PK_RB_SDK_VERSION=<version>` (with
271
+ `MUSCAT_PK_REBUILD_IMAGE=1`) to match a robot running a different SDK version.
272
+
273
+ On Linux the dev containers run as the invoking user (`--user`), so build output
274
+ under `dist/` and `cpp/build-*` is not left root-owned.
275
+
44
276
  Full spec: [`docs/plugin-system/CREATE-CLI.md`](../../docs/plugin-system/CREATE-CLI.md).
@@ -3,6 +3,6 @@
3
3
  import { runNew } from "../src/new.mjs";
4
4
 
5
5
  runNew(process.argv.slice(2)).catch((err) => {
6
- console.error(`\n✖ ${err?.message || err}`);
6
+ console.error(`\n ✖ ${err?.message || err}`);
7
7
  process.exit(1);
8
8
  });
@@ -1,36 +1,108 @@
1
1
  #!/usr/bin/env node
2
2
  // muscat-pk — Muscat plugin developer CLI.
3
- // Subcommands: new, build, pack, dev, dev:ui, dev:back, update, sdk.
3
+ // Subcommands: new, build, dev, dev:ui, dev:back, storybook, mcp, update, uninstall, sdk, version.
4
+ import { readFileSync, realpathSync } from "node:fs";
5
+ import { resolve } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { spawnSync } from "node:child_process";
8
+ import { color, compareKitVersions, kitVersion, log, resolveLocalCliBin } from "../src/util.mjs";
4
9
  import { runNew } from "../src/new.mjs";
5
10
  import { runBuild } from "../src/build.mjs";
6
- import { runPack } from "../src/pack.mjs";
7
11
  import { runDevUi } from "../src/devUi.mjs";
8
12
  import { runDevBack } from "../src/devBack.mjs";
9
13
  import { runDev } from "../src/dev.mjs";
10
- import { runUpdate } from "../src/update.mjs";
14
+ import { runUpdate, runUpdateCheck } from "../src/update.mjs";
15
+ import { runUninstall } from "../src/uninstall.mjs";
11
16
  import { runSdk } from "../src/sdk.mjs";
12
17
  import { runType } from "../src/type.mjs";
13
- import { runPreview } from "../src/preview.mjs";
18
+ import { runStorybook } from "../src/storybook.mjs";
19
+ import { runCompletion } from "../src/completion.mjs";
20
+ // mcp.mjs is dynamically imported below — it pulls in the MCP SDK + a full
21
+ // TypeScript program, and every other command would pay that cold-start cost
22
+ // on every invocation otherwise (see ros2.mjs/python.mjs/cpp.mjs for the same
23
+ // pattern in build.mjs).
14
24
 
15
- const [, , cmd, ...args] = process.argv;
25
+ // 실행 중인 게 글로벌/바이너리인데 cwd 상위에 로컬 설치가 있으면 그쪽으로 넘긴다.
26
+ // vite preset / preview-host / manifest 검증이 항상 프로젝트가 고정한 버전과
27
+ // 맞아야 해서다 (버전이 안 맞으면 "module not found" 류 에러로 터진다).
28
+ function readVersion(binPath) {
29
+ try {
30
+ return JSON.parse(readFileSync(resolve(binPath, "../../../package.json"), "utf8")).version;
31
+ } catch {
32
+ return "";
33
+ }
34
+ }
35
+
36
+ const isBinaryMode = typeof Bun !== "undefined";
37
+
38
+ // 바이너리에는 package.json 이 없다 — 컴파일 시 임베드한 버전을 쓴다.
39
+ if (isBinaryMode && !process.env.MUSCAT_PK_VERSION) {
40
+ process.env.MUSCAT_PK_VERSION = (await import("../src/templates-embedded.mjs")).KIT_VERSION;
41
+ }
16
42
 
17
- const HELP = `muscat-pk — Muscat plugin kit
43
+ (function delegateToLocalInstall() {
44
+ try {
45
+ const localBin = resolveLocalCliBin();
46
+ if (!localBin) return;
47
+ // 바이너리는 node_modules 안의 mjs일 수 없으니 자기 자신 비교 생략.
48
+ // (import.meta.url이 /$bunfs/ 가상 경로라 realpath가 throw하기도 한다.)
49
+ if (!isBinaryMode && realpathSync(localBin) === realpathSync(fileURLToPath(import.meta.url))) return;
50
+ // Say so — otherwise an outdated local copy silently answers instead, and
51
+ // its missing/renamed subcommands look like the CLI is broken.
52
+ const localVersion = readVersion(localBin);
53
+ // An older local copy can't update a project correctly — it doesn't know what changed since
54
+ // it was published. Run this CLI's update instead, still touching this project only.
55
+ if (process.argv[2] === "update" && localVersion && compareKitVersions(localVersion, kitVersion()) < 0) {
56
+ console.error(color.dim(`[muscat-pk] project's local install (v${localVersion}) is older — updating it with this CLI (v${kitVersion()})`));
57
+ process.env.MUSCAT_PK_UPDATE_PROJECT_ONLY = "1";
58
+ return;
59
+ }
60
+ console.error(
61
+ color.dim(`[muscat-pk] using this project's local install${localVersion ? ` (v${localVersion})` : ""}: ${localBin}`),
62
+ );
63
+ // Bun 바이너리의 execPath는 스크립트 인자를 실행하지 않으니 PATH의 node로 넘긴다.
64
+ const runtime = isBinaryMode ? "node" : process.execPath;
65
+ const r = spawnSync(runtime, [localBin, ...process.argv.slice(2)], { stdio: "inherit" });
66
+ if (r.error) {
67
+ log.warn(`Failed to run local install via ${runtime} (${r.error.code}); continuing with this binary.`);
68
+ return;
69
+ }
70
+ process.exit(r.status ?? 0);
71
+ } catch {
72
+ // realpath 실패 등 — 그냥 지금 프로세스로 계속.
73
+ }
74
+ })();
18
75
 
19
- Usage: muscat-pk <command> [options]
76
+ const [, , cmd, ...args] = process.argv;
20
77
 
21
- Commands:
22
- new [dir] Scaffold a new plugin project
23
- type change Switch backend type (python <-> ros2)
24
- build Build src/content.tsx -> dist/content.js (+ manifest, assets)
25
- pack Build then create a distributable ZIP (with size report)
26
- dev Run dev:ui and dev:back together
27
- dev:ui Preview the plugin in a mini-Muscat (preview-host)
28
- dev:back Run the plugin back end (python: watchfiles reload / ros2: Docker)
29
- preview Preview against a real Muscat server (prompts for robot IP)
30
- update Update @rainbow-robotics/muscat-plugin-kit and @rainbow-robotics/plugin-ui
31
- sdk <list|update [version]> Manage the python rainbow-rb-sdk version
78
+ const commandRow = (command, description) => ` ${color.cyan(command.padEnd(30))}${description}`;
79
+ const option = (text) => color.yellow(text);
32
80
 
33
- Run "muscat-pk <command> --help" for details.`;
81
+ function formatHelp() {
82
+ return [
83
+ `${color.bold("muscat-pk")} ${color.dim("— Muscat plugin kit")}`,
84
+ "",
85
+ `${color.bold("Usage:")} ${color.cyan("muscat-pk")} ${color.yellow("<command>")} ${color.dim("[options]")}`,
86
+ "",
87
+ color.bold("Commands:"),
88
+ commandRow("new [dir]", `Scaffold a new plugin project ${color.dim("(prompts: author, email, description, type, front-package-manager)")}`),
89
+ commandRow("type change", `Switch backend type ${color.dim("(python | cpp | ros2-python | ros2-cpp)")}`),
90
+ commandRow("build", `Build + lock deps + vendor wheels + zip ${color.dim(`(${option("--arch")} amd64|arm64|both)`)}`),
91
+ commandRow("dev", `Run a local Muscat runtime, dev:ui, and dev:back together ${color.dim(`(${option("--sim")} 500920|RBY2|rby1-a|rby1-m|rby1-ub)`)}`),
92
+ commandRow("dev:ui", `Preview the plugin in a mini-Muscat ${color.dim("(preview-host)")}`),
93
+ commandRow("dev:back", `Run the plugin back end ${color.dim("(python: watchfiles reload / ros2: Docker)")}`),
94
+ commandRow("storybook", `Browse the bundled rb-components Storybook ${color.dim(`(${option("--port")} <n>, ${option("--rebuild")})`)}`),
95
+ commandRow("mcp", `Start an MCP server ${color.dim("(stdio)")} exposing rb-components/rb SDK docs to AI agents ${color.dim(`(${option("--install")} codex: register in ~/.codex/config.toml)`)}`),
96
+ commandRow("update", `Update ${color.magenta("@rainbow-robotics/muscat-plugin-kit")}, ${color.magenta("@rainbow-robotics/plugin-ui")} and ${color.magenta("@rainbow-robotics/preview-host")} ${color.dim(`(local-only if run from a project's local install; ${option("--global")} also updates the global CLI)`)}`),
97
+ commandRow("uninstall", `Remove the installed ${color.cyan("muscat-pk")} CLI ${color.dim("(npm global or S3 binary)")}`),
98
+ commandRow("sdk <list|update [version]>", "Manage the python rainbow-rb-sdk version"),
99
+ commandRow("sim list", `List the robot simulators for ${option("dev --sim")}`),
100
+ commandRow("version", `Print the installed ${color.cyan("muscat-pk")} version`),
101
+ commandRow("completion [shell]", `Print a shell completion script ${color.dim("(bash | zsh | fish | powershell)")}`),
102
+ "",
103
+ `Run ${color.cyan("muscat-pk <command> --help")} for details.`,
104
+ ].join("\n");
105
+ }
34
106
 
35
107
  async function main() {
36
108
  try {
@@ -41,34 +113,58 @@ async function main() {
41
113
  return await runType(args);
42
114
  case "build":
43
115
  return await runBuild(args);
44
- case "pack":
45
- return await runPack(args);
46
116
  case "dev":
47
117
  return await runDev(args);
48
118
  case "dev:ui":
49
119
  return await runDevUi(args);
50
120
  case "dev:back":
51
121
  return await runDevBack(args);
52
- case "preview":
53
- return await runPreview(args);
122
+ case "storybook":
123
+ return await runStorybook(args);
124
+ case "mcp": {
125
+ // Relay by default so `muscat-pk update` reaches a running session; --serve is the server.
126
+ if (args[0] !== "--serve" && args[0] !== "--install" && args[0] !== "install")
127
+ return (await import("../src/mcpProxy.mjs")).runMcpProxy();
128
+ const { runMcp, installMcp } = await import("../src/mcp.mjs");
129
+ if (args[0] === "--install" || args[0] === "install")
130
+ return installMcp(args[1]);
131
+ return await runMcp(args);
132
+ }
54
133
  case "update":
55
134
  return await runUpdate(args);
135
+ case "update:check": // internal: update runs it with the freshly installed local kit
136
+ return await runUpdateCheck(args);
137
+ case "uninstall":
138
+ return await runUninstall(args);
56
139
  case "sdk":
57
140
  return await runSdk(args);
141
+ case "sim":
142
+ if (args[0] !== "list") throw new Error("usage: muscat-pk sim list");
143
+ return (await import("../src/sim.mjs")).runSimList();
144
+ case "completion":
145
+ return await runCompletion(args);
146
+ case "version":
147
+ case "-v":
148
+ case "--version":
149
+ console.log(kitVersion());
150
+ return;
58
151
  case undefined:
59
152
  case "-h":
60
153
  case "--help":
61
154
  case "help":
62
- console.log(HELP);
155
+ console.log(formatHelp());
63
156
  return;
64
157
  default:
65
158
  console.error(`Unknown command: ${cmd}\n`);
66
- console.log(HELP);
159
+ console.log(formatHelp());
67
160
  process.exitCode = 1;
68
161
  }
69
162
  } catch (err) {
70
- console.error(`\n✖ ${err?.message || err}`);
71
- process.exitCode = 1;
163
+ console.error();
164
+ log.error(err?.message || String(err));
165
+ // exit, not exitCode: a failed dev:ui (e.g. Ctrl+C before vite was ready) leaves file watchers that
166
+ // would keep the process hanging.
167
+ process.exit(1);
72
168
  }
73
169
  }
74
170
 
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ // Pre-build step: serialise cli/templates/** into cli/src/templates-embedded.mjs
3
+ // so that `bun build --compile` can embed them without needing the filesystem.
4
+ import { readdirSync, readFileSync, writeFileSync, statSync } from "node:fs";
5
+ import { resolve } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const root = resolve(fileURLToPath(import.meta.url), "..");
9
+ const out = resolve(root, "src/templates-embedded.mjs");
10
+
11
+ const files = {};
12
+ function walk(baseDir, prefix) {
13
+ for (const name of readdirSync(baseDir)) {
14
+ const full = resolve(baseDir, name);
15
+ const key = prefix + name;
16
+ if (statSync(full).isDirectory()) { walk(full + "/", key + "/"); continue; }
17
+ files[key] = readFileSync(full, "base64");
18
+ }
19
+ }
20
+ walk(resolve(root, "templates") + "/", "");
21
+ walk(resolve(root, "docker") + "/", "docker/");
22
+
23
+ const { version } = JSON.parse(readFileSync(resolve(root, "../package.json"), "utf8"));
24
+
25
+ writeFileSync(out,
26
+ `// AUTO-GENERATED by cli/bundle-templates.mjs — do not edit.\n` +
27
+ `// ponytail: generated at publish time; not tracked in git.\n` +
28
+ `export const KIT_VERSION = ${JSON.stringify(version)};\n` +
29
+ `export const TEMPLATES = ${JSON.stringify(files)};\n`
30
+ );
31
+ console.log(`bundled ${Object.keys(files).length} template files → src/templates-embedded.mjs`);
@@ -0,0 +1,28 @@
1
+ # Dev/build container for the pure C++ plugin back end.
2
+ # Matches the Muscat robot backend OS (Ubuntu 24.04) so the compiled binary
3
+ # is ABI-compatible with the robot. Used by `muscat-pk dev:back` and `build`
4
+ # — NOT shipped in the plugin ZIP.
5
+ FROM ubuntu:24.04
6
+ LABEL com.rainbow-robotics.muscat-pk="true"
7
+
8
+ RUN apt-get update && apt-get install -y --no-install-recommends \
9
+ build-essential \
10
+ cmake \
11
+ && rm -rf /var/lib/apt/lists/*
12
+
13
+ # Rainbow Robotics C++ SDK for find_package(rb_sdk). muscat-pk passes the version pinned in the
14
+ # project's CMakeLists.txt (find_package(rb_sdk <ver> EXACT)); without a pin (ROS 2 rclpy, `muscat-pk mcp`
15
+ # outside a project) the newest SDK is installed. Runtime and -dev are installed together at one version.
16
+ ARG RB_SDK_VERSION=
17
+ RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl \
18
+ && install -d /etc/apt/keyrings \
19
+ && curl -fsSL https://rainbowrobotics.github.io/rb-sdk/rb-sdk-apt-repo.gpg.key -o /etc/apt/keyrings/rb-sdk.asc \
20
+ && printf 'deb [signed-by=/etc/apt/keyrings/rb-sdk.asc] https://rainbowrobotics.github.io/rb-sdk %s main\n' stable dev > /etc/apt/sources.list.d/rb-sdk.list \
21
+ && apt-get update \
22
+ && apt-get install -y --no-install-recommends "rainbow-rb-sdk${RB_SDK_VERSION:+=$RB_SDK_VERSION}" "rainbow-rb-sdk-dev${RB_SDK_VERSION:+=$RB_SDK_VERSION}" \
23
+ && rm -rf /var/lib/apt/lists/*
24
+
25
+
26
+ WORKDIR /plugin
27
+
28
+ CMD ["bash"]
@@ -2,12 +2,29 @@
2
2
  # Matches the Muscat robot backend: ROS2 Jazzy + Python 3.12 (Ubuntu 24.04).
3
3
  # Used by `muscat-pk dev:back` — NOT shipped in the plugin ZIP.
4
4
  FROM ros:jazzy-ros-base
5
+ LABEL com.rainbow-robotics.muscat-pk="true"
5
6
 
6
7
  RUN apt-get update && apt-get install -y --no-install-recommends \
7
8
  python3-pip \
8
9
  python3-colcon-common-extensions \
9
10
  && rm -rf /var/lib/apt/lists/*
10
11
 
12
+ # Rainbow Robotics C++ SDK for find_package(rb_sdk). muscat-pk passes the version pinned in the
13
+ # project's CMakeLists.txt (find_package(rb_sdk <ver> EXACT)); without a pin (ROS 2 rclpy, `muscat-pk mcp`
14
+ # outside a project) the newest SDK is installed. Runtime and -dev are installed together at one version.
15
+ ARG RB_SDK_VERSION=
16
+ RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl \
17
+ && install -d /etc/apt/keyrings \
18
+ && curl -fsSL https://rainbowrobotics.github.io/rb-sdk/rb-sdk-apt-repo.gpg.key -o /etc/apt/keyrings/rb-sdk.asc \
19
+ && printf 'deb [signed-by=/etc/apt/keyrings/rb-sdk.asc] https://rainbowrobotics.github.io/rb-sdk %s main\n' stable dev > /etc/apt/sources.list.d/rb-sdk.list \
20
+ && apt-get update \
21
+ && apt-get install -y --no-install-recommends "rainbow-rb-sdk${RB_SDK_VERSION:+=$RB_SDK_VERSION}" "rainbow-rb-sdk-dev${RB_SDK_VERSION:+=$RB_SDK_VERSION}" \
22
+ && rm -rf /var/lib/apt/lists/*
23
+
24
+
25
+ # `docker exec` skips /ros_entrypoint.sh — source ROS for the login shells dev:back runs.
26
+ RUN echo ". /opt/ros/${ROS_DISTRO}/setup.sh" > /etc/profile.d/ros.sh
27
+
11
28
  WORKDIR /plugin
12
29
 
13
30
  CMD ["bash"]
@@ -0,0 +1,21 @@
1
+ # Dev/build container for the Python plugin back end.
2
+ # Matches the Muscat robot backend: Ubuntu 24.04 + Python 3.12.
3
+ # Used by `muscat-pk dev:back` (hot-reload) and `muscat-pk build` (lock + wheel vendor).
4
+ # NOT shipped in the plugin ZIP — the robot installs deps from dist/wheels/ offline.
5
+ FROM ubuntu:24.04
6
+ LABEL com.rainbow-robotics.muscat-pk="true"
7
+
8
+ RUN apt-get update && apt-get install -y --no-install-recommends \
9
+ python3 \
10
+ python3-pip \
11
+ && rm -rf /var/lib/apt/lists/* \
12
+ && pip3 install uv==0.8.18 --break-system-packages
13
+
14
+ # TODO(cpp-sdk): the Python SDK is a pybind wrapper over the cpp SDK, so the
15
+ # cpp SDK shared lib must be present for the python module to load. Install the
16
+ # rainbow cpp SDK (apt, pinned to the robot's version) here once it exists.
17
+
18
+
19
+ WORKDIR /plugin
20
+
21
+ CMD ["bash"]
@@ -0,0 +1,12 @@
1
+ // Runs on `npm publish` / `yarn npm publish` (and `npm pack`) via the "prepack"
2
+ // lifecycle hook. Builds the bundled Storybook (foundations + muscat) and stages
3
+ // it into cli/storybook-dist so it ships inside the published muscat-pk and
4
+ // `muscat-pk storybook` works from an external install.
5
+ //
6
+ // In the monorepo this runs the real build; outside it (re-packing an already
7
+ // published copy) buildStorybook() no-ops and the pre-staged dist is used.
8
+ import { buildStorybook } from "./src/storybook.mjs";
9
+ import { stageProgramCommands } from "./src/programCommands.mjs";
10
+
11
+ buildStorybook();
12
+ stageProgramCommands();