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.
- package/LICENSE +192 -0
- package/README.md +90 -4
- package/dist/commands/config.d.ts +20 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +143 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/doctor.d.ts +33 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +232 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/down.d.ts +13 -0
- package/dist/commands/down.d.ts.map +1 -0
- package/dist/commands/down.js +81 -0
- package/dist/commands/down.js.map +1 -0
- package/dist/commands/init.d.ts +21 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +259 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logs.d.ts +18 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +67 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/status.d.ts +12 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +52 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/up.d.ts +19 -0
- package/dist/commands/up.d.ts.map +1 -0
- package/dist/commands/up.js +58 -0
- package/dist/commands/up.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +106 -0
- package/dist/index.js.map +1 -0
- package/dist/menu.d.ts +9 -0
- package/dist/menu.d.ts.map +1 -0
- package/dist/menu.js +96 -0
- package/dist/menu.js.map +1 -0
- package/dist/runners/real-robot.d.ts +15 -0
- package/dist/runners/real-robot.d.ts.map +1 -0
- package/dist/runners/real-robot.js +46 -0
- package/dist/runners/real-robot.js.map +1 -0
- package/dist/runners/sim.d.ts +17 -0
- package/dist/runners/sim.d.ts.map +1 -0
- package/dist/runners/sim.js +51 -0
- package/dist/runners/sim.js.map +1 -0
- package/dist/util/env.d.ts +24 -0
- package/dist/util/env.d.ts.map +1 -0
- package/dist/util/env.js +53 -0
- package/dist/util/env.js.map +1 -0
- package/dist/util/logger.d.ts +24 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +62 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/paths.d.ts +57 -0
- package/dist/util/paths.d.ts.map +1 -0
- package/dist/util/paths.js +132 -0
- package/dist/util/paths.js.map +1 -0
- package/dist/util/pidfile.d.ts +16 -0
- package/dist/util/pidfile.d.ts.map +1 -0
- package/dist/util/pidfile.js +63 -0
- package/dist/util/pidfile.js.map +1 -0
- package/dist/util/state.d.ts +26 -0
- package/dist/util/state.d.ts.map +1 -0
- package/dist/util/state.js +55 -0
- package/dist/util/state.js.map +1 -0
- package/package.json +60 -1
- package/runtime/BUNDLE.json +11 -0
- package/runtime/LICENSE +192 -0
- package/runtime/README.md +273 -0
- package/runtime/docs/architecture.md +366 -0
- package/runtime/docs/cli.md +140 -0
- package/runtime/docs/memory.md +292 -0
- package/runtime/docs/robot-setup.md +347 -0
- package/runtime/package.json +28 -0
- package/runtime/packages/agenticros/agenticros-agenticros-0.0.1.tgz +0 -0
- package/runtime/packages/agenticros/openclaw.plugin.json +451 -0
- package/runtime/packages/agenticros/package.json +41 -0
- package/runtime/packages/agenticros/src/camera-snapshot-cache.ts +59 -0
- package/runtime/packages/agenticros/src/camera-snapshot-routes.ts +44 -0
- package/runtime/packages/agenticros/src/commands/estop.ts +41 -0
- package/runtime/packages/agenticros/src/commands/transport.ts +195 -0
- package/runtime/packages/agenticros/src/config-file.ts +136 -0
- package/runtime/packages/agenticros/src/config-page.ts +498 -0
- package/runtime/packages/agenticros/src/context/robot-context.ts +373 -0
- package/runtime/packages/agenticros/src/depth.ts +313 -0
- package/runtime/packages/agenticros/src/describer.ts +157 -0
- package/runtime/packages/agenticros/src/image-binary-trim.ts +16 -0
- package/runtime/packages/agenticros/src/index.ts +85 -0
- package/runtime/packages/agenticros/src/landing-page.ts +38 -0
- package/runtime/packages/agenticros/src/memory.ts +44 -0
- package/runtime/packages/agenticros/src/plugin-api.ts +173 -0
- package/runtime/packages/agenticros/src/plugin-image-base64.ts +69 -0
- package/runtime/packages/agenticros/src/preflight.ts +110 -0
- package/runtime/packages/agenticros/src/routes.ts +328 -0
- package/runtime/packages/agenticros/src/safety/validator.ts +43 -0
- package/runtime/packages/agenticros/src/service.ts +359 -0
- package/runtime/packages/agenticros/src/skill-api.ts +65 -0
- package/runtime/packages/agenticros/src/skill-loader.ts +146 -0
- package/runtime/packages/agenticros/src/teleop/page.ts +498 -0
- package/runtime/packages/agenticros/src/teleop/routes.ts +650 -0
- package/runtime/packages/agenticros/src/tools/index.ts +26 -0
- package/runtime/packages/agenticros/src/tools/ros2-action.ts +50 -0
- package/runtime/packages/agenticros/src/tools/ros2-camera.ts +221 -0
- package/runtime/packages/agenticros/src/tools/ros2-depth-distance.ts +58 -0
- package/runtime/packages/agenticros/src/tools/ros2-introspect.ts +62 -0
- package/runtime/packages/agenticros/src/tools/ros2-memory.ts +158 -0
- package/runtime/packages/agenticros/src/tools/ros2-param.ts +87 -0
- package/runtime/packages/agenticros/src/tools/ros2-publish.ts +52 -0
- package/runtime/packages/agenticros/src/tools/ros2-service.ts +46 -0
- package/runtime/packages/agenticros/src/tools/ros2-subscribe.ts +71 -0
- package/runtime/packages/agenticros/tsconfig.json +9 -0
- package/runtime/packages/agenticros-claude-code/README.md +260 -0
- package/runtime/packages/agenticros-claude-code/config.example.json +9 -0
- package/runtime/packages/agenticros-claude-code/dist/config.d.ts +8 -0
- package/runtime/packages/agenticros-claude-code/dist/config.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/config.js +93 -0
- package/runtime/packages/agenticros-claude-code/dist/config.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/depth.d.ts +20 -0
- package/runtime/packages/agenticros-claude-code/dist/depth.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/depth.js +126 -0
- package/runtime/packages/agenticros-claude-code/dist/depth.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.d.ts +6 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.js +36 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.d.ts +33 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.js +134 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.d.ts +43 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.js +73 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.d.ts +58 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.js +251 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.d.ts +61 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.js +268 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/index.d.ts +3 -0
- package/runtime/packages/agenticros-claude-code/dist/index.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/index.js +111 -0
- package/runtime/packages/agenticros-claude-code/dist/index.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/memory.d.ts +17 -0
- package/runtime/packages/agenticros-claude-code/dist/memory.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/memory.js +44 -0
- package/runtime/packages/agenticros-claude-code/dist/memory.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/safety.d.ts +10 -0
- package/runtime/packages/agenticros-claude-code/dist/safety.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/safety.js +34 -0
- package/runtime/packages/agenticros-claude-code/dist/safety.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/tools.d.ts +36 -0
- package/runtime/packages/agenticros-claude-code/dist/tools.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/tools.js +777 -0
- package/runtime/packages/agenticros-claude-code/dist/tools.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/transport.d.ts +17 -0
- package/runtime/packages/agenticros-claude-code/dist/transport.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/transport.js +46 -0
- package/runtime/packages/agenticros-claude-code/dist/transport.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.d.ts +42 -0
- package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.js +114 -0
- package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/package.json +29 -0
- package/runtime/packages/agenticros-claude-code/src/config.ts +96 -0
- package/runtime/packages/agenticros-claude-code/src/depth.ts +173 -0
- package/runtime/packages/agenticros-claude-code/src/find-object/coco-classes.ts +38 -0
- package/runtime/packages/agenticros-claude-code/src/find-object/find-object.ts +190 -0
- package/runtime/packages/agenticros-claude-code/src/follow-me/controller.ts +109 -0
- package/runtime/packages/agenticros-claude-code/src/follow-me/depth-loop.ts +420 -0
- package/runtime/packages/agenticros-claude-code/src/follow-me/detector.ts +303 -0
- package/runtime/packages/agenticros-claude-code/src/follow-me/loop.ts +330 -0
- package/runtime/packages/agenticros-claude-code/src/index.ts +125 -0
- package/runtime/packages/agenticros-claude-code/src/memory.ts +51 -0
- package/runtime/packages/agenticros-claude-code/src/safety.ts +44 -0
- package/runtime/packages/agenticros-claude-code/src/tools.ts +891 -0
- package/runtime/packages/agenticros-claude-code/src/transport.ts +58 -0
- package/runtime/packages/agenticros-claude-code/src/zero-shot/detector.ts +169 -0
- package/runtime/packages/agenticros-claude-code/tsconfig.json +9 -0
- package/runtime/packages/agenticros-claude-code/yolo-debug.mjs +106 -0
- package/runtime/packages/agenticros-gemini/README.md +139 -0
- package/runtime/packages/agenticros-gemini/package.json +28 -0
- package/runtime/packages/agenticros-gemini/scripts/smoke-api.mjs +42 -0
- package/runtime/packages/agenticros-gemini/src/chat.ts +139 -0
- package/runtime/packages/agenticros-gemini/src/config.ts +92 -0
- package/runtime/packages/agenticros-gemini/src/depth.ts +173 -0
- package/runtime/packages/agenticros-gemini/src/index.ts +58 -0
- package/runtime/packages/agenticros-gemini/src/memory.ts +32 -0
- package/runtime/packages/agenticros-gemini/src/safety.ts +44 -0
- package/runtime/packages/agenticros-gemini/src/tools.ts +516 -0
- package/runtime/packages/agenticros-gemini/src/transport.ts +58 -0
- package/runtime/packages/agenticros-gemini/tsconfig.json +8 -0
- package/runtime/packages/core/package.json +47 -0
- package/runtime/packages/core/src/banner.ts +32 -0
- package/runtime/packages/core/src/cmd-vel-twist.ts +31 -0
- package/runtime/packages/core/src/config.ts +279 -0
- package/runtime/packages/core/src/index.ts +54 -0
- package/runtime/packages/core/src/memory/__tests__/factory.test.ts +70 -0
- package/runtime/packages/core/src/memory/__tests__/local-provider.test.ts +195 -0
- package/runtime/packages/core/src/memory/__tests__/mem0-provider.test.ts +192 -0
- package/runtime/packages/core/src/memory/__tests__/smart-defaults.test.ts +46 -0
- package/runtime/packages/core/src/memory/factory.ts +63 -0
- package/runtime/packages/core/src/memory/index.ts +10 -0
- package/runtime/packages/core/src/memory/local/provider.ts +229 -0
- package/runtime/packages/core/src/memory/mem0/provider.ts +379 -0
- package/runtime/packages/core/src/memory/types.ts +96 -0
- package/runtime/packages/core/src/topic-utils.ts +95 -0
- package/runtime/packages/core/src/transport/factory.ts +47 -0
- package/runtime/packages/core/src/transport/local/conversion.ts +333 -0
- package/runtime/packages/core/src/transport/local/entities.ts +129 -0
- package/runtime/packages/core/src/transport/local/transport.ts +386 -0
- package/runtime/packages/core/src/transport/rosbridge/actions.ts +81 -0
- package/runtime/packages/core/src/transport/rosbridge/adapter.ts +157 -0
- package/runtime/packages/core/src/transport/rosbridge/client.ts +438 -0
- package/runtime/packages/core/src/transport/rosbridge/services.ts +41 -0
- package/runtime/packages/core/src/transport/rosbridge/topics.ts +60 -0
- package/runtime/packages/core/src/transport/rosbridge/types.ts +118 -0
- package/runtime/packages/core/src/transport/transport.ts +77 -0
- package/runtime/packages/core/src/transport/types.ts +137 -0
- package/runtime/packages/core/src/transport/webrtc/signaling-client.ts +196 -0
- package/runtime/packages/core/src/transport/webrtc/signaling-types.ts +130 -0
- package/runtime/packages/core/src/transport/webrtc/transport.ts +516 -0
- package/runtime/packages/core/src/transport/zenoh/adapter.ts +357 -0
- package/runtime/packages/core/src/transport/zenoh/cdr.ts +183 -0
- package/runtime/packages/core/src/transport/zenoh/keys.ts +51 -0
- package/runtime/packages/core/tsconfig.json +9 -0
- package/runtime/packages/ros-camera/package.json +30 -0
- package/runtime/packages/ros-camera/src/index.ts +13 -0
- package/runtime/packages/ros-camera/src/snapshot.ts +372 -0
- package/runtime/packages/ros-camera/tsconfig.json +9 -0
- package/runtime/pnpm-lock.yaml +5260 -0
- package/runtime/pnpm-workspace.yaml +2 -0
- package/runtime/ros2_ws/src/agenticros_agent/agenticros_agent/__init__.py +0 -0
- package/runtime/ros2_ws/src/agenticros_agent/agenticros_agent/agent_node.py +561 -0
- package/runtime/ros2_ws/src/agenticros_agent/package.xml +25 -0
- package/runtime/ros2_ws/src/agenticros_agent/resource/agenticros_agent +0 -0
- package/runtime/ros2_ws/src/agenticros_agent/setup.cfg +4 -0
- package/runtime/ros2_ws/src/agenticros_agent/setup.py +25 -0
- package/runtime/ros2_ws/src/agenticros_bringup/README.md +128 -0
- package/runtime/ros2_ws/src/agenticros_bringup/agenticros_bringup/__init__.py +1 -0
- package/runtime/ros2_ws/src/agenticros_bringup/agenticros_bringup/cmd_vel_relay.py +33 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/cmd_vel_bridge.launch.py +58 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/gazebo_turtlebot3.launch.py +69 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/mode_a_gazebo.launch.py +55 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/mode_a_gazebo_rviz.launch.py +48 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/realsense_rosbridge.launch.py +154 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/rosbridge_gazebo.launch.py +54 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/rviz.launch.py +38 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/turtlebot3_gazebo_rviz.launch.py +42 -0
- package/runtime/ros2_ws/src/agenticros_bringup/package.xml +24 -0
- package/runtime/ros2_ws/src/agenticros_bringup/resource/agenticros_bringup +0 -0
- package/runtime/ros2_ws/src/agenticros_bringup/rviz/turtlebot3_agenticros.rviz +174 -0
- package/runtime/ros2_ws/src/agenticros_bringup/setup.cfg +4 -0
- package/runtime/ros2_ws/src/agenticros_bringup/setup.py +28 -0
- package/runtime/ros2_ws/src/agenticros_discovery/agenticros_discovery/__init__.py +0 -0
- package/runtime/ros2_ws/src/agenticros_discovery/agenticros_discovery/discovery_node.py +172 -0
- package/runtime/ros2_ws/src/agenticros_discovery/package.xml +22 -0
- package/runtime/ros2_ws/src/agenticros_discovery/resource/agenticros_discovery +0 -0
- package/runtime/ros2_ws/src/agenticros_discovery/setup.cfg +5 -0
- package/runtime/ros2_ws/src/agenticros_discovery/setup.py +25 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/README.md +66 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/__init__.py +1 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/__main__.py +5 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/follow_me_node.py +278 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/follower_controller.py +631 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/person_tracker.py +635 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/package.xml +22 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/resource/agenticros_follow_me +0 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/setup.py +25 -0
- package/runtime/ros2_ws/src/agenticros_msgs/CMakeLists.txt +26 -0
- package/runtime/ros2_ws/src/agenticros_msgs/msg/CapabilityManifest.msg +9 -0
- package/runtime/ros2_ws/src/agenticros_msgs/package.xml +22 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeGetStatus.srv +11 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeSetDistance.srv +4 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeSetTarget.srv +6 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeStart.srv +5 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeStop.srv +3 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/GetCapabilities.srv +5 -0
- package/runtime/scripts/activate_workspace.sh +285 -0
- package/runtime/scripts/agenticros-describer.policy.yaml +96 -0
- package/runtime/scripts/agenticros-proxy.cjs +99 -0
- package/runtime/scripts/agenticros-rosbridge.policy.yaml +62 -0
- package/runtime/scripts/check-cli-tarball-size.mjs +42 -0
- package/runtime/scripts/configure_agenticros.sh +200 -0
- package/runtime/scripts/fix-openclaw-control-ui-path.sh +20 -0
- package/runtime/scripts/install_cli.sh +94 -0
- package/runtime/scripts/install_rosbridge_from_source.sh +67 -0
- package/runtime/scripts/lib/agenticros-banner.sh +28 -0
- package/runtime/scripts/onboard_robot.sh +75 -0
- package/runtime/scripts/openai.policy.yaml +77 -0
- package/runtime/scripts/openclaw-dashboard-url.cjs +49 -0
- package/runtime/scripts/pack-runtime.mjs +245 -0
- package/runtime/scripts/run_demo_native.sh +43 -0
- package/runtime/scripts/run_nemoclaw_host_stack.sh +91 -0
- package/runtime/scripts/run_robot_rosbridge.sh +36 -0
- package/runtime/scripts/sandbox_rosbridge_relay.py +137 -0
- package/runtime/scripts/setup-openclaw-local.cjs +75 -0
- package/runtime/scripts/setup_gateway_plugin.sh +329 -0
- package/runtime/scripts/setup_robot.sh +113 -0
- package/runtime/scripts/setup_workspace.sh +484 -0
- package/runtime/scripts/smoke_test_nemoclaw.sh +123 -0
- package/runtime/scripts/start_demo.sh +55 -0
- package/runtime/scripts/sync-skill-tools.mjs +335 -0
- package/runtime/scripts/test-rclnodejs.mts +129 -0
- package/runtime/scripts/use-openclaw-2026.2.26.sh +19 -0
- package/runtime/scripts/use-openclaw-2026.3.11.sh +19 -0
- package/runtime/scripts/zenoh-bridge-ros2dds-robot.json5 +30 -0
- package/runtime/scripts/zenohd-agenticros.json5 +11 -0
- package/runtime/scripts/zenohd-rosclaw.json5 +11 -0
- package/runtime/tsconfig.base.json +19 -0
- package/index.js +0 -6
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* sync-skill-tools.mjs
|
|
4
|
+
*
|
|
5
|
+
* Discover AgenticROS skill tool names and merge them into the agenticros plugin's
|
|
6
|
+
* `contracts.tools` allowlist in `packages/agenticros/openclaw.plugin.json`.
|
|
7
|
+
*
|
|
8
|
+
* OpenClaw 2026+ enforces `contracts.tools` as a strict allowlist: any tool that a
|
|
9
|
+
* plugin registers at runtime but that is not declared in the manifest is rejected
|
|
10
|
+
* with `plugin must declare contracts.tools for: <name>` and silently dropped.
|
|
11
|
+
* Since AgenticROS skills register their own tools dynamically (e.g. `follow_robot`),
|
|
12
|
+
* the manifest must list every skill tool that should be exposed.
|
|
13
|
+
*
|
|
14
|
+
* How it works
|
|
15
|
+
* ------------
|
|
16
|
+
* 1. Resolve the OpenClaw config (OPENCLAW_CONFIG or ~/.openclaw/openclaw.json).
|
|
17
|
+
* 2. Read `plugins.entries.agenticros.config.skillPaths` and `.skillPackages`.
|
|
18
|
+
* 3. For each entry, locate the skill's built entry (dist/index.js), import it,
|
|
19
|
+
* and call `registerSkill(api, config, context)` with a stub `api` whose
|
|
20
|
+
* `registerTool` is a spy that just records `tool.name`.
|
|
21
|
+
* 4. Merge the discovered tool names with the static core tool list and write
|
|
22
|
+
* them back into `packages/agenticros/openclaw.plugin.json`.
|
|
23
|
+
*
|
|
24
|
+
* Usage
|
|
25
|
+
* -----
|
|
26
|
+
* node scripts/sync-skill-tools.mjs # write the manifest
|
|
27
|
+
* node scripts/sync-skill-tools.mjs --dry-run # print what would change
|
|
28
|
+
* node scripts/sync-skill-tools.mjs --verbose # show per-skill discovery details
|
|
29
|
+
*
|
|
30
|
+
* Run this whenever you add, remove, or rebuild a skill in `skillPaths` /
|
|
31
|
+
* `skillPackages`. After it succeeds, refresh the OpenClaw plugin registry
|
|
32
|
+
* (`openclaw plugins registry --refresh`) and restart the gateway so OpenClaw
|
|
33
|
+
* re-reads the updated `contracts.tools`.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
37
|
+
import { join, resolve, dirname, isAbsolute } from "node:path";
|
|
38
|
+
import { homedir } from "node:os";
|
|
39
|
+
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
40
|
+
import { createRequire } from "node:module";
|
|
41
|
+
|
|
42
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
43
|
+
const __dirname = dirname(__filename);
|
|
44
|
+
const REPO_ROOT = resolve(__dirname, "..");
|
|
45
|
+
const MANIFEST_PATH = join(REPO_ROOT, "packages/agenticros/openclaw.plugin.json");
|
|
46
|
+
|
|
47
|
+
const args = new Set(process.argv.slice(2));
|
|
48
|
+
const DRY_RUN = args.has("--dry-run") || args.has("-n");
|
|
49
|
+
const VERBOSE = args.has("--verbose") || args.has("-v");
|
|
50
|
+
|
|
51
|
+
const CORE_TOOLS = [
|
|
52
|
+
"ros2_publish",
|
|
53
|
+
"ros2_subscribe_once",
|
|
54
|
+
"ros2_service_call",
|
|
55
|
+
"ros2_action_goal",
|
|
56
|
+
"ros2_param_get",
|
|
57
|
+
"ros2_param_set",
|
|
58
|
+
"ros2_list_topics",
|
|
59
|
+
"ros2_camera_snapshot",
|
|
60
|
+
"ros2_depth_distance",
|
|
61
|
+
// Memory tools (registered conditionally at runtime when memory.enabled=true).
|
|
62
|
+
// Listed here so they remain in the allowlist after sync-skill-tools rewrites it.
|
|
63
|
+
"memory_remember",
|
|
64
|
+
"memory_recall",
|
|
65
|
+
"memory_forget",
|
|
66
|
+
"memory_status",
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
function log(...m) {
|
|
70
|
+
console.log("[sync-skill-tools]", ...m);
|
|
71
|
+
}
|
|
72
|
+
function vlog(...m) {
|
|
73
|
+
if (VERBOSE) console.log("[sync-skill-tools]", ...m);
|
|
74
|
+
}
|
|
75
|
+
function warn(...m) {
|
|
76
|
+
console.warn("[sync-skill-tools] WARN:", ...m);
|
|
77
|
+
}
|
|
78
|
+
function fail(msg) {
|
|
79
|
+
console.error("[sync-skill-tools] ERROR:", msg);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getOpenClawConfigPath() {
|
|
84
|
+
const env = process.env.OPENCLAW_CONFIG;
|
|
85
|
+
if (env && env.length > 0) return resolve(env);
|
|
86
|
+
return join(homedir(), ".openclaw", "openclaw.json");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function readOpenClawConfig() {
|
|
90
|
+
const p = getOpenClawConfigPath();
|
|
91
|
+
if (!existsSync(p)) {
|
|
92
|
+
warn(`OpenClaw config not found: ${p} — assuming no skills configured.`);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
return JSON.parse(readFileSync(p, "utf8"));
|
|
97
|
+
} catch (e) {
|
|
98
|
+
fail(`Cannot parse ${p}: ${e?.message ?? e}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getSkillEntries(cfg) {
|
|
103
|
+
const skillPaths = cfg?.plugins?.entries?.agenticros?.config?.skillPaths ?? [];
|
|
104
|
+
const skillPackages = cfg?.plugins?.entries?.agenticros?.config?.skillPackages ?? [];
|
|
105
|
+
return { skillPaths, skillPackages };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function findSkillEntryFromPath(dirPath) {
|
|
109
|
+
if (!existsSync(dirPath)) {
|
|
110
|
+
warn(`skillPaths entry does not exist: ${dirPath}`);
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
const pkgPath = join(dirPath, "package.json");
|
|
114
|
+
if (!existsSync(pkgPath)) {
|
|
115
|
+
warn(`skillPaths entry missing package.json: ${dirPath}`);
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
let pkg;
|
|
119
|
+
try {
|
|
120
|
+
pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
121
|
+
} catch (e) {
|
|
122
|
+
warn(`Invalid package.json in ${dirPath}: ${e?.message ?? e}`);
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
if (!pkg.agenticrosSkill) {
|
|
126
|
+
warn(`Not an AgenticROS skill (missing agenticrosSkill flag): ${dirPath}`);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
const main = pkg.main ?? "index.js";
|
|
130
|
+
const entry = join(dirPath, main);
|
|
131
|
+
if (!existsSync(entry)) {
|
|
132
|
+
warn(`Skill entry not built (run pnpm build in the skill repo): ${entry}`);
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
return { entry, packageName: pkg.name ?? dirPath, packageJson: pkg };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function resolvePackageEntry(packageName) {
|
|
139
|
+
if (!packageName || packageName.trim() === "") return null;
|
|
140
|
+
if (packageName.includes(" ")) {
|
|
141
|
+
warn(`Invalid skillPackages entry (contains spaces): "${packageName}"`);
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const req = createRequire(join(REPO_ROOT, "package.json"));
|
|
146
|
+
const entry = req.resolve(packageName);
|
|
147
|
+
return entry;
|
|
148
|
+
} catch {
|
|
149
|
+
warn(`Skill package not resolvable from repo root: ${packageName}`);
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Create a stub OpenClawPluginApi that captures registerTool calls.
|
|
156
|
+
* Other methods are no-ops so that registerSkill can complete without crashing.
|
|
157
|
+
*/
|
|
158
|
+
function createSpyApi() {
|
|
159
|
+
const tools = [];
|
|
160
|
+
const noop = () => {};
|
|
161
|
+
const noopLog = {
|
|
162
|
+
info: (m) => vlog(" skill.logger.info:", m),
|
|
163
|
+
warn: (m) => vlog(" skill.logger.warn:", m),
|
|
164
|
+
error: (m) => vlog(" skill.logger.error:", m),
|
|
165
|
+
};
|
|
166
|
+
return {
|
|
167
|
+
tools,
|
|
168
|
+
api: {
|
|
169
|
+
pluginConfig: {},
|
|
170
|
+
logger: noopLog,
|
|
171
|
+
registerTool(tool) {
|
|
172
|
+
if (tool && typeof tool.name === "string" && tool.name.length > 0) {
|
|
173
|
+
tools.push(tool.name);
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
registerService: noop,
|
|
177
|
+
registerCommand: noop,
|
|
178
|
+
registerHttpRoute: noop,
|
|
179
|
+
on: noop,
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function createStubContext() {
|
|
185
|
+
return {
|
|
186
|
+
getTransport() {
|
|
187
|
+
throw new Error("stub: getTransport not available during contract discovery");
|
|
188
|
+
},
|
|
189
|
+
getDepthDistance() {
|
|
190
|
+
return Promise.resolve({ valid: false, distance_m: 0 });
|
|
191
|
+
},
|
|
192
|
+
getDepthSectors() {
|
|
193
|
+
return Promise.resolve({ valid: false, left_m: 0, center_m: 0, right_m: 0 });
|
|
194
|
+
},
|
|
195
|
+
logger: {
|
|
196
|
+
info: () => {},
|
|
197
|
+
warn: () => {},
|
|
198
|
+
error: () => {},
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async function discoverSkillTools(entryPath, packageName) {
|
|
204
|
+
const url = pathToFileURL(entryPath).href;
|
|
205
|
+
let mod;
|
|
206
|
+
try {
|
|
207
|
+
mod = await import(url);
|
|
208
|
+
} catch (e) {
|
|
209
|
+
warn(`Failed to import ${packageName} (${entryPath}): ${e?.message ?? e}`);
|
|
210
|
+
return [];
|
|
211
|
+
}
|
|
212
|
+
const registerSkill =
|
|
213
|
+
mod.registerSkill ?? mod.default?.registerSkill ?? mod.default;
|
|
214
|
+
if (typeof registerSkill !== "function") {
|
|
215
|
+
warn(`${packageName}: no registerSkill export — skipping discovery`);
|
|
216
|
+
return [];
|
|
217
|
+
}
|
|
218
|
+
const { tools, api } = createSpyApi();
|
|
219
|
+
const ctx = createStubContext();
|
|
220
|
+
// Provide a config skeleton that matches AgenticROSConfig defaults loosely
|
|
221
|
+
// enough that registration doesn't crash on access paths like config.skills.x.
|
|
222
|
+
const stubConfig = {
|
|
223
|
+
transport: { mode: "rosbridge" },
|
|
224
|
+
robot: { name: "Robot", namespace: "", cameraTopic: "" },
|
|
225
|
+
teleop: { cmdVelTopic: "", cameraTopic: "", speedDefault: 0.3, cameraPollMs: 150 },
|
|
226
|
+
safety: { maxLinearVelocity: 1, maxAngularVelocity: 1.5 },
|
|
227
|
+
skills: {},
|
|
228
|
+
skillPaths: [],
|
|
229
|
+
skillPackages: [],
|
|
230
|
+
};
|
|
231
|
+
try {
|
|
232
|
+
await Promise.resolve(registerSkill(api, stubConfig, ctx));
|
|
233
|
+
} catch (e) {
|
|
234
|
+
warn(
|
|
235
|
+
`${packageName} registerSkill threw during discovery — captured ${tools.length} tools before error: ${e?.message ?? e}`,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
return tools;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function uniqueOrdered(...lists) {
|
|
242
|
+
const seen = new Set();
|
|
243
|
+
const out = [];
|
|
244
|
+
for (const list of lists) {
|
|
245
|
+
for (const name of list) {
|
|
246
|
+
if (typeof name !== "string") continue;
|
|
247
|
+
const trimmed = name.trim();
|
|
248
|
+
if (!trimmed || seen.has(trimmed)) continue;
|
|
249
|
+
seen.add(trimmed);
|
|
250
|
+
out.push(trimmed);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function arraysEqual(a, b) {
|
|
257
|
+
if (a.length !== b.length) return false;
|
|
258
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async function main() {
|
|
263
|
+
if (!existsSync(MANIFEST_PATH)) fail(`Manifest not found: ${MANIFEST_PATH}`);
|
|
264
|
+
const manifestRaw = readFileSync(MANIFEST_PATH, "utf8");
|
|
265
|
+
let manifest;
|
|
266
|
+
try {
|
|
267
|
+
manifest = JSON.parse(manifestRaw);
|
|
268
|
+
} catch (e) {
|
|
269
|
+
fail(`Cannot parse manifest: ${e?.message ?? e}`);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const cfg = readOpenClawConfig();
|
|
273
|
+
const { skillPaths, skillPackages } = cfg ? getSkillEntries(cfg) : { skillPaths: [], skillPackages: [] };
|
|
274
|
+
|
|
275
|
+
log(`Resolved OpenClaw config: ${getOpenClawConfigPath()}`);
|
|
276
|
+
log(`skillPaths: ${skillPaths.length === 0 ? "(none)" : skillPaths.join(", ")}`);
|
|
277
|
+
log(`skillPackages: ${skillPackages.length === 0 ? "(none)" : skillPackages.join(", ")}`);
|
|
278
|
+
|
|
279
|
+
const discovered = new Map(); // skillId/packageName -> tools[]
|
|
280
|
+
|
|
281
|
+
for (const pkg of skillPackages) {
|
|
282
|
+
const entry = resolvePackageEntry(pkg);
|
|
283
|
+
if (!entry) continue;
|
|
284
|
+
vlog(`Resolving package "${pkg}" → ${entry}`);
|
|
285
|
+
const tools = await discoverSkillTools(entry, pkg);
|
|
286
|
+
if (tools.length > 0) discovered.set(pkg, tools);
|
|
287
|
+
else vlog(` no tools discovered for ${pkg}`);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
for (const dir of skillPaths) {
|
|
291
|
+
const absDir = isAbsolute(dir) ? dir : resolve(REPO_ROOT, dir);
|
|
292
|
+
const resolved = findSkillEntryFromPath(absDir);
|
|
293
|
+
if (!resolved) continue;
|
|
294
|
+
vlog(`Resolving path "${absDir}" → ${resolved.entry} (${resolved.packageName})`);
|
|
295
|
+
const tools = await discoverSkillTools(resolved.entry, resolved.packageName);
|
|
296
|
+
if (tools.length > 0) discovered.set(resolved.packageName, tools);
|
|
297
|
+
else vlog(` no tools discovered for ${resolved.packageName}`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (discovered.size === 0) {
|
|
301
|
+
log("No skill tools discovered. contracts.tools will contain only core tools.");
|
|
302
|
+
} else {
|
|
303
|
+
for (const [name, tools] of discovered.entries()) {
|
|
304
|
+
log(`Discovered ${tools.length} tool(s) from ${name}: ${tools.join(", ")}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const skillTools = [...discovered.values()].flat();
|
|
309
|
+
const merged = uniqueOrdered(CORE_TOOLS, skillTools);
|
|
310
|
+
const previous = Array.isArray(manifest?.contracts?.tools)
|
|
311
|
+
? manifest.contracts.tools.slice()
|
|
312
|
+
: [];
|
|
313
|
+
|
|
314
|
+
if (arraysEqual(previous, merged)) {
|
|
315
|
+
log("Manifest is already up to date.");
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
log(`Updating contracts.tools:\n before: [${previous.join(", ")}]\n after: [${merged.join(", ")}]`);
|
|
320
|
+
|
|
321
|
+
if (DRY_RUN) {
|
|
322
|
+
log("Dry run — manifest not modified.");
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
manifest.contracts = manifest.contracts ?? {};
|
|
327
|
+
manifest.contracts.tools = merged;
|
|
328
|
+
writeFileSync(MANIFEST_PATH, JSON.stringify(manifest, null, 2) + "\n", "utf8");
|
|
329
|
+
log(`Wrote ${MANIFEST_PATH}`);
|
|
330
|
+
log("Next steps:");
|
|
331
|
+
log(" 1. openclaw plugins registry --refresh");
|
|
332
|
+
log(" 2. Restart the OpenClaw gateway so the new contracts take effect.");
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
main().catch((e) => fail(e?.stack ?? String(e)));
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env npx tsx
|
|
2
|
+
/**
|
|
3
|
+
* Validation prototype for rclnodejs ESM integration.
|
|
4
|
+
*
|
|
5
|
+
* Run with ROS2 workspace sourced:
|
|
6
|
+
* npx tsx scripts/test-rclnodejs.mts
|
|
7
|
+
*
|
|
8
|
+
* Tests:
|
|
9
|
+
* 1. ESM import of rclnodejs
|
|
10
|
+
* 2. init() + createNode() + spin()
|
|
11
|
+
* 3. Topic/service introspection
|
|
12
|
+
* 4. Message type loading
|
|
13
|
+
* 5. Message construction and extraction
|
|
14
|
+
* 6. Clean shutdown
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { createRequire } from "node:module";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
import { resolve, dirname } from "node:path";
|
|
20
|
+
|
|
21
|
+
// Resolve from the plugin directory where rclnodejs is actually installed
|
|
22
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const pluginDir = resolve(__dirname, "../extensions/openclaw-plugin");
|
|
24
|
+
const pluginRequire = createRequire(resolve(pluginDir, "package.json"));
|
|
25
|
+
|
|
26
|
+
// --- Test 1: ESM import ---
|
|
27
|
+
console.log("=== Test 1: ESM import of rclnodejs ===");
|
|
28
|
+
|
|
29
|
+
let rclnodejs: any;
|
|
30
|
+
try {
|
|
31
|
+
rclnodejs = await import("rclnodejs");
|
|
32
|
+
console.log(" ✓ Direct ESM import succeeded");
|
|
33
|
+
} catch {
|
|
34
|
+
console.log(" ⚠ Direct ESM import failed, trying createRequire fallback...");
|
|
35
|
+
rclnodejs = pluginRequire("rclnodejs");
|
|
36
|
+
console.log(" ✓ createRequire fallback succeeded (resolved from plugin node_modules)");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// --- Test 2: init + createNode + spin ---
|
|
40
|
+
console.log("\n=== Test 2: init + createNode + spin ===");
|
|
41
|
+
|
|
42
|
+
await rclnodejs.init();
|
|
43
|
+
console.log(" ✓ rclnodejs.init() succeeded");
|
|
44
|
+
|
|
45
|
+
const node = rclnodejs.createNode("agenticros_test");
|
|
46
|
+
console.log(" ✓ createNode('agenticros_test') succeeded");
|
|
47
|
+
|
|
48
|
+
rclnodejs.spin(node);
|
|
49
|
+
console.log(" ✓ spin(node) started (non-blocking)");
|
|
50
|
+
|
|
51
|
+
// --- Test 3: Introspection ---
|
|
52
|
+
console.log("\n=== Test 3: Topic/service introspection ===");
|
|
53
|
+
|
|
54
|
+
const topics = node.getTopicNamesAndTypes();
|
|
55
|
+
console.log(` ✓ getTopicNamesAndTypes() returned ${topics.length} topic(s):`);
|
|
56
|
+
for (const t of topics.slice(0, 10)) {
|
|
57
|
+
const name = typeof t === "object" && "name" in t ? (t as { name: string }).name : String(t);
|
|
58
|
+
const types =
|
|
59
|
+
typeof t === "object" && "types" in t ? (t as { types: string[] }).types : [];
|
|
60
|
+
console.log(` - ${name} [${types.join(", ")}]`);
|
|
61
|
+
}
|
|
62
|
+
if (topics.length > 10) console.log(` ... and ${topics.length - 10} more`);
|
|
63
|
+
|
|
64
|
+
const services = node.getServiceNamesAndTypes();
|
|
65
|
+
console.log(` ✓ getServiceNamesAndTypes() returned ${services.length} service(s):`);
|
|
66
|
+
for (const s of services.slice(0, 10)) {
|
|
67
|
+
const name = typeof s === "object" && "name" in s ? (s as { name: string }).name : String(s);
|
|
68
|
+
const types =
|
|
69
|
+
typeof s === "object" && "types" in s ? (s as { types: string[] }).types : [];
|
|
70
|
+
console.log(` - ${name} [${types.join(", ")}]`);
|
|
71
|
+
}
|
|
72
|
+
if (services.length > 10) console.log(` ... and ${services.length - 10} more`);
|
|
73
|
+
|
|
74
|
+
// --- Test 4: Message type loading ---
|
|
75
|
+
console.log("\n=== Test 4: Message type loading ===");
|
|
76
|
+
|
|
77
|
+
let TwistClass: any;
|
|
78
|
+
try {
|
|
79
|
+
TwistClass = rclnodejs.require("geometry_msgs/msg/Twist");
|
|
80
|
+
console.log(" ✓ rclnodejs.require('geometry_msgs/msg/Twist') succeeded");
|
|
81
|
+
console.log(` Type: ${typeof TwistClass}`);
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.log(` ✗ Failed to load Twist: ${e}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// --- Test 5: Message construction and extraction ---
|
|
87
|
+
console.log("\n=== Test 5: Message construction & extraction ===");
|
|
88
|
+
|
|
89
|
+
if (TwistClass) {
|
|
90
|
+
try {
|
|
91
|
+
const msg = new TwistClass();
|
|
92
|
+
msg.linear.x = 1.0;
|
|
93
|
+
msg.linear.y = 0.0;
|
|
94
|
+
msg.linear.z = 0.0;
|
|
95
|
+
msg.angular.x = 0.0;
|
|
96
|
+
msg.angular.y = 0.0;
|
|
97
|
+
msg.angular.z = 0.5;
|
|
98
|
+
console.log(" ✓ Created Twist message and set fields");
|
|
99
|
+
|
|
100
|
+
// Try toPlainObject if available
|
|
101
|
+
if (typeof msg.toPlainObject === "function") {
|
|
102
|
+
const plain = msg.toPlainObject();
|
|
103
|
+
console.log(" ✓ msg.toPlainObject() succeeded:");
|
|
104
|
+
console.log(` ${JSON.stringify(plain)}`);
|
|
105
|
+
} else {
|
|
106
|
+
console.log(" ⚠ toPlainObject() not available, extracting fields manually:");
|
|
107
|
+
const plain = {
|
|
108
|
+
linear: { x: msg.linear.x, y: msg.linear.y, z: msg.linear.z },
|
|
109
|
+
angular: { x: msg.angular.x, y: msg.angular.y, z: msg.angular.z },
|
|
110
|
+
};
|
|
111
|
+
console.log(` ${JSON.stringify(plain)}`);
|
|
112
|
+
}
|
|
113
|
+
} catch (e) {
|
|
114
|
+
console.log(` ✗ Message construction failed: ${e}`);
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
console.log(" ⚠ Skipped — Twist class not loaded");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// --- Test 6: Clean shutdown ---
|
|
121
|
+
console.log("\n=== Test 6: Clean shutdown ===");
|
|
122
|
+
|
|
123
|
+
node.destroy();
|
|
124
|
+
console.log(" ✓ node.destroy() succeeded");
|
|
125
|
+
|
|
126
|
+
rclnodejs.shutdown();
|
|
127
|
+
console.log(" ✓ rclnodejs.shutdown() succeeded");
|
|
128
|
+
|
|
129
|
+
console.log("\n=== All tests passed ===");
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Install OpenClaw 2026.2.26 so plugin HTTP routes (config, teleop) and web chat load.
|
|
3
|
+
# Use this when 2026.3.2 rejects every plugin route with "missing or invalid auth" and
|
|
4
|
+
# neither auth.mode=none nor requireAuth: false fix it.
|
|
5
|
+
set -e
|
|
6
|
+
echo ""
|
|
7
|
+
echo " Installing OpenClaw 2026.2.26 (plugin routes work on this version)..."
|
|
8
|
+
echo ""
|
|
9
|
+
npm install -g openclaw@2026.2.26
|
|
10
|
+
echo ""
|
|
11
|
+
echo " Done. Next steps:"
|
|
12
|
+
echo " 1. Restart the gateway: openclaw gateway"
|
|
13
|
+
echo " 2. Open in your browser:"
|
|
14
|
+
echo " AgenticROS: http://127.0.0.1:18789/plugins/agenticros/"
|
|
15
|
+
echo " 3. Web chat: run node scripts/openclaw-dashboard-url.cjs and open the URL it prints"
|
|
16
|
+
echo " (2026.2.26 needs the token in the URL for the web chat to connect)"
|
|
17
|
+
echo ""
|
|
18
|
+
echo " To go back to latest OpenClaw later: npm install -g openclaw@latest"
|
|
19
|
+
echo ""
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Install OpenClaw 2026.3.11 for testing (Gateway/Control UI and auth fixes).
|
|
3
|
+
# Use this branch (test-openclaw-2026.3.11) to try 2026.3.11; roll back by
|
|
4
|
+
# checking out main and running: npm install -g openclaw@latest (or use-openclaw-2026.2.26.sh)
|
|
5
|
+
set -e
|
|
6
|
+
echo ""
|
|
7
|
+
echo " Installing OpenClaw 2026.3.11 (test branch)..."
|
|
8
|
+
echo ""
|
|
9
|
+
npm install -g openclaw@2026.3.11
|
|
10
|
+
echo ""
|
|
11
|
+
echo " Done. Next steps:"
|
|
12
|
+
echo " 1. Restart the gateway: openclaw gateway"
|
|
13
|
+
echo " 2. Open in your browser:"
|
|
14
|
+
echo " AgenticROS: http://127.0.0.1:18789/plugins/agenticros/"
|
|
15
|
+
echo " 3. Web chat: run node scripts/openclaw-dashboard-url.cjs and open the URL it prints"
|
|
16
|
+
echo ""
|
|
17
|
+
echo " To roll back: checkout main and run npm install -g openclaw@latest"
|
|
18
|
+
echo " Or use ./scripts/use-openclaw-2026.2.26.sh to pin to 2026.2.26."
|
|
19
|
+
echo ""
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// CONFIG FOR: zenoh-bridge-ros2dds (standalone) ON THE ROBOT
|
|
2
|
+
// DO NOT use this file with zenohd. zenohd does not load the ros2dds plugin and will
|
|
3
|
+
// panic on unknown keys (e.g. "allow"). On the Mac, run zenohd with zenohd-agenticros.json5 only.
|
|
4
|
+
//
|
|
5
|
+
// On the robot, run: zenoh-bridge-ros2dds -c /path/to/zenoh-bridge-ros2dds-robot.json5
|
|
6
|
+
// Edit connect.endpoints: use your Mac's actual IP (e.g. 192.168.0.241). Must match the
|
|
7
|
+
// subnet the robot can reach (robot 192.168.0.x → use Mac 192.168.0.x; wrong subnet = connection timeout).
|
|
8
|
+
// Subscriber patterns must match the Zenoh key AgenticROS publishes (topic without leading slash).
|
|
9
|
+
// If you use robot.namespace = "robot3946b404-c33e-4aa3-9a8d-16deb1c5c593", key is "robot3946b404-c33e-4aa3-9a8d-16deb1c5c593/cmd_vel" (ROS2 topic /robot3946.../cmd_vel).
|
|
10
|
+
// If you use robot.namespace = "3946b404-c33e-4aa3-9a8d-16deb1c5c593", key is "3946b404-c33e-4aa3-9a8d-16deb1c5c593/cmd_vel".
|
|
11
|
+
// If you use robot.namespace = "", key is "cmd_vel" (ROS2 /cmd_vel).
|
|
12
|
+
|
|
13
|
+
{
|
|
14
|
+
"mode": "client",
|
|
15
|
+
"connect": {
|
|
16
|
+
"endpoints": ["tcp/192.168.0.241:7447"]
|
|
17
|
+
},
|
|
18
|
+
"plugins": {
|
|
19
|
+
"ros2dds": {
|
|
20
|
+
"allow": {
|
|
21
|
+
"publishers": [".+"],
|
|
22
|
+
"subscribers": [".+/cmd_vel", "cmd_vel", "3946b404-c33e-4aa3-9a8d-16deb1c5c593/cmd_vel", "robot3946b404-c33e-4aa3-9a8d-16deb1c5c593/cmd_vel"],
|
|
23
|
+
"service_servers": [],
|
|
24
|
+
"service_clients": [],
|
|
25
|
+
"action_servers": [],
|
|
26
|
+
"action_clients": []
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationMap": true,
|
|
14
|
+
"sourceMap": true,
|
|
15
|
+
"outDir": "./dist",
|
|
16
|
+
"rootDir": "./src"
|
|
17
|
+
},
|
|
18
|
+
"exclude": ["node_modules", "dist"]
|
|
19
|
+
}
|