agenticros 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/LICENSE +192 -0
  2. package/README.md +90 -4
  3. package/dist/commands/config.d.ts +20 -0
  4. package/dist/commands/config.d.ts.map +1 -0
  5. package/dist/commands/config.js +143 -0
  6. package/dist/commands/config.js.map +1 -0
  7. package/dist/commands/doctor.d.ts +33 -0
  8. package/dist/commands/doctor.d.ts.map +1 -0
  9. package/dist/commands/doctor.js +232 -0
  10. package/dist/commands/doctor.js.map +1 -0
  11. package/dist/commands/down.d.ts +13 -0
  12. package/dist/commands/down.d.ts.map +1 -0
  13. package/dist/commands/down.js +81 -0
  14. package/dist/commands/down.js.map +1 -0
  15. package/dist/commands/init.d.ts +21 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +259 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/logs.d.ts +18 -0
  20. package/dist/commands/logs.d.ts.map +1 -0
  21. package/dist/commands/logs.js +67 -0
  22. package/dist/commands/logs.js.map +1 -0
  23. package/dist/commands/status.d.ts +12 -0
  24. package/dist/commands/status.d.ts.map +1 -0
  25. package/dist/commands/status.js +52 -0
  26. package/dist/commands/status.js.map +1 -0
  27. package/dist/commands/up.d.ts +19 -0
  28. package/dist/commands/up.d.ts.map +1 -0
  29. package/dist/commands/up.js +58 -0
  30. package/dist/commands/up.js.map +1 -0
  31. package/dist/index.d.ts +12 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +106 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/menu.d.ts +9 -0
  36. package/dist/menu.d.ts.map +1 -0
  37. package/dist/menu.js +96 -0
  38. package/dist/menu.js.map +1 -0
  39. package/dist/runners/real-robot.d.ts +15 -0
  40. package/dist/runners/real-robot.d.ts.map +1 -0
  41. package/dist/runners/real-robot.js +46 -0
  42. package/dist/runners/real-robot.js.map +1 -0
  43. package/dist/runners/sim.d.ts +17 -0
  44. package/dist/runners/sim.d.ts.map +1 -0
  45. package/dist/runners/sim.js +51 -0
  46. package/dist/runners/sim.js.map +1 -0
  47. package/dist/util/env.d.ts +24 -0
  48. package/dist/util/env.d.ts.map +1 -0
  49. package/dist/util/env.js +53 -0
  50. package/dist/util/env.js.map +1 -0
  51. package/dist/util/logger.d.ts +24 -0
  52. package/dist/util/logger.d.ts.map +1 -0
  53. package/dist/util/logger.js +62 -0
  54. package/dist/util/logger.js.map +1 -0
  55. package/dist/util/paths.d.ts +57 -0
  56. package/dist/util/paths.d.ts.map +1 -0
  57. package/dist/util/paths.js +132 -0
  58. package/dist/util/paths.js.map +1 -0
  59. package/dist/util/pidfile.d.ts +16 -0
  60. package/dist/util/pidfile.d.ts.map +1 -0
  61. package/dist/util/pidfile.js +63 -0
  62. package/dist/util/pidfile.js.map +1 -0
  63. package/dist/util/state.d.ts +26 -0
  64. package/dist/util/state.d.ts.map +1 -0
  65. package/dist/util/state.js +55 -0
  66. package/dist/util/state.js.map +1 -0
  67. package/package.json +60 -1
  68. package/runtime/BUNDLE.json +11 -0
  69. package/runtime/LICENSE +192 -0
  70. package/runtime/README.md +273 -0
  71. package/runtime/docs/architecture.md +366 -0
  72. package/runtime/docs/cli.md +140 -0
  73. package/runtime/docs/memory.md +292 -0
  74. package/runtime/docs/robot-setup.md +347 -0
  75. package/runtime/package.json +28 -0
  76. package/runtime/packages/agenticros/agenticros-agenticros-0.0.1.tgz +0 -0
  77. package/runtime/packages/agenticros/openclaw.plugin.json +451 -0
  78. package/runtime/packages/agenticros/package.json +41 -0
  79. package/runtime/packages/agenticros/src/camera-snapshot-cache.ts +59 -0
  80. package/runtime/packages/agenticros/src/camera-snapshot-routes.ts +44 -0
  81. package/runtime/packages/agenticros/src/commands/estop.ts +41 -0
  82. package/runtime/packages/agenticros/src/commands/transport.ts +195 -0
  83. package/runtime/packages/agenticros/src/config-file.ts +136 -0
  84. package/runtime/packages/agenticros/src/config-page.ts +498 -0
  85. package/runtime/packages/agenticros/src/context/robot-context.ts +373 -0
  86. package/runtime/packages/agenticros/src/depth.ts +313 -0
  87. package/runtime/packages/agenticros/src/describer.ts +157 -0
  88. package/runtime/packages/agenticros/src/image-binary-trim.ts +16 -0
  89. package/runtime/packages/agenticros/src/index.ts +85 -0
  90. package/runtime/packages/agenticros/src/landing-page.ts +38 -0
  91. package/runtime/packages/agenticros/src/memory.ts +44 -0
  92. package/runtime/packages/agenticros/src/plugin-api.ts +173 -0
  93. package/runtime/packages/agenticros/src/plugin-image-base64.ts +69 -0
  94. package/runtime/packages/agenticros/src/preflight.ts +110 -0
  95. package/runtime/packages/agenticros/src/routes.ts +328 -0
  96. package/runtime/packages/agenticros/src/safety/validator.ts +43 -0
  97. package/runtime/packages/agenticros/src/service.ts +359 -0
  98. package/runtime/packages/agenticros/src/skill-api.ts +65 -0
  99. package/runtime/packages/agenticros/src/skill-loader.ts +146 -0
  100. package/runtime/packages/agenticros/src/teleop/page.ts +498 -0
  101. package/runtime/packages/agenticros/src/teleop/routes.ts +650 -0
  102. package/runtime/packages/agenticros/src/tools/index.ts +26 -0
  103. package/runtime/packages/agenticros/src/tools/ros2-action.ts +50 -0
  104. package/runtime/packages/agenticros/src/tools/ros2-camera.ts +221 -0
  105. package/runtime/packages/agenticros/src/tools/ros2-depth-distance.ts +58 -0
  106. package/runtime/packages/agenticros/src/tools/ros2-introspect.ts +62 -0
  107. package/runtime/packages/agenticros/src/tools/ros2-memory.ts +158 -0
  108. package/runtime/packages/agenticros/src/tools/ros2-param.ts +87 -0
  109. package/runtime/packages/agenticros/src/tools/ros2-publish.ts +52 -0
  110. package/runtime/packages/agenticros/src/tools/ros2-service.ts +46 -0
  111. package/runtime/packages/agenticros/src/tools/ros2-subscribe.ts +71 -0
  112. package/runtime/packages/agenticros/tsconfig.json +9 -0
  113. package/runtime/packages/agenticros-claude-code/README.md +260 -0
  114. package/runtime/packages/agenticros-claude-code/config.example.json +9 -0
  115. package/runtime/packages/agenticros-claude-code/dist/config.d.ts +8 -0
  116. package/runtime/packages/agenticros-claude-code/dist/config.d.ts.map +1 -0
  117. package/runtime/packages/agenticros-claude-code/dist/config.js +93 -0
  118. package/runtime/packages/agenticros-claude-code/dist/config.js.map +1 -0
  119. package/runtime/packages/agenticros-claude-code/dist/depth.d.ts +20 -0
  120. package/runtime/packages/agenticros-claude-code/dist/depth.d.ts.map +1 -0
  121. package/runtime/packages/agenticros-claude-code/dist/depth.js +126 -0
  122. package/runtime/packages/agenticros-claude-code/dist/depth.js.map +1 -0
  123. package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.d.ts +6 -0
  124. package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.d.ts.map +1 -0
  125. package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.js +36 -0
  126. package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.js.map +1 -0
  127. package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.d.ts +33 -0
  128. package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.d.ts.map +1 -0
  129. package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.js +134 -0
  130. package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.js.map +1 -0
  131. package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.d.ts +43 -0
  132. package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.d.ts.map +1 -0
  133. package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.js +73 -0
  134. package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.js.map +1 -0
  135. package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.d.ts +58 -0
  136. package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.d.ts.map +1 -0
  137. package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.js +251 -0
  138. package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.js.map +1 -0
  139. package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.d.ts +61 -0
  140. package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.d.ts.map +1 -0
  141. package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.js +268 -0
  142. package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.js.map +1 -0
  143. package/runtime/packages/agenticros-claude-code/dist/index.d.ts +3 -0
  144. package/runtime/packages/agenticros-claude-code/dist/index.d.ts.map +1 -0
  145. package/runtime/packages/agenticros-claude-code/dist/index.js +111 -0
  146. package/runtime/packages/agenticros-claude-code/dist/index.js.map +1 -0
  147. package/runtime/packages/agenticros-claude-code/dist/memory.d.ts +17 -0
  148. package/runtime/packages/agenticros-claude-code/dist/memory.d.ts.map +1 -0
  149. package/runtime/packages/agenticros-claude-code/dist/memory.js +44 -0
  150. package/runtime/packages/agenticros-claude-code/dist/memory.js.map +1 -0
  151. package/runtime/packages/agenticros-claude-code/dist/safety.d.ts +10 -0
  152. package/runtime/packages/agenticros-claude-code/dist/safety.d.ts.map +1 -0
  153. package/runtime/packages/agenticros-claude-code/dist/safety.js +34 -0
  154. package/runtime/packages/agenticros-claude-code/dist/safety.js.map +1 -0
  155. package/runtime/packages/agenticros-claude-code/dist/tools.d.ts +36 -0
  156. package/runtime/packages/agenticros-claude-code/dist/tools.d.ts.map +1 -0
  157. package/runtime/packages/agenticros-claude-code/dist/tools.js +777 -0
  158. package/runtime/packages/agenticros-claude-code/dist/tools.js.map +1 -0
  159. package/runtime/packages/agenticros-claude-code/dist/transport.d.ts +17 -0
  160. package/runtime/packages/agenticros-claude-code/dist/transport.d.ts.map +1 -0
  161. package/runtime/packages/agenticros-claude-code/dist/transport.js +46 -0
  162. package/runtime/packages/agenticros-claude-code/dist/transport.js.map +1 -0
  163. package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.d.ts +42 -0
  164. package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.d.ts.map +1 -0
  165. package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.js +114 -0
  166. package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.js.map +1 -0
  167. package/runtime/packages/agenticros-claude-code/package.json +29 -0
  168. package/runtime/packages/agenticros-claude-code/src/config.ts +96 -0
  169. package/runtime/packages/agenticros-claude-code/src/depth.ts +173 -0
  170. package/runtime/packages/agenticros-claude-code/src/find-object/coco-classes.ts +38 -0
  171. package/runtime/packages/agenticros-claude-code/src/find-object/find-object.ts +190 -0
  172. package/runtime/packages/agenticros-claude-code/src/follow-me/controller.ts +109 -0
  173. package/runtime/packages/agenticros-claude-code/src/follow-me/depth-loop.ts +420 -0
  174. package/runtime/packages/agenticros-claude-code/src/follow-me/detector.ts +303 -0
  175. package/runtime/packages/agenticros-claude-code/src/follow-me/loop.ts +330 -0
  176. package/runtime/packages/agenticros-claude-code/src/index.ts +125 -0
  177. package/runtime/packages/agenticros-claude-code/src/memory.ts +51 -0
  178. package/runtime/packages/agenticros-claude-code/src/safety.ts +44 -0
  179. package/runtime/packages/agenticros-claude-code/src/tools.ts +891 -0
  180. package/runtime/packages/agenticros-claude-code/src/transport.ts +58 -0
  181. package/runtime/packages/agenticros-claude-code/src/zero-shot/detector.ts +169 -0
  182. package/runtime/packages/agenticros-claude-code/tsconfig.json +9 -0
  183. package/runtime/packages/agenticros-claude-code/yolo-debug.mjs +106 -0
  184. package/runtime/packages/agenticros-gemini/README.md +139 -0
  185. package/runtime/packages/agenticros-gemini/package.json +28 -0
  186. package/runtime/packages/agenticros-gemini/scripts/smoke-api.mjs +42 -0
  187. package/runtime/packages/agenticros-gemini/src/chat.ts +139 -0
  188. package/runtime/packages/agenticros-gemini/src/config.ts +92 -0
  189. package/runtime/packages/agenticros-gemini/src/depth.ts +173 -0
  190. package/runtime/packages/agenticros-gemini/src/index.ts +58 -0
  191. package/runtime/packages/agenticros-gemini/src/memory.ts +32 -0
  192. package/runtime/packages/agenticros-gemini/src/safety.ts +44 -0
  193. package/runtime/packages/agenticros-gemini/src/tools.ts +516 -0
  194. package/runtime/packages/agenticros-gemini/src/transport.ts +58 -0
  195. package/runtime/packages/agenticros-gemini/tsconfig.json +8 -0
  196. package/runtime/packages/core/package.json +47 -0
  197. package/runtime/packages/core/src/banner.ts +32 -0
  198. package/runtime/packages/core/src/cmd-vel-twist.ts +31 -0
  199. package/runtime/packages/core/src/config.ts +279 -0
  200. package/runtime/packages/core/src/index.ts +54 -0
  201. package/runtime/packages/core/src/memory/__tests__/factory.test.ts +70 -0
  202. package/runtime/packages/core/src/memory/__tests__/local-provider.test.ts +195 -0
  203. package/runtime/packages/core/src/memory/__tests__/mem0-provider.test.ts +192 -0
  204. package/runtime/packages/core/src/memory/__tests__/smart-defaults.test.ts +46 -0
  205. package/runtime/packages/core/src/memory/factory.ts +63 -0
  206. package/runtime/packages/core/src/memory/index.ts +10 -0
  207. package/runtime/packages/core/src/memory/local/provider.ts +229 -0
  208. package/runtime/packages/core/src/memory/mem0/provider.ts +379 -0
  209. package/runtime/packages/core/src/memory/types.ts +96 -0
  210. package/runtime/packages/core/src/topic-utils.ts +95 -0
  211. package/runtime/packages/core/src/transport/factory.ts +47 -0
  212. package/runtime/packages/core/src/transport/local/conversion.ts +333 -0
  213. package/runtime/packages/core/src/transport/local/entities.ts +129 -0
  214. package/runtime/packages/core/src/transport/local/transport.ts +386 -0
  215. package/runtime/packages/core/src/transport/rosbridge/actions.ts +81 -0
  216. package/runtime/packages/core/src/transport/rosbridge/adapter.ts +157 -0
  217. package/runtime/packages/core/src/transport/rosbridge/client.ts +438 -0
  218. package/runtime/packages/core/src/transport/rosbridge/services.ts +41 -0
  219. package/runtime/packages/core/src/transport/rosbridge/topics.ts +60 -0
  220. package/runtime/packages/core/src/transport/rosbridge/types.ts +118 -0
  221. package/runtime/packages/core/src/transport/transport.ts +77 -0
  222. package/runtime/packages/core/src/transport/types.ts +137 -0
  223. package/runtime/packages/core/src/transport/webrtc/signaling-client.ts +196 -0
  224. package/runtime/packages/core/src/transport/webrtc/signaling-types.ts +130 -0
  225. package/runtime/packages/core/src/transport/webrtc/transport.ts +516 -0
  226. package/runtime/packages/core/src/transport/zenoh/adapter.ts +357 -0
  227. package/runtime/packages/core/src/transport/zenoh/cdr.ts +183 -0
  228. package/runtime/packages/core/src/transport/zenoh/keys.ts +51 -0
  229. package/runtime/packages/core/tsconfig.json +9 -0
  230. package/runtime/packages/ros-camera/package.json +30 -0
  231. package/runtime/packages/ros-camera/src/index.ts +13 -0
  232. package/runtime/packages/ros-camera/src/snapshot.ts +372 -0
  233. package/runtime/packages/ros-camera/tsconfig.json +9 -0
  234. package/runtime/pnpm-lock.yaml +5260 -0
  235. package/runtime/pnpm-workspace.yaml +2 -0
  236. package/runtime/ros2_ws/src/agenticros_agent/agenticros_agent/__init__.py +0 -0
  237. package/runtime/ros2_ws/src/agenticros_agent/agenticros_agent/agent_node.py +561 -0
  238. package/runtime/ros2_ws/src/agenticros_agent/package.xml +25 -0
  239. package/runtime/ros2_ws/src/agenticros_agent/resource/agenticros_agent +0 -0
  240. package/runtime/ros2_ws/src/agenticros_agent/setup.cfg +4 -0
  241. package/runtime/ros2_ws/src/agenticros_agent/setup.py +25 -0
  242. package/runtime/ros2_ws/src/agenticros_bringup/README.md +128 -0
  243. package/runtime/ros2_ws/src/agenticros_bringup/agenticros_bringup/__init__.py +1 -0
  244. package/runtime/ros2_ws/src/agenticros_bringup/agenticros_bringup/cmd_vel_relay.py +33 -0
  245. package/runtime/ros2_ws/src/agenticros_bringup/launch/cmd_vel_bridge.launch.py +58 -0
  246. package/runtime/ros2_ws/src/agenticros_bringup/launch/gazebo_turtlebot3.launch.py +69 -0
  247. package/runtime/ros2_ws/src/agenticros_bringup/launch/mode_a_gazebo.launch.py +55 -0
  248. package/runtime/ros2_ws/src/agenticros_bringup/launch/mode_a_gazebo_rviz.launch.py +48 -0
  249. package/runtime/ros2_ws/src/agenticros_bringup/launch/realsense_rosbridge.launch.py +154 -0
  250. package/runtime/ros2_ws/src/agenticros_bringup/launch/rosbridge_gazebo.launch.py +54 -0
  251. package/runtime/ros2_ws/src/agenticros_bringup/launch/rviz.launch.py +38 -0
  252. package/runtime/ros2_ws/src/agenticros_bringup/launch/turtlebot3_gazebo_rviz.launch.py +42 -0
  253. package/runtime/ros2_ws/src/agenticros_bringup/package.xml +24 -0
  254. package/runtime/ros2_ws/src/agenticros_bringup/resource/agenticros_bringup +0 -0
  255. package/runtime/ros2_ws/src/agenticros_bringup/rviz/turtlebot3_agenticros.rviz +174 -0
  256. package/runtime/ros2_ws/src/agenticros_bringup/setup.cfg +4 -0
  257. package/runtime/ros2_ws/src/agenticros_bringup/setup.py +28 -0
  258. package/runtime/ros2_ws/src/agenticros_discovery/agenticros_discovery/__init__.py +0 -0
  259. package/runtime/ros2_ws/src/agenticros_discovery/agenticros_discovery/discovery_node.py +172 -0
  260. package/runtime/ros2_ws/src/agenticros_discovery/package.xml +22 -0
  261. package/runtime/ros2_ws/src/agenticros_discovery/resource/agenticros_discovery +0 -0
  262. package/runtime/ros2_ws/src/agenticros_discovery/setup.cfg +5 -0
  263. package/runtime/ros2_ws/src/agenticros_discovery/setup.py +25 -0
  264. package/runtime/ros2_ws/src/agenticros_follow_me/README.md +66 -0
  265. package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/__init__.py +1 -0
  266. package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/__main__.py +5 -0
  267. package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/follow_me_node.py +278 -0
  268. package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/follower_controller.py +631 -0
  269. package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/person_tracker.py +635 -0
  270. package/runtime/ros2_ws/src/agenticros_follow_me/package.xml +22 -0
  271. package/runtime/ros2_ws/src/agenticros_follow_me/resource/agenticros_follow_me +0 -0
  272. package/runtime/ros2_ws/src/agenticros_follow_me/setup.py +25 -0
  273. package/runtime/ros2_ws/src/agenticros_msgs/CMakeLists.txt +26 -0
  274. package/runtime/ros2_ws/src/agenticros_msgs/msg/CapabilityManifest.msg +9 -0
  275. package/runtime/ros2_ws/src/agenticros_msgs/package.xml +22 -0
  276. package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeGetStatus.srv +11 -0
  277. package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeSetDistance.srv +4 -0
  278. package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeSetTarget.srv +6 -0
  279. package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeStart.srv +5 -0
  280. package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeStop.srv +3 -0
  281. package/runtime/ros2_ws/src/agenticros_msgs/srv/GetCapabilities.srv +5 -0
  282. package/runtime/scripts/activate_workspace.sh +285 -0
  283. package/runtime/scripts/agenticros-describer.policy.yaml +96 -0
  284. package/runtime/scripts/agenticros-proxy.cjs +99 -0
  285. package/runtime/scripts/agenticros-rosbridge.policy.yaml +62 -0
  286. package/runtime/scripts/check-cli-tarball-size.mjs +42 -0
  287. package/runtime/scripts/configure_agenticros.sh +200 -0
  288. package/runtime/scripts/fix-openclaw-control-ui-path.sh +20 -0
  289. package/runtime/scripts/install_cli.sh +94 -0
  290. package/runtime/scripts/install_rosbridge_from_source.sh +67 -0
  291. package/runtime/scripts/lib/agenticros-banner.sh +28 -0
  292. package/runtime/scripts/onboard_robot.sh +75 -0
  293. package/runtime/scripts/openai.policy.yaml +77 -0
  294. package/runtime/scripts/openclaw-dashboard-url.cjs +49 -0
  295. package/runtime/scripts/pack-runtime.mjs +245 -0
  296. package/runtime/scripts/run_demo_native.sh +43 -0
  297. package/runtime/scripts/run_nemoclaw_host_stack.sh +91 -0
  298. package/runtime/scripts/run_robot_rosbridge.sh +36 -0
  299. package/runtime/scripts/sandbox_rosbridge_relay.py +137 -0
  300. package/runtime/scripts/setup-openclaw-local.cjs +75 -0
  301. package/runtime/scripts/setup_gateway_plugin.sh +329 -0
  302. package/runtime/scripts/setup_robot.sh +113 -0
  303. package/runtime/scripts/setup_workspace.sh +484 -0
  304. package/runtime/scripts/smoke_test_nemoclaw.sh +123 -0
  305. package/runtime/scripts/start_demo.sh +55 -0
  306. package/runtime/scripts/sync-skill-tools.mjs +335 -0
  307. package/runtime/scripts/test-rclnodejs.mts +129 -0
  308. package/runtime/scripts/use-openclaw-2026.2.26.sh +19 -0
  309. package/runtime/scripts/use-openclaw-2026.3.11.sh +19 -0
  310. package/runtime/scripts/zenoh-bridge-ros2dds-robot.json5 +30 -0
  311. package/runtime/scripts/zenohd-agenticros.json5 +11 -0
  312. package/runtime/scripts/zenohd-rosclaw.json5 +11 -0
  313. package/runtime/tsconfig.base.json +19 -0
  314. package/index.js +0 -6
@@ -0,0 +1,484 @@
1
+ #!/bin/bash
2
+ # setup_workspace.sh - Cross-platform setup for AgenticROS development environment
3
+ #
4
+ # DESCRIPTION:
5
+ # This script performs the initial setup required for AgenticROS development.
6
+ # It supports both Ubuntu (native ROS2) and macOS (RoboStack with mamba).
7
+ # The script installs dependencies, creates the appropriate environment,
8
+ # and builds all ROS2 packages. Run this script once before using the
9
+ # activate_workspace.sh script for daily development.
10
+ #
11
+ # USAGE:
12
+ # ./scripts/setup_workspace.sh [options]
13
+ #
14
+ # OPTIONS:
15
+ # -e, --env-name NAME Name of the environment to create (default: ros_env)
16
+ # -d, --ros-distro DISTRO ROS2 distribution (default: humble)
17
+ # -h, --help Show this help message
18
+ #
19
+ # EXAMPLES:
20
+ # # Use defaults (ros_env, jazzy)
21
+ # ./scripts/setup_workspace.sh
22
+ #
23
+ # # Custom environment name
24
+ # ./scripts/setup_workspace.sh --env-name my_ros_env
25
+ #
26
+ # # Different ROS2 distro
27
+ # ./scripts/setup_workspace.sh --ros-distro humble
28
+ #
29
+ # PLATFORMS SUPPORTED:
30
+ # - Ubuntu/Debian: Native ROS2 installation with apt + venv
31
+ # - macOS: RoboStack with mamba/conda environment
32
+ #
33
+ # WHAT IT DOES:
34
+ # 1. Detects platform (Ubuntu vs macOS)
35
+ # 2. Installs platform-specific infrastructure
36
+ # 3. Creates appropriate environment (venv with --system-site-packages vs conda)
37
+ # 4. Installs ROS2, rosbridge_library, and all required development tools
38
+ # 5. Installs agent-specific pip dependencies (aiortc, websockets)
39
+ # 6. Builds all ROS2 packages in ros2_ws
40
+ # 7. Validates the complete setup
41
+
42
+ set -e # Exit on any error
43
+
44
+ # Default values
45
+ DEFAULT_ENV_NAME="ros_env"
46
+ DEFAULT_ROS_DISTRO="humble"
47
+ ENV_NAME=""
48
+ ROS_DISTRO=""
49
+
50
+ # Find the repository root
51
+ REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
52
+ ROS2_WS_PATH="$REPO_ROOT/ros2_ws"
53
+
54
+ # Colors for output
55
+ RED='\033[0;31m'
56
+ GREEN='\033[0;32m'
57
+ YELLOW='\033[1;33m'
58
+ BLUE='\033[0;34m'
59
+ NC='\033[0m' # No Color
60
+
61
+ # Logging functions
62
+ log_info() {
63
+ echo -e "${BLUE}[INFO]${NC} $1"
64
+ }
65
+
66
+ log_success() {
67
+ echo -e "${GREEN}[SUCCESS]${NC} $1"
68
+ }
69
+
70
+ log_warning() {
71
+ echo -e "${YELLOW}[WARNING]${NC} $1"
72
+ }
73
+
74
+ log_error() {
75
+ echo -e "${RED}[ERROR]${NC} $1"
76
+ }
77
+
78
+ # Help function
79
+ show_help() {
80
+ cat << EOF
81
+ AgenticROS Development Environment Setup
82
+
83
+ USAGE:
84
+ $0 [options]
85
+
86
+ OPTIONS:
87
+ -e, --env-name NAME Name of the environment to create (default: $DEFAULT_ENV_NAME)
88
+ -d, --ros-distro DISTRO ROS2 distribution (default: $DEFAULT_ROS_DISTRO)
89
+ -h, --help Show this help message
90
+
91
+ EXAMPLES:
92
+ # Use defaults
93
+ $0
94
+
95
+ # Custom environment name
96
+ $0 --env-name my_ros_env
97
+
98
+ # Different ROS2 distribution
99
+ $0 --ros-distro humble
100
+
101
+ SUPPORTED PLATFORMS:
102
+ - Ubuntu/Debian: Native ROS2 with apt + Python venv
103
+ - macOS: RoboStack with mamba/conda environment
104
+
105
+ SUPPORTED ROS2 DISTRIBUTIONS:
106
+ - jazzy (default)
107
+ - humble
108
+ - kilted
109
+ EOF
110
+ }
111
+
112
+ # Parse command line arguments
113
+ parse_args() {
114
+ while [[ $# -gt 0 ]]; do
115
+ case $1 in
116
+ -e|--env-name)
117
+ ENV_NAME="$2"
118
+ shift 2
119
+ ;;
120
+ -d|--ros-distro)
121
+ ROS_DISTRO="$2"
122
+ shift 2
123
+ ;;
124
+ -h|--help)
125
+ show_help
126
+ exit 0
127
+ ;;
128
+ *)
129
+ log_error "Unknown option: $1"
130
+ show_help
131
+ exit 1
132
+ ;;
133
+ esac
134
+ done
135
+
136
+ # Set defaults if not specified
137
+ ENV_NAME="${ENV_NAME:-$DEFAULT_ENV_NAME}"
138
+ ROS_DISTRO="${ROS_DISTRO:-$DEFAULT_ROS_DISTRO}"
139
+ }
140
+
141
+ # Platform detection
142
+ detect_platform() {
143
+ if [[ "$OSTYPE" == "darwin"* ]]; then
144
+ PLATFORM="macos"
145
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
146
+ if command -v apt &> /dev/null; then
147
+ PLATFORM="ubuntu"
148
+ else
149
+ log_error "Linux platform detected but apt not found. Only Ubuntu/Debian supported."
150
+ exit 1
151
+ fi
152
+ else
153
+ log_error "Unsupported platform: $OSTYPE"
154
+ log_error "Supported platforms: macOS, Ubuntu/Debian"
155
+ exit 1
156
+ fi
157
+ }
158
+
159
+ # Check and install mamba/conda if needed (for macOS)
160
+ check_mamba() {
161
+ if ! command -v mamba &> /dev/null; then
162
+ if ! command -v conda &> /dev/null; then
163
+ log_info "Neither mamba nor conda found. Installing miniforge automatically..."
164
+
165
+ local installer="Miniforge3-MacOSX-$(uname -m).sh"
166
+ local url="https://github.com/conda-forge/miniforge/releases/latest/download/$installer"
167
+
168
+ log_info "Downloading miniforge installer..."
169
+ if ! curl -L -O "$url"; then
170
+ log_error "Failed to download miniforge installer"
171
+ exit 1
172
+ fi
173
+
174
+ log_info "Installing miniforge..."
175
+ if ! bash "$installer" -b -p "$HOME/miniforge3"; then
176
+ log_error "Failed to install miniforge"
177
+ exit 1
178
+ fi
179
+
180
+ rm -f "$installer"
181
+ eval "$($HOME/miniforge3/bin/conda shell.$(basename $SHELL) hook)"
182
+ log_success "Miniforge installed successfully"
183
+ else
184
+ log_warning "conda found but mamba not available. Installing mamba..."
185
+ conda install mamba -c conda-forge -y
186
+ fi
187
+ fi
188
+ }
189
+
190
+ # Validate ROS2 distribution support
191
+ validate_ros_distro() {
192
+ local supported_distros=("humble" "jazzy" "kilted")
193
+ local distro_supported=false
194
+
195
+ for supported in "${supported_distros[@]}"; do
196
+ if [[ "$ROS_DISTRO" == "$supported" ]]; then
197
+ distro_supported=true
198
+ break
199
+ fi
200
+ done
201
+
202
+ if [[ "$distro_supported" == false ]]; then
203
+ log_error "ROS2 distribution '$ROS_DISTRO' is not supported"
204
+ log_error "Supported distributions: ${supported_distros[*]}"
205
+ exit 1
206
+ fi
207
+ }
208
+
209
+ # Check if already in conda environment
210
+ check_conda_env_active() {
211
+ if [[ -n "$CONDA_DEFAULT_ENV" ]]; then
212
+ log_warning "Already in conda environment: $CONDA_DEFAULT_ENV"
213
+ if [[ "$CONDA_DEFAULT_ENV" == "$ENV_NAME" ]]; then
214
+ log_info "Already in target environment '$ENV_NAME', continuing setup..."
215
+ return 0
216
+ else
217
+ log_warning "In different environment. Will deactivate and switch to '$ENV_NAME'"
218
+ conda deactivate 2>/dev/null || true
219
+ mamba deactivate 2>/dev/null || true
220
+ fi
221
+ fi
222
+ return 1
223
+ }
224
+
225
+ # Ubuntu setup function
226
+ setup_ubuntu() {
227
+ log_info "Setting up Ubuntu environment..."
228
+
229
+ # Step 1: Install system dependencies
230
+ log_info "[1/5] Installing system dependencies..."
231
+ sudo apt update
232
+ sudo apt install -y \
233
+ python3-dev \
234
+ python3-venv \
235
+ python3-pip \
236
+ build-essential \
237
+ cmake \
238
+ pkg-config \
239
+ curl \
240
+ gnupg2 \
241
+ lsb-release \
242
+ software-properties-common
243
+
244
+ # Step 2: Install ROS2 and required packages
245
+ log_info "[2/5] Setting up ROS2 $ROS_DISTRO..."
246
+
247
+ if ! command -v ros2 &> /dev/null; then
248
+ log_info "Installing ROS2 $ROS_DISTRO..."
249
+
250
+ sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
251
+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
252
+
253
+ sudo apt update
254
+ else
255
+ log_success "ROS2 base already installed"
256
+ fi
257
+
258
+ log_info "Ensuring all required ROS2 packages are installed..."
259
+ sudo apt install -y \
260
+ ros-$ROS_DISTRO-ros-base \
261
+ ros-$ROS_DISTRO-rosbridge-library \
262
+ ros-$ROS_DISTRO-rosbridge-suite \
263
+ python3-colcon-common-extensions
264
+
265
+ log_success "All required ROS2 packages installed"
266
+
267
+ # Step 3: Create Python virtual environment with system site-packages
268
+ # This is critical: rclpy and rosbridge_library are system-installed via apt.
269
+ # The venv must inherit them via --system-site-packages.
270
+ log_info "[3/5] Setting up Python virtual environment..."
271
+ VENV_PATH="$REPO_ROOT/$ENV_NAME"
272
+
273
+ if [ -d "$VENV_PATH" ]; then
274
+ log_warning "Virtual environment already exists at: $VENV_PATH"
275
+ else
276
+ log_info "Creating virtual environment at: $VENV_PATH (with --system-site-packages)"
277
+ python3 -m venv "$VENV_PATH" --system-site-packages
278
+ log_success "Virtual environment created"
279
+ fi
280
+
281
+ # Step 4: Install agent-specific Python packages
282
+ log_info "[4/5] Installing Python packages for agenticros_agent..."
283
+ source "$VENV_PATH/bin/activate"
284
+ pip install --upgrade pip
285
+ pip install aiortc websockets
286
+ log_success "Python packages installed (aiortc, websockets)"
287
+
288
+ # Step 5: Build ROS2 packages
289
+ log_info "[5/5] Building ROS2 packages..."
290
+ cd "$ROS2_WS_PATH"
291
+ source /opt/ros/$ROS_DISTRO/setup.bash
292
+ colcon build --symlink-install
293
+ log_success "ROS2 packages built successfully"
294
+ }
295
+
296
+ # macOS setup function
297
+ setup_macos() {
298
+ log_info "Setting up macOS environment with RoboStack..."
299
+
300
+ # Step 1: Check mamba installation
301
+ log_info "[1/5] Checking mamba installation..."
302
+ check_mamba
303
+ log_success "Mamba is available"
304
+
305
+ # Step 2: Create conda environment
306
+ log_info "[2/5] Setting up conda environment '$ENV_NAME'..."
307
+
308
+ local already_in_target_env=false
309
+ if check_conda_env_active; then
310
+ already_in_target_env=true
311
+ fi
312
+
313
+ if mamba env list | grep -q "^$ENV_NAME "; then
314
+ log_warning "Environment '$ENV_NAME' already exists"
315
+ if [[ "$already_in_target_env" == false ]]; then
316
+ log_info "Activating existing environment..."
317
+ eval "$(mamba shell hook)"
318
+ mamba activate "$ENV_NAME"
319
+ fi
320
+ else
321
+ log_info "Creating new environment '$ENV_NAME'..."
322
+ mamba create -n "$ENV_NAME" -y
323
+ eval "$(mamba shell hook)"
324
+ mamba activate "$ENV_NAME"
325
+ fi
326
+
327
+ conda config --env --add channels conda-forge
328
+ conda config --env --remove channels defaults 2>/dev/null || true
329
+ conda config --env --add channels robostack-$ROS_DISTRO
330
+
331
+ # Step 3: Install ROS2 and development tools
332
+ log_info "[3/5] Installing ROS2 $ROS_DISTRO and development tools..."
333
+ mamba install -y \
334
+ ros-$ROS_DISTRO-ros-base \
335
+ ros-$ROS_DISTRO-rosbridge-library \
336
+ compilers \
337
+ cmake \
338
+ pkg-config \
339
+ make \
340
+ ninja \
341
+ colcon-common-extensions \
342
+ python \
343
+ pip
344
+
345
+ log_success "ROS2 and development tools installed"
346
+
347
+ # Step 4: Install agent-specific Python packages
348
+ log_info "[4/5] Installing Python packages for agenticros_agent..."
349
+ pip install aiortc websockets
350
+ log_success "Python packages installed (aiortc, websockets)"
351
+
352
+ # Deactivate and reactivate to ensure proper ROS setup
353
+ mamba deactivate
354
+ mamba activate "$ENV_NAME"
355
+
356
+ # Step 5: Build ROS2 packages
357
+ log_info "[5/5] Building ROS2 packages..."
358
+ cd "$ROS2_WS_PATH"
359
+ colcon build --symlink-install
360
+ log_success "ROS2 packages built successfully"
361
+ }
362
+
363
+ # Validation function
364
+ validate_setup() {
365
+ log_info "Validating setup..."
366
+
367
+ cd "$ROS2_WS_PATH"
368
+
369
+ if [[ "$PLATFORM" == "macos" ]]; then
370
+ eval "$(mamba shell hook)"
371
+ mamba activate "$ENV_NAME"
372
+ else
373
+ source /opt/ros/$ROS_DISTRO/setup.bash
374
+ source "$REPO_ROOT/$ENV_NAME/bin/activate"
375
+ fi
376
+
377
+ # Source workspace
378
+ if [ -f "install/setup.bash" ]; then
379
+ source install/setup.bash
380
+ log_success "Workspace sourced successfully"
381
+ else
382
+ log_error "Workspace build failed - install/setup.bash not found"
383
+ return 1
384
+ fi
385
+
386
+ # Test ROS2 functionality
387
+ if command -v ros2 &> /dev/null; then
388
+ log_success "ROS2 command available"
389
+ else
390
+ log_error "ROS2 command not available"
391
+ return 1
392
+ fi
393
+
394
+ # Test if our packages are available
395
+ local all_found=true
396
+ for pkg in agenticros_msgs agenticros_discovery agenticros_agent; do
397
+ if ros2 pkg list 2>/dev/null | grep -q "$pkg"; then
398
+ log_success "Package found: $pkg"
399
+ else
400
+ log_warning "Package not found: $pkg"
401
+ all_found=false
402
+ fi
403
+ done
404
+
405
+ # Test agent Python dependencies
406
+ if python3 -c "import aiortc; import websockets" 2>/dev/null; then
407
+ log_success "Agent Python dependencies available (aiortc, websockets)"
408
+ else
409
+ log_warning "Agent Python dependencies missing (aiortc or websockets)"
410
+ fi
411
+
412
+ # Test rosbridge_library availability
413
+ if python3 -c "from rosbridge_library.internal.ros_loader import get_message_class" 2>/dev/null; then
414
+ log_success "rosbridge_library available"
415
+ else
416
+ log_warning "rosbridge_library not available"
417
+ fi
418
+
419
+ return 0
420
+ }
421
+
422
+ # Main execution
423
+ main() {
424
+ # shellcheck source=scripts/lib/agenticros-banner.sh
425
+ source "$REPO_ROOT/scripts/lib/agenticros-banner.sh"
426
+ agenticros_banner
427
+ echo "AgenticROS Development Setup"
428
+ echo ""
429
+
430
+ parse_args "$@"
431
+ detect_platform
432
+
433
+ if [[ "$PLATFORM" == "macos" ]]; then
434
+ validate_ros_distro
435
+ fi
436
+
437
+ log_info "Platform detected: $PLATFORM"
438
+ log_info "Environment name: $ENV_NAME"
439
+ log_info "ROS2 distribution: $ROS_DISTRO"
440
+ log_info "Repository root: $REPO_ROOT"
441
+
442
+ if [[ "$PLATFORM" == "macos" && -n "$CONDA_DEFAULT_ENV" ]]; then
443
+ log_info "Current conda environment: $CONDA_DEFAULT_ENV"
444
+ fi
445
+ echo ""
446
+
447
+ case $PLATFORM in
448
+ ubuntu)
449
+ setup_ubuntu
450
+ ;;
451
+ macos)
452
+ setup_macos
453
+ ;;
454
+ *)
455
+ log_error "Unsupported platform: $PLATFORM"
456
+ exit 1
457
+ ;;
458
+ esac
459
+
460
+ echo ""
461
+
462
+ if validate_setup; then
463
+ log_success "Setup validation passed!"
464
+ else
465
+ log_error "Setup validation failed!"
466
+ exit 1
467
+ fi
468
+
469
+ echo ""
470
+ echo "Setup complete!"
471
+ echo ""
472
+ echo "Next steps:"
473
+ echo " 1. Activate your development environment for daily use:"
474
+ echo " source $REPO_ROOT/scripts/activate_workspace.sh"
475
+ echo ""
476
+ echo " 2. Test discovery node:"
477
+ echo " ros2 run agenticros_discovery discovery_node"
478
+ echo ""
479
+ echo " 3. Test agent node (requires signaling server):"
480
+ echo " AGENTICROS_SIGNALING_URL=ws://localhost:8000 ros2 run agenticros_agent agent_node"
481
+ echo ""
482
+ }
483
+
484
+ main "$@"
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Smoke-test the hybrid NemoClaw + AgenticROS bridge.
4
+ #
5
+ # Checks, in order:
6
+ # 1. NemoClaw sandbox container is up.
7
+ # 2. agenticros_rosbridge policy is loaded into the live gateway bundle
8
+ # with the SSRF allowed_ips block (so host.docker.internal is reachable).
9
+ # 3. rosbridge_server is bound on the host (0.0.0.0:9090).
10
+ # 4. The plugin's actual TCP connection through the OPA proxy is ALLOWED
11
+ # (not denied by engine:ssrf or engine:opa).
12
+ # 5. A real WebSocket request to /rosapi/topics through the proxy returns
13
+ # a list of ROS 2 topics (i.e. the gateway can both reach rosbridge and
14
+ # speak its protocol).
15
+ # 6. The NemoClaw dashboard HTTP endpoint serves a non-empty body.
16
+ #
17
+ # Exit code: 0 on all-pass, 1 on any failure. Prints a one-line PASS/FAIL per
18
+ # check + a final summary.
19
+ #
20
+ # Usage: ./scripts/smoke_test_nemoclaw.sh
21
+
22
+ set -uo pipefail
23
+
24
+ GREEN=$'\033[32m'; RED=$'\033[31m'; YELLOW=$'\033[33m'; RESET=$'\033[0m'
25
+ PASS=0; FAIL=0
26
+ pass() { echo "${GREEN}PASS${RESET} $*"; PASS=$((PASS+1)); }
27
+ fail() { echo "${RED}FAIL${RESET} $*"; FAIL=$((FAIL+1)); }
28
+ warn() { echo "${YELLOW}WARN${RESET} $*"; }
29
+
30
+ CONTAINER=$(docker ps --format '{{.Names}}' 2>/dev/null | grep '^openshell-nemo-' | head -1 || true)
31
+ if [[ -z "${CONTAINER}" ]]; then
32
+ fail "No openshell-nemo-* container running — start NemoClaw with 'nemoclaw nemo start'"
33
+ exit 1
34
+ fi
35
+ pass "sandbox container: ${CONTAINER}"
36
+
37
+ # ----- 2. agenticros_rosbridge policy loaded with allowed_ips ---------------
38
+ OPENSHELL_BIN="${OPENSHELL_BIN:-$(command -v openshell || echo "$HOME/.local/bin/openshell")}"
39
+ if [[ ! -x "${OPENSHELL_BIN}" ]]; then
40
+ warn "openshell CLI not found at ${OPENSHELL_BIN} — skipping policy bundle check"
41
+ else
42
+ POLICY_BUNDLE=$("${OPENSHELL_BIN}" policy get --full nemo 2>/dev/null || true)
43
+ if grep -q 'agenticros_rosbridge:' <<<"${POLICY_BUNDLE}"; then
44
+ if grep -q 'allowed_ips:' <<<"${POLICY_BUNDLE}"; then
45
+ pass "agenticros_rosbridge policy is loaded with allowed_ips (SSRF guard satisfied)"
46
+ else
47
+ fail "agenticros_rosbridge policy is loaded but missing allowed_ips — SSRF guard will deny"
48
+ fi
49
+ else
50
+ fail "agenticros_rosbridge policy is NOT loaded — run: nemoclaw nemo policy-add --yes --from-file scripts/agenticros-rosbridge.policy.yaml"
51
+ fi
52
+ fi
53
+
54
+ # ----- 3. rosbridge_server bound on host:9090 -------------------------------
55
+ if ss -ltn 2>/dev/null | awk '{print $4}' | grep -qE '(:9090|:::9090|0\.0\.0\.0:9090)$'; then
56
+ pass "rosbridge_server is listening on host :9090"
57
+ else
58
+ fail "nothing is listening on host :9090 — start the host stack: ./scripts/run_nemoclaw_host_stack.sh humble"
59
+ fi
60
+
61
+ # ----- 4. sandbox proxy decision for the plugin's binary --------------------
62
+ LOG_FILE=$(docker exec "${CONTAINER}" sh -c 'ls -t /var/log/openshell.*.log 2>/dev/null | head -1' 2>/dev/null | tr -d '\r')
63
+ if [[ -n "${LOG_FILE}" ]]; then
64
+ LAST_DECISION=$(docker exec "${CONTAINER}" sh -c "grep -E 'host.docker.internal:9090|host.openshell.internal:9090' '${LOG_FILE}' | tail -1" 2>/dev/null)
65
+ if [[ -z "${LAST_DECISION}" ]]; then
66
+ warn "no recent proxy decisions for host.docker.internal:9090 in ${LOG_FILE} (gateway hasn't tried yet?)"
67
+ elif grep -qE 'ALLOWED.*policy:agenticros_rosbridge' <<<"${LAST_DECISION}"; then
68
+ pass "last proxy decision: ALLOWED via agenticros_rosbridge"
69
+ elif grep -q 'engine:ssrf' <<<"${LAST_DECISION}"; then
70
+ fail "last proxy decision: DENIED by SSRF guard — add allowed_ips to the policy. Saw: ${LAST_DECISION##*OCSF }"
71
+ elif grep -q 'engine:opa' <<<"${LAST_DECISION}"; then
72
+ fail "last proxy decision: DENIED by OPA — endpoint missing from agenticros_rosbridge. Saw: ${LAST_DECISION##*OCSF }"
73
+ else
74
+ warn "unrecognised proxy decision: ${LAST_DECISION##*OCSF }"
75
+ fi
76
+ fi
77
+
78
+ # ----- 5. live WebSocket roundtrip to /rosapi/topics through the proxy ------
79
+ GW_PID=$(docker exec "${CONTAINER}" pgrep -f openclaw-gateway 2>/dev/null | head -1 | tr -d '\r')
80
+ WS_PATH=$(docker exec "${CONTAINER}" sh -c 'ls -d /sandbox/agenticros/node_modules/.pnpm/ws@*/node_modules/ws 2>/dev/null | head -1' | tr -d '\r')
81
+ if [[ -z "${GW_PID}" ]] || [[ -z "${WS_PATH}" ]]; then
82
+ warn "skip WebSocket roundtrip — gateway pid=${GW_PID:-?} ws=${WS_PATH:-?}"
83
+ else
84
+ TOPICS_JSON=$(docker exec "${CONTAINER}" sh -c "nsenter --target ${GW_PID} --net -- node --input-type=commonjs -e '
85
+ const http=require(\"http\");
86
+ const WebSocket=require(\"${WS_PATH}\");
87
+ const agent=new http.Agent({keepAlive:false});
88
+ agent.createConnection=(opts,cb)=>{
89
+ const req=http.request({host:\"10.200.0.1\",port:3128,method:\"CONNECT\",path:opts.host+\":\"+opts.port,headers:{Host:opts.host+\":\"+opts.port}});
90
+ req.on(\"connect\",(res,sock)=>{ if(res.statusCode!==200){cb(new Error(\"proxy \"+res.statusCode));return;} cb(null,sock); });
91
+ req.on(\"error\",cb); req.end();
92
+ };
93
+ const ws=new WebSocket(\"ws://host.docker.internal:9090\",{agent});
94
+ ws.on(\"open\",()=>ws.send(JSON.stringify({op:\"call_service\",service:\"/rosapi/topics\",id:\"smoke\"})));
95
+ ws.on(\"message\",m=>{const o=JSON.parse(m.toString()); console.log(JSON.stringify({count:(o.values&&o.values.topics||[]).length, sample:(o.values&&o.values.topics||[]).slice(0,3)})); ws.close(); process.exit(0);});
96
+ ws.on(\"error\",e=>{console.error(\"ERR\",e.message); process.exit(1);});
97
+ setTimeout(()=>{console.error(\"timeout\"); process.exit(2);},6000);
98
+ ' 2>&1" 2>/dev/null | tail -1)
99
+ if grep -qE '^\{"count":[0-9]+' <<<"${TOPICS_JSON}"; then
100
+ pass "WebSocket roundtrip: $(jq -r '"\(.count) topics, sample=\(.sample|join(", "))"' <<<"${TOPICS_JSON}" 2>/dev/null || echo "${TOPICS_JSON}")"
101
+ else
102
+ fail "WebSocket roundtrip failed: ${TOPICS_JSON:-<no output>}"
103
+ fi
104
+ fi
105
+
106
+ # ----- 6. NemoClaw dashboard reachable + non-empty --------------------------
107
+ DASH_URL=$(nemoclaw nemo dashboard-url --quiet 2>/dev/null | head -1 || true)
108
+ DASH_BASE=${DASH_URL%%#*}
109
+ if [[ -z "${DASH_BASE}" ]]; then
110
+ warn "dashboard URL not reported by nemoclaw (sandbox not Ready?)"
111
+ else
112
+ DASH_BYTES=$(curl -fsS "${DASH_BASE}" 2>/dev/null | wc -c | tr -d ' ')
113
+ if [[ -n "${DASH_BYTES}" ]] && [[ "${DASH_BYTES}" -gt 200 ]]; then
114
+ pass "dashboard at ${DASH_BASE} returns ${DASH_BYTES}-byte body"
115
+ echo " URL with token: ${DASH_URL}"
116
+ else
117
+ fail "dashboard at ${DASH_BASE} returned ${DASH_BYTES:-0} bytes — gateway crashed?"
118
+ fi
119
+ fi
120
+
121
+ echo
122
+ echo "Summary: ${GREEN}${PASS} passed${RESET}, ${RED}${FAIL} failed${RESET}"
123
+ [[ ${FAIL} -eq 0 ]]
@@ -0,0 +1,55 @@
1
+ #!/bin/bash
2
+ # start_demo.sh - Prepare the AgenticROS Claude Code demo (local DDS transport).
3
+ #
4
+ # What this does:
5
+ # 1. Sources ROS2 + the agenticros workspace
6
+ # 2. Launches the RealSense camera in the background (logs to /tmp)
7
+ # 3. Builds the @agenticros/claude-code MCP server
8
+ # 4. Starts the robot's motor controller via `robotics start motors`
9
+ #
10
+ # After this finishes, launch Claude Code from the repo root. The MCP server
11
+ # is auto-started by .mcp.json over stdio — nothing else to run on this host.
12
+ #
13
+ # Usage: ./scripts/start_demo.sh [jazzy|humble]
14
+
15
+ set -e
16
+
17
+ ROS_DISTRO="${1:-jazzy}"
18
+ REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
19
+ CAMERA_LOG=/tmp/agenticros-camera.log
20
+ CAMERA_PID_FILE=/tmp/agenticros-camera.pid
21
+ source "$REPO_ROOT/scripts/lib/agenticros-banner.sh"
22
+
23
+ agenticros_banner
24
+ echo "Starting AgenticROS Claude Code demo"
25
+ echo ""
26
+
27
+ echo "==> Sourcing ROS2 ($ROS_DISTRO) and agenticros workspace"
28
+ source "/opt/ros/$ROS_DISTRO/setup.bash"
29
+ if [[ -f "$REPO_ROOT/ros2_ws/install/setup.bash" ]]; then
30
+ source "$REPO_ROOT/ros2_ws/install/setup.bash"
31
+ else
32
+ echo " (ros2_ws is not built — run: cd ros2_ws && colcon build --symlink-install)"
33
+ fi
34
+
35
+ echo "==> Starting RealSense camera (logs: $CAMERA_LOG)"
36
+ if [[ -f "$CAMERA_PID_FILE" ]] && kill -0 "$(cat "$CAMERA_PID_FILE")" 2>/dev/null; then
37
+ echo " Already running (pid $(cat "$CAMERA_PID_FILE")) — skipping"
38
+ elif pgrep -f "realsense2_camera_node" >/dev/null; then
39
+ echo " Detected an existing realsense2_camera_node — skipping"
40
+ else
41
+ nohup ros2 launch realsense2_camera rs_launch.py >"$CAMERA_LOG" 2>&1 &
42
+ echo $! >"$CAMERA_PID_FILE"
43
+ echo " Started (pid $(cat "$CAMERA_PID_FILE"))"
44
+ fi
45
+
46
+ echo "==> Building @agenticros/claude-code MCP server"
47
+ cd "$REPO_ROOT"
48
+ pnpm --filter @agenticros/claude-code build
49
+
50
+ echo "==> Starting motor controller (robotics start motors)"
51
+ robotics start motors
52
+
53
+ echo ""
54
+ echo "Demo ready. Launch Claude Code from $REPO_ROOT — .mcp.json starts the MCP server."
55
+ echo "Stop the camera with: kill \$(cat $CAMERA_PID_FILE)"