These are real excerpts from a tutorial series generated with this skill for the
RosClaw project (a TypeScript plugin that controls ROS2 robots via chat). They show
the two genres in their finished form. Source repo: https://github.com/PlaiPin/rosclaw
(the series lives under learn/code/).
A few hops from the "journey of one command" doc. Note the
file · function · linetags, the plain-language + analogy, and the forward links to deep-dives.
After the safety check passes, the
ros2_publishtool'sexecuteruns. Its job is surprisingly small — read params, get the transport, send.📍
src/tools/ros2-publish.ts·execute()· lines 24–37async execute(_toolCallId, params) { const topic = params["topic"] as string; // pull the three params const message = params["message"] as Record<string, unknown>; const transport = getTransport(); // grab the shared connection transport.publish({ topic, type, msg: message }); // publish! }
- The tool is a thin layer: it doesn't care whether the transport underneath is WebSocket or WebRTC — it just hands the request to
transport. That's the payoff of the layered design (Station 6).- 🔍 Deep-dive: doc 15 · ros2-publish.ts
# File Function Lines One line Deep-dive 4 tools/ros2-publish.tsexecute()24–37 read params → transport.publish15 5 service.tsgetTransport()18–23 return the one shared connection 12 6 transport/rosbridge/adapter.tspublish()55–58 hand off to TopicPublisher10
The opening of a per-file deep-dive — locator block, then a chunk with a syntax mini-lesson the first time
importappears.
Source file: src/tools/ros2-publish.ts
File 15 in the order — the first real tool. The previous doc covered the generic tool skeleton; here we fill it in with the simplest tool ("publish a message to a topic"). It's the entry point for "send a command to the robot."
import { Type } from "@sinclair/typebox"; import type { OpenClawPluginApi } from "../plugin-api.js"; import { getTransport } from "../service.js";
import { Type } from "@sinclair/typebox";— a value import of TypeBox'sType, an object with methods (Type.Object,Type.String, …) used to describe parameter shapes.「Syntax mini-lesson」:
import { X } from "Y"This pulls the named thingXout of moduleYso this file can use it. Curly braces mean a named import (the module deliberately exposesX). Without braces it'd be a default import. We'll meetimport type { … }next — same idea, but thetypekeyword says "only for type-checking; erased at runtime."
- This file registers one AI tool,
ros2_publish, that forwards a message to the transport layer.
import { X } from "Y"— named import (first taught here)import type { X }— type-only import (recall doc 01)
The full RosClaw series is 33 docs (one flow main-line + 32 per-file deep-dives) plus a 5-chapter intro, all in Chinese for "a beginner's beginner." This skill captures that exact workflow so you can reproduce it for any codebase.