google/xb-add-interactions
>- Generate and implement user interactions for an XR Blocks app. Use when adding scene-wide actions, ray hover or selection, direct hand touch or grab, gestures, dragging, manipulation, or physics-driven object behavior.
npx skills add https://github.com/google/xrblocks --skill xb-add-interactions
Produce a complete interaction design in code: input intent, event
ownership, target geometry, state transitions, feedback, cleanup, and user test
instructions. If the app shell does not run yet, establish it with
xb-build-app first.
For each requested interaction, record:
Keep one row per distinct user intent. A drag and a tap on the same object are
separate actions because their ownership and phases differ.
This step is complete when every requested action has a target, event phases,
state owner, feedback, and user-test path.
Choose the highest-level public API that expresses each action:
Script hooks such as onSelect*,onSqueeze*, and onKey*.
onObjectSelectStart/End and onHover*; enable reticleswhen users need a visible ray target.
options.enableHands() with onObjectTouch* oronObjectGrab*.
options.enableGestures() withxb.core.gestureRecognition events.
options.enableHeadGestures() withxb.input.headGestures events.
xb.core.dragManager andxb.DragMode.
options.physics.RAPIER, initPhysics(), and physicsStep().
Read selection and direct hands,
gesture events, or
manipulation and physics for the
selected branch. Confirm every symbol in
../../src/xrblocks.ts and every hook signature in
../../src/core/Script.ts.
This step is complete when each action maps to one public event family without
reconstructing a higher-level event in update().
Create the code around the action inventory:
xb.Script that owns the application state or containsthe targeted mesh.
mesh when the visible geometry is too thin, irregular, or small to target
comfortably.
idle, hovered, active,held, and disabled—and derive visuals from that state.
then update feedback. Share the domain method when several input sources mean
the same action.
selection, grabbing, dragging, or physics synchronization.
highlight, label, cursor change, or another cue appropriate to the scene.
stable state.
automation, or debugging must identify them.
For direct manipulation, preserve the initial hand-to-object or
controller-to-object offset so the object does not snap on grab. For physics,
keep the rigid body authoritative and synchronize the visual object during
physicsStep().
This step is complete when every inventory row has an owning object, target
geometry, handler, phase state, domain transition, feedback, and release path in
the implementation.
Enable required options before xb.init(options) and implement matching start
and end phases.
true from object-select or hover hooks only when that script consumesthe event and ancestor handling should stop.
do not stop propagation.
a single select input cannot apply it twice.
dispose().selected input may disappear.
This step is complete when paired lifecycle phases, propagation, optional data,
and cleanup are explicit for every interaction branch.
Run code-level checks available in the environment: resolve imports, build or
type-check changed code, load the initial scene, and confirm interactive targets
and affordances initialize without relevant console errors. Inspect that each
inventory row is wired to its intended public callback and state owner.
Give the user one compact card per action:
throwing feel, or haptics.
Finish when the interaction implementation is complete and the user can test
every action without inferring controls, expected feedback, or device-specific
checks from the source.
Take google/xb-add-interactions from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.