[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6FQM223D52SNVV361Z6G1XA":3,"skill-same:01M6FQM223D52SNVV361Z6G1XA":82},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":49,"ownerHtmlUrl":50,"ownerBlogUrl":51,"ownerDescription":52,"updatedAt":53,"install":54,"resources":67},"01M6FQM223D52SNVV361Z6G1XA","three-live-authoring",null,"Builds interactive 3D viewers, procedural Three.js scenes, AR product configurators, and 6DoF WebXR, Android XR, and iOS\u002FvisionOS spatial computing apps using \u003Cthree-live> and \u003Cxr-live>. Use when creating or editing \u003Cthree-live> or \u003Cxr-live> HTML elements, writing \u003Cscript type=\"text\u002Fthree\"> procedural scenes, configuring userData.xr spatial traits or userData.interactivity behavior graphs, building \u003Cdiv slot=\"spatial\"> 3D HTML cards, or integrating native Android (Filament \u002F Jetpack XR SceneCore) and iOS\u002FvisionOS (RealityKit) spatial views.","google\u002Fthree-live","google","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1342004?v=4","01M698VYEFDM0VJBZDYYJ2T83S","Google","01M6FQKY2F8Z0ZCYTZXQDHNZH2",373,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fthree-live\u002Fblob\u002Fmain\u002Fskills\u002Fthree-live-authoring\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"three","authoring","live","three live authoring","html","procedural","product","when","native","ar","text","jetpack","traits","apps","use","scenes","writing","editing","webxr","3D","2026-11-10 10:12:30",false,"---\nname: three-live-authoring\ndescription: >-\n  Builds interactive 3D viewers, procedural Three.js scenes, AR product\n  configurators, and 6DoF WebXR, Android XR, and iOS\u002FvisionOS spatial computing\n  apps using \u003Cthree-live> and \u003Cxr-live>. Use when creating or editing\n  \u003Cthree-live> or \u003Cxr-live> HTML elements, writing \u003Cscript type=\"text\u002Fthree\">\n  procedural scenes, configuring userData.xr spatial traits or\n  userData.interactivity behavior graphs, building \u003Cdiv slot=\"spatial\"> 3D HTML\n  cards, or integrating native Android (Filament \u002F Jetpack XR SceneCore) and\n  iOS\u002FvisionOS (RealityKit) spatial views.\n---\n\n# Authoring 3D & Spatial Apps with `\u003Cthree-live>` and `\u003Cxr-live>`\n\n`\u003Cthree-live>` and `\u003Cxr-live>` compile declarative HTML and sandboxed Three.js scripts (`\u003Cscript type=\"text\u002Fthree\">`) into WebGL2\u002FWebXR on the web, Google Filament & Jetpack XR SceneCore on Android, and Apple RealityKit & Quick Look on iOS\u002FvisionOS.\n\n## 1. Choose the Right Component & Bundle\n\n- **Use `\u003Cthree-live>` (`three-live.min.js` or `three-live-full.min.js`)** when you need:\n    -   A 3D `.glb` \u002F `.usdz` model viewer (`\u003Cmodel-viewer>` drop-in\n        replacement) with built-in `EXT_meshopt_compression` decoding and\n        `KHR_materials_variants` (`variant-name`)\n    -   A procedural Three.js scene (including 2D `Shape`\u002F`ExtrudeGeometry`,\n        3D `SweepGeometry`\u002F`HelixGeometry`\u002F`LoftGeometry` sweeps, coils, and\n        lofted vessels, `THREE.CSG` Booleans, 3D `TextGeometry`, optional a la\n        carte domain kits\n        `THREE.Mechanical`, `THREE.Architecture`, `THREE.Industrial`,\n        `THREE.Science`, and `THREE.Electronics` via `three-live-kits.min.js` or\n        `three-live-kit-\u003Cdomain>.min.js`, and `THREE.InstancedMesh` GPU\n        instancing) with\n        orbit controls and 1-tap mobile AR handoff (`ar`)\n    -   PBR Next materials (clearcoat, transmission, dispersion, iridescence,\n        sheen, volume), 5 filmic\u002Fcommerce tone-mapping modes\n        (`tone-mapping=\"neutral|aces|agx|reinhard|none\"`), HDR emissive `bloom`,\n        silhouette `outline`, `.hdr` environment lighting, ground contact\n        shadows, multi-light depth shadow maps (`shadow-maps=\"auto|pcf|off\"`,\n        `light.castShadow`, `mesh.castShadow`, `mesh.receiveShadow`), loop-free\n        `THREE.TSL` procedural node materials (`three-live-tsl.min.js` \u002F\n        `MeshStandardNodeMaterial` + `el.setMaterialUniform()`), skeletal\n        animations & 2-bone\u002FFABRIK `ik`, or 2D screen-space hotspots\n        (`slot=\"hotspot-*\"`)\n- **Use `\u003Cxr-live>` (`xr-live-full.min.js`)** when you need:\n    - 6DoF WebXR (`xr-mode=\"ar\"` \u002F `\"vr\"` \u002F `\"auto\"`) or desktop 6DoF simulation (`xr-simulator=\"living-room\"`)\n    -   Declarative spatial manipulation traits (`grab`, `scale`, `billboard`,\n        `follow`, `anchor`, `physics`, `orbit`, `handles`, `dimensions`,\n        `snapTo`, `snapSocket`, `gaze`, `explode`, `navigable`, `sync`, `bloom`,\n        `outline`, `ik`, `text`, `splat`, `audioEmitter`)\n    - True 3D raycastable HTML\u002FCSS spatial cards (`\u003Cdiv slot=\"spatial\">`)\n    -   Real-world depth occlusion & heightfield physics\n        (`xr-depth=\"occlusion-physics\"`), 25-joint hand gesture recognition\n        (`xr-hands=\"gestures\"`), spatial 3D painting (`spatial-paint`),\n        depth-colliding particles (`particles`), 3D Gaussian Splats with 3D\n        covariance & SH degree 1–3 (`splatUrl` \u002F `splat`), world plane\u002Freticle\n        understanding (`world-understanding`), multimodal Gemini Live\n        (`connectGeminiLive()` \u002F `holdToAsk`), 3D CAD dimension callouts & tape\n        measure (`spatial-measure`), magnetic socket\u002Fgrid snapping\n        (`magnetic-snap`), hands-free eye\u002Fhead gaze dwell (`gaze-dwell`),\n        multi-part exploded views & section clipping (`explode` \u002F\n        `section-plane`), `#xr-state` & `XRAnchor` persistence\n        (`persistent-anchors`), parabolic XR locomotion (`locomotion`), or\n        multi-user co-presence & WebRTC voice signaling (`shared-room` +\n        `shared-room-voice`; your app owns the `RTCPeerConnection`).\n-   **Add `xr-live-sim.min.js` (included in `xr-live-full.min.js`)** when the\n    scene is an interactive simulation: a game, training drill, or safety\n    walkthrough with a controllable character (`character`), steering agents\n    (`agent`), integrity and hits (`integrity`, `hit-zones`), trigger zones\n    (`zone`), spawners (`spawner`), objectives and scoring (`objective`,\n    `scenario-timer`, `target-score`, `attempts`), or procedural audio cues\n    (`audioCues`, `synth-audio`). Use neutral names: `integrity` (not health),\n    `group` (not team).\n\n---\n\n## 2. Critical Rules That Prevent Broken Scenes\n\n1. **Include `allow-client-scripts` whenever using inline `\u003Cscript type=\"text\u002Fthree\">` or `executeScript()`:**\n   - `\u003Cthree-live>` and `\u003Cxr-live>` reject inline client scripts unless `allow-client-scripts` is present on the host element.\n   - Server-hosted scripts loaded via `script-src=\"\u002Fpath\u002Fto\u002Fscene.js\"` do not require `allow-client-scripts`.\n2. **Use the pre-defined `THREE` and `scene` globals inside `\u003Cscript type=\"text\u002Fthree\">`:**\n   - Do **not** `import * as THREE from 'three'`, do **not** create a `new THREE.WebGLRenderer()`, and do **not** call `document.body.appendChild(...)` inside `\u003Cscript type=\"text\u002Fthree\">`. The script runs inside an isolated Web Worker (or Rust Boa sandbox) with zero DOM access and populates the global `scene` directly (`scene.add(mesh)`).\n3. **Never use `GLTFLoader` or `TextureLoader` inside `\u003Cscript type=\"text\u002Fthree\">`:**\n   - Network APIs (`fetch`, `XMLHttpRequest`) are revoked inside the procedural sandbox. Load `.glb` assets declaratively via `\u003Cthree-live src=\"model.glb\">` or `\u003Cxr-anchor src=\"model.glb\">`.\n4. **Prefer `mesh.userData.xr = { ... }` over legacy `userData.xrTraits`:**\n   - The structured `userData.xr` object supports all core and extended spatial traits and exports cleanly to `.glb` (`extras.xr` + `ANDROID_xr_scenecore`) and `.usdz` (`customData.xr`).\n5. **Always name interactive meshes (`mesh.name = '...'`):**\n   - `meshclick` events, `selected-mesh`, `userData.xr.orbit.target`, `userData.interactivity` target references, `holdToAsk` prompts, and WebMCP `place_xr_object_at_gaze` all identify nodes by `mesh.name`.\n6.  **Use loop-free `THREE.MeshStandardNodeMaterial` + `THREE.TSL` for\n    procedural shaders (never `ShaderMaterial` or `TSL.Loop`):**\n    -   Load `three-live-tsl.min.js` (or `three-live-full.min.js` \u002F\n        `xr-live-full.min.js`) and assign `colorNode`, `opacityNode`,\n        `emissiveNode`, `roughnessNode`, `metalnessNode`, `normalScaleNode`,\n        `bumpNode`, or `positionNode` using `THREE.TSL` (`uv`, `time`,\n        `positionLocal`, `positionWorld`, `normalLocal`, `normalWorld`,\n        `viewDirection`, `uniform(val, name)`, `fresnel`, `simplexNoise2D\u002F3D`,\n        `voronoi2D`, `checker`, `triplanar`, `hueShift`, `bumpFromHeight`,\n        `remap`). Keep graphs acyclic (`\u003C= 128` nodes, `\u003C= 16` uniforms) and\n        avoid fragment-only ops (`viewDirection`, `fresnel`, `bumpFromHeight`)\n        inside `positionNode` (`TL501`–`TL504`).\n\n---\n\n## 3. Canonical `userData.xr` Trait Quick Reference\n\nAttach `userData.xr` to any `THREE.Mesh` or `THREE.Group` inside `\u003Cscript type=\"text\u002Fthree\">`:\n\nTrait Key                | Accepted Values                                                                                                                                                                                                                                                                                                       | Behavior\n:----------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------\n`grab`                   | `'1-hand' \\| '2-hand' \\| true`                                                                                                                                                                                                                                                                                        | Enables 6DoF pinch \u002F controller trigger grabbing (`true` defaults to `'2-hand'`).\n`scale`                  | `{ min?: number, max?: number } \\| true`                                                                                                                                                                                                                                                                              | Two-hand pinch-to-scale clamped to `[min, max]` (default `0.05`–`5.0`).\n`billboard`              | `'capsule' \\| 'cylindrical' \\| 'spherical' \\| true`                                                                                                                                                                                                                                                                   | Faces the active viewer camera (`'capsule'` \u002F `'cylindrical'` yaw-only; `'spherical'` full 3D).\n`follow`                 | `'head' \\| 'hand-left' \\| 'hand-right'` **or** `{ mode, lazy, distance, deadzoneDeg, stiffness, height, faceUser, snapOnStart }`                                                                                                                                                                                      | String values use eager spring follow; object values activate lazy follow with angular deadzone + critically damped spring.\n`anchor`                 | `'floor' \\| 'wall' \\| 'ceiling' \\| 'table' \\| 'horizontal' \\| 'vertical'` **or** `{ target?, id?, persist? }`                                                                                                                                                                                                         | Snaps node to detected real-world planes or simulated surfaces; `persist: true` saves user-moved transforms across reloads and `#xr-state` URLs.\n`physics` \u002F `rigidBody`  | `'dynamic' \\| 'static' \\| 'kinematic' \\| true` **or** `{ body?, shape?: 'auto' \\| 'box' \\| 'sphere' \\| 'cylinder', mass?, restitution?, friction?, linearDamping?, angularDamping?, gravityScale?, velocity?, angularVelocity?, lockRotation? }`                                                                      | Steps 60 Hz deterministic Sequential Impulse rigid-body physics (gravity, restitution bounce, friction, stacking, sleeping, character push, projectile knockback, and depth heightfield collisions); emits `xrcollision` and `xrsleep`.\n`orbit`                  | `{ target: [x,y,z] \\| 'nodeName', radius, speed, height, phase, faceCenter }`                                                                                                                                                                                                                                         | Orbits around a 3D point or named target mesh at `speed` rad\u002Fs.\n`handles`                | `{ rotateAxis?: 'y' \\| 'none', minScale?: number, maxScale?: number } \\| true`                                                                                                                                                                                                                                        | Spawns 4 top-corner uniform-scale handles and a bottom pedestal yaw-rotation bar; emits `xr-handles-change`.\n`dimensions`             | `{ unit?: 'auto' \\| 'm' \\| 'cm' \\| 'mm' \\| 'in' \\| 'ft-in', axes?: Array\u003C'x' \\| 'y' \\| 'z'>, color?: string, showOnSelect?: boolean } \\| true`                                                                                                                                                                        | Renders live `W × H × D` bounding-box dimension guide bars and 3D vector-glyph labels (`spatial-measure`).\n`snapTo`                 | `{ grid?: number \\| [x,y,z], angleDeg?: number, surface?: 'none' \\| 'floor' \\| 'wall' \\| 'ceiling' \\| 'any', socketTag?: string, radius?: number } \\| true`                                                                                                                                                           | Snaps grabbed meshes to matching `snapSocket` anchors (`1.25×` breakaway hysteresis), grids, surfaces, and yaw angles (`magnetic-snap`).\n`snapSocket`             | `string` **or** `{ tag: string, radius?: number, alignRotation?: boolean, highlightColor?: string }`                                                                                                                                                                                                                  | Marks a node as a magnetic snap target socket with a pulsing proximity ring (`magnetic-snap`).\n`gaze`                   | `{ dwellMs?: number, action?: 'select' \\| 'ask', repeat?: boolean } \\| true`                                                                                                                                                                                                                                          | Opts mesh into hands-free eye\u002Fhead gaze dwell (`250..10000ms`, default `1200ms`), routing to `meshclick` or `gemini-live` (`gaze-dwell`).\n`explode`                | `{ direction?: [x,y,z], distance?: number, layer?: number, leaderLine?: boolean } \\| boolean`                                                                                                                                                                                                                         | Configures per-part explosion vector, distance, staggered `layer` (`1..10`), and dashed leader lines (`exploded-view`); `false` pins base parts.\n`navigable`              | `boolean \\| 'walkable' \\| 'blocked'`                                                                                                                                                                                                                                                                                  | Marks floor\u002Fdeck meshes as valid (`'walkable'`) or blocked landing surfaces for parabolic XR teleportation (`spatial-locomotion`).\n`sync`                   | `boolean`                                                                                                                                                                                                                                                                                                             | Controls whether user manipulations sync across peers in `shared-room` (defaults to `true` on grabbable nodes).\n`particles`              | `{ preset: 'rain' \\| 'snow' \\| 'sparks' \\| 'confetti', count?: number, area?: [x,y,z], speed?: number }`                                                                                                                                                                                                              | Emits up to `2,000` depth-colliding particles inside `area`.\n`holdToAsk`              | `{ prompt?: string, holdMs?: number } \\| true`                                                                                                                                                                                                                                                                        | Press-and-hold on the mesh starts speech recognition and queries Gemini Live; emits `xr-hold-to-ask`.\n`worldUnderstanding`     | `{ planes?: boolean, meshes?: boolean, reticle?: boolean, objects?: boolean }`                                                                                                                                                                                                                                        | Enables WebXR plane\u002Fmesh detection and gaze surface reticle (`__xr_reticle__`).\n`splatUrl`               | `'https:\u002F\u002F...\u002Fscene.splat'` or `'.spz'`                                                                                                                                                                                                                                                                               | Streams and depth-sorts 3D Gaussian Splats (`.splat` or Niantic `.spz` v2\u002Fv3 with 3D covariance + SH degree 1–3).\n`splat`                  | `{ url: string, shDegree?: 0 \\| 1 \\| 2 \\| 3, maxSplats?: number }`                                                                                                                                                                                                                                                    | Structured 3D Gaussian Splat trait controlling Spherical Harmonics degree (`0..3`) and splat cap.\n`bloom`                  | `{ strength?: number, threshold?: number, radius?: number } \\| boolean \\| number`                                                                                                                                                                                                                                     | Enables HDR emissive bloom on the scene\u002Fnode (`strength` in `[0, 5]`, `threshold` in `[0, 2]`, `radius` in `[0, 1]`).\n`outline`                | `{ color?: string, thickness?: number } \\| boolean \\| string`                                                                                                                                                                                                                                                         | Renders an inverted-hull or screen-space silhouette outline (`thickness` in `[0.002, 0.25]`) around the node.\n`ik`                     | `{ root: string, mid?: string, effector: string, target: string \\| [x, y, z], pole?: string \\| [x, y, z], solver?: 'two-bone' \\| 'fabrik', iterations?: number, tolerance?: number, weight?: number }`                                                                                                                | Solves analytical 2-bone (`root` → `mid` → `effector`) or FABRIK inverse kinematics toward `target` (and optional `pole`, alias `poleTarget`).\n`lod`                    | `boolean \\| number[] \\| { distances?: number[], ratios?: number[], levels?: Array\u003C{ distance: number, ratio?: number, node?: string }>, cullDistance?: number, hysteresis?: number }`                                                                                                                                 | Distance-based Level-of-Detail switching with hysteresis, far-distance culling, and automatic vertex-clustering decimation (also `new THREE.LOD()`).\n`text`                   | `{ text: string, size?: number, depth?: number, bevelEnabled?: boolean, bevelThickness?: number, bevelSize?: number }`                                                                                                                                                                                                | Extruded 3D vector text metadata exported to glTF `extras.xr.text` and USDZ `customData.xr`.\n`audioEmitter` \u002F `audio` | `'hum' \\| 'reactor' \\| 'wind' \\| 'beacon' \\| 'geiger' \\| 'chimeLoop' \\| 'machinery' \\| 'water'` or `'https:\u002F\u002F...\u002Fsound.mp3'` or `{ preset?, src?, volume?, loop?, autoplay?, playOnSelect?, distanceModel?, refDistance?, maxDistance?, rolloffFactor?, coneInnerAngle?, coneOuterAngle?, coneOuterGain?, pitchHz? }` | Attaches a 3D positional and directional spatial audio emitter (`spatial-audio`), exporting `KHR_audio_emitter` and USDZ `SpatialAudio`.\n`character`              | `true \\| 'third-person' \\| 'first-person' \\| 'top-down' \\| 'fixed'` **or** `{ speed, jumpVelocity, radius, height, cameraMode, clips }`                                                                                                                                                                               | (`xr-live-sim`) Keyboard, gamepad, or touch-joystick character that slides along `collidable` nodes.\n`agent`                  | `'patrol' \\| 'chase' \\| 'flee' \\| 'follow' \\| 'wander'` **or** `{ mode, target, speed, sightRadius, waypoints }`                                                                                                                                                                                                      | (`xr-live-sim`) Steering agent; `target: 'user'` means the character, else the viewer.\n`integrity`              | `number` **or** `{ max, group, showBar, scoreValue, contactAmount, hideOnDepleted }`                                                                                                                                                                                                                                  | (`xr-live-sim`) Takes hits from other groups; emits `xrhit` and `xrdepleted`.\n`zone`                   | `'box' \\| 'sphere'` **or** `{ shape, size, radius, watchGroups, color }`                                                                                                                                                                                                                                              | (`xr-live-sim`) Emits `xrzoneenter` \u002F `xrzoneexit` for characters, agents, and integrity nodes.\n`spawner`                | `'TemplateName'` **or** `{ template, intervalSec, maxActive, totalCount, spawnRadius }`                                                                                                                                                                                                                               | (`xr-live-sim`) Clones a hidden template node; emits `xrspawn`.\n`objective`              | `'pickup' \\| 'checkpoint' \\| 'key' \\| 'time-bonus' \\| 'restore'` **or** `{ type, amount, order, required, radius, respawnSec }`                                                                                                                                                                                       | (`xr-live-sim`) Completed by proximity to the character, or by tap without one; `order > 0` enforces sequence.\n`audioCues`              | `{ onTap?, onObjective?, onHit?, onDepleted?, onZoneEnter?, onZoneExit?, onSpawn?, onJump?, onLand? }` (cue names such as `'confirm'`, `'alarm'`)                                                                                                                                                                     | (`xr-live-sim`) Procedural cues with `synth-audio`; separate from the file-based `audio` trait.\n`collidable`             | `true`                                                                                                                                                                                                                                                                                                                | (`xr-live-sim`) Wall or floor for characters and agents.\n`pointerEvents`          | `'none'`                                                                                                                                                                                                                                                                                                              | Excludes the mesh from raycast picking so rays pass through to objects behind it.\n\n---\n\n## 4. Progressive Disclosure References\n\nRead these reference files when you need detailed schemas, copy-pasteable recipes, or debugging steps:\n\n-   **[`references\u002Fxr-traits-and-plugins.md`](references\u002Fxr-traits-and-plugins.md)**:\n    Complete attribute tables, clamping ranges, DOM events,\n    `userData.interactivity` (`KHR_interactivity`) actions, all 15 spatial\n    plugin controllers, the 6 `xr-live-sim` simulation plugins, Gemini Live API,\n    and WebMCP tool schemas.\n-   **[`references\u002Frecipes.md`](references\u002Frecipes.md)**: 10 production-ready,\n    copy-pasteable code templates (E-commerce configurator, Physics ballpit &\n    spatial HTML UI, manipulation handles & lazy HUD, Gemini Live + World\n    Understanding, Spatial Paint + Particles + Gaussian Splats, Native\n    Android\u002FiOS integration, CAD Exploded View + Measure + Gaze Dwell, Magnetic\n    Snapping + Persistent `#xr-state` + Locomotion, Multi-User `shared-room`\n    Co-Presence, and an `xr-live-sim` training drill).\n-   **[`references\u002Fdebugging-and-csp.md`](references\u002Fdebugging-and-csp.md)**:\n    Diagnosing blank scenes, inspecting `THREE.getAuthorWarnings()`, running\n    closed-loop `three-live-cli validate --json` \u002F `render --view=quad` \u002F\n    `sim --json` checks (`TL100–TL402`), configuring Worker\u002Fiframe sandboxes &\n    `connect-src wss:` under strict CSP \u002F Trusted Types, and verifying bundle\n    budgets.\n\n--------------------------------------------------------------------------------\n\n## 5. Closed-Loop CLI Verification (`three-live-cli`)\n\nAlways verify authored `.js`, `.html`, or `.glb` scenes headlessly using\n`three-live-cli`:\n\n1.  **Validate & Spatial Lint:** `three-live-cli validate scene.js --json` — fix\n    all `TL100–TL402` errors and spatial warnings (`inFrustum`,\n    `screenCoveragePct`, `grounded`, broken target references) before rendering.\n2.  **Render 4-Up Quad Contact Sheet:** `three-live-cli render scene.js -o\n    preview.png --view=quad --grid --annotations` — inspect perspective camera\n    framing (`CAMERA`), front\u002Fright elevation (`FRONT`, `RIGHT`), and top-down\n    layout (`TOP`) with `1 m` gridlines and AABB labels.\n3.  **Match a Reference (when given a photo, mockup, sketch, or blueprint):**\n    `three-live-cli render scene.js -o compare.png --reference=ref.jpg\n    --view=camera` (or `--view=front|right|top` for blueprints) — iterate until\n    `silhouetteIou >= 0.85` and `|aspectError| \u003C 0.05` when `silhouetteReliable`\n    is true, otherwise compare the aligned OVERLAY panel.\n4.  **Simulate Interactivity & Temporal Motion:** `three-live-cli render\n    scene.js -o anim.png --frames=4 --duration=2.0 --trigger-select=\u003Cnode>` or\n    `three-live-cli sim scene.js --duration=5.0 --actions='[...]' --json`. For\n    games, play the level closed-loop with\n    `three-live-cli gym reset scene.js --session ep.json` and\n    `three-live-cli gym step --session ep.json --actions='[...]'` (or the\n    `three_live_gym_*` MCP tools) to check it is winnable.\n","# Authoring 3D & Spatial Apps with `\u003Cthree-live>` and `\u003Cxr-live>`\n\n`\u003Cthree-live>` and `\u003Cxr-live>` compile declarative HTML and sandboxed Three.js scripts (`\u003Cscript type=\"text\u002Fthree\">`) into WebGL2\u002FWebXR on the web, Google Filament & Jetpack XR SceneCore on Android, and Apple RealityKit & Quick Look on iOS\u002FvisionOS.\n\n## 1. Choose the Right Component & Bundle\n\n- **Use `\u003Cthree-live>` (`three-live.min.js` or `three-live-full.min.js`)** when you need:\n    -   A 3D `.glb` \u002F `.usdz` model viewer (`\u003Cmodel-viewer>` drop-in\n        replacement) with built-in `EXT_meshopt_compression` decoding and\n        `KHR_materials_variants` (`variant-name`)\n    -   A procedural Three.js scene (including 2D `Shape`\u002F`ExtrudeGeometry`,\n        3D `SweepGeometry`\u002F`HelixGeometry`\u002F`LoftGeometry` sweeps, coils, and\n        lofted vessels, `THREE.CSG` Booleans, 3D `TextGeometry`, optional a la\n        carte domain kits\n        `THREE.Mechanical`, `THREE.Architecture`, `THREE.Industrial`,\n        `THREE.Science`, and `THREE.Electronics` via `three-live-kits.min.js` or\n        `three-live-kit-\u003Cdomain>.min.js`, and `THREE.InstancedMesh` GPU\n        instancing) with\n        orbit controls and 1-tap mobile AR handoff (`ar`)\n    -   PBR Next materials (clearcoat, transmission, dispersion, iridescence,\n        sheen, volume), 5 filmic\u002Fcommerce tone-mapping modes\n        (`tone-mapping=\"neutral|aces|agx|reinhard|none\"`), HDR emissive `bloom`,\n        silhouette `outline`, `.hdr` environment lighting, ground contact\n        shadows, multi-light depth shadow maps (`shadow-maps=\"auto|pcf|off\"`,\n        `light.castShadow`, `mesh.castShadow`, `mesh.receiveShadow`), loop-free\n        `THREE.TSL` procedural node materials (`three-live-tsl.min.js` \u002F\n        `MeshStandardNodeMaterial` + `el.setMaterialUniform()`), skeletal\n        animations & 2-bone\u002FFABRIK `ik`, or 2D screen-space hotspots\n        (`slot=\"hotspot-*\"`)\n- **Use `\u003Cxr-live>` (`xr-live-full.min.js`)** when you need:\n    - 6DoF WebXR (`xr-mode=\"ar\"` \u002F `\"vr\"` \u002F `\"auto\"`) or desktop 6DoF simulation (`xr-simulator=\"living-room\"`)\n    -   Declarative spatial manipulation traits (`grab`, `scale`, `billboard`,\n        `follow`, `anchor`, `physics`, `orbit`, `handles`, `dimensions`,\n        `snapTo`, `snapSocket`, `gaze`, `explode`, `navigable`, `sync`, `bloom`,\n        `outline`, `ik`, `text`, `splat`, `audioEmitter`)\n    - True 3D raycastable HTML\u002FCSS spatial cards (`\u003Cdiv slot=\"spatial\">`)\n    -   Real-world depth occlusion & heightfield physics\n        (`xr-depth=\"occlusion-physics\"`), 25-joint hand gesture recognition\n        (`xr-hands=\"gestures\"`), spatial 3D painting (`spatial-paint`),\n        depth-colliding particles (`particles`), 3D Gaussian Splats with 3D\n        covariance & SH degree 1–3 (`splatUrl` \u002F `splat`), world plane\u002Freticle\n        understanding (`world-understanding`), multimodal Gemini Live\n        (`connectGeminiLive()` \u002F `holdToAsk`), 3D CAD dimension callouts & tape\n        measure (`spatial-measure`), magnetic socket\u002Fgrid snapping\n        (`magnetic-snap`), hands-free eye\u002Fhead gaze dwell (`gaze-dwell`),\n        multi-part exploded views & section clipping (`explode` \u002F\n        `section-plane`), `#xr-state` & `XRAnchor` persistence\n        (`persistent-anchors`), parabolic XR locomotion (`locomotion`), or\n        multi-user co-presence & WebRTC voice signaling (`shared-room` +\n        `shared-room-voice`; your app owns the `RTCPeerConnection`).\n-   **Add `xr-live-sim.min.js` (included in `xr-live-full.min.js`)** when the\n    scene is an interactive simulation: a game, training drill, or safety\n    walkthrough with a controllable character (`character`), steering agents\n    (`agent`), integrity and hits (`integrity`, `hit-zones`), trigger zones\n    (`zone`), spawners (`spawner`), objectives and scoring (`objective`,\n    `scenario-timer`, `target-score`, `attempts`), or procedural audio cues\n    (`audioCues`, `synth-audio`). Use neutral names: `integrity` (not health),\n    `group` (not team).\n\n---\n\n## 2. Critical Rules That Prevent Broken Scenes\n\n1. **Include `allow-client-scripts` whenever using inline `\u003Cscript type=\"text\u002Fthree\">` or `executeScript()`:**\n   - `\u003Cthree-live>` and `\u003Cxr-live>` reject inline client scripts unless `allow-client-scripts` is present on the host element.\n   - Server-hosted scripts loaded via `script-src=\"\u002Fpath\u002Fto\u002Fscene.js\"` do not require `allow-client-scripts`.\n2. **Use the pre-defined `THREE` and `scene` globals inside `\u003Cscript type=\"text\u002Fthree\">`:**\n   - Do **not** `import * as THREE from 'three'`, do **not** create a `new THREE.WebGLRenderer()`, and do **not** call `document.body.appendChild(...)` inside `\u003Cscript type=\"text\u002Fthree\">`. The script runs inside an isolated Web Worker (or Rust Boa sandbox) with zero DOM access and populates the global `scene` directly (`scene.add(mesh)`).\n3. **Never use `GLTFLoader` or `TextureLoader` inside `\u003Cscript type=\"text\u002Fthree\">`:**\n   - Network APIs (`fetch`, `XMLHttpRequest`) are revoked inside the procedural sandbox. Load `.glb` assets declaratively via `\u003Cthree-live src=\"model.glb\">` or `\u003Cxr-anchor src=\"model.glb\">`.\n4. **Prefer `mesh.userData.xr = { ... }` over legacy `userData.xrTraits`:**\n   - The structured `userData.xr` object supports all core and extended spatial traits and exports cleanly to `.glb` (`extras.xr` + `ANDROID_xr_scenecore`) and `.usdz` (`customData.xr`).\n5. **Always name interactive meshes (`mesh.name = '...'`):**\n   - `meshclick` events, `selected-mesh`, `userData.xr.orbit.target`, `userData.interactivity` target references, `holdToAsk` prompts, and WebMCP `place_xr_object_at_gaze` all identify nodes by `mesh.name`.\n6.  **Use loop-free `THREE.MeshStandardNodeMaterial` + `THREE.TSL` for\n    procedural shaders (never `ShaderMaterial` or `TSL.Loop`):**\n    -   Load `three-live-tsl.min.js` (or `three-live-full.min.js` \u002F\n        `xr-live-full.min.js`) and assign `colorNode`, `opacityNode`,\n        `emissiveNode`, `roughnessNode`, `metalnessNode`, `normalScaleNode`,\n        `bumpNode`, or `positionNode` using `THREE.TSL` (`uv`, `time`,\n        `positionLocal`, `positionWorld`, `normalLocal`, `normalWorld`,\n        `viewDirection`, `uniform(val, name)`, `fresnel`, `simplexNoise2D\u002F3D`,\n        `voronoi2D`, `checker`, `triplanar`, `hueShift`, `bumpFromHeight`,\n        `remap`). Keep graphs acyclic (`\u003C= 128` nodes, `\u003C= 16` uniforms) and\n        avoid fragment-only ops (`viewDirection`, `fresnel`, `bumpFromHeight`)\n        inside `positionNode` (`TL501`–`TL504`).\n\n---\n\n## 3. Canonical `userData.xr` Trait Quick Reference\n\nAttach `userData.xr` to any `THREE.Mesh` or `THREE.Group` inside `\u003Cscript type=\"text\u002Fthree\">`:\n\nTrait Key                | Accepted Values                                                                                                                                                                                                                                                                                                       | Behavior\n:----------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------\n`grab`                   | `'1-hand' \\| '2-hand' \\| true`                                                                                                                                                                                                                                                                                        | Enables 6DoF pinch \u002F controller trigger grabbing (`true` defaults to `'2-hand'`).\n`scale`                  | `{ min?: number, max?: number } \\| true`                                                                                                                                                                                                                                                                              | Two-hand pinch-to-scale clamped to `[min, max]` (default `0.05`–`5.0`).\n`billboard`              | `'capsule' \\| 'cylindrical' \\| 'spherical' \\| true`                                                                                                                                                                                                                                                                   | Faces the active viewer camera (`'capsule'` \u002F `'cylindrical'` yaw-only; `'spherical'` full 3D).\n`follow`                 | `'head' \\| 'hand-left' \\| 'hand-right'` **or** `{ mode, lazy, distance, deadzoneDeg, stiffness, height, faceUser, snapOnStart }`                                                                                                                                                                                      | String values use eager spring follow; object values activate lazy follow with angular deadzone + critically damped spring.\n`anchor`                 | `'floor' \\| 'wall' \\| 'ceiling' \\| 'table' \\| 'horizontal' \\| 'vertical'` **or** `{ target?, id?, persist? }`                                                                                                                                                                                                         | Snaps node to detected real-world planes or simulated surfaces; `persist: true` saves user-moved transforms across reloads and `#xr-state` URLs.\n`physics` \u002F `rigidBody`  | `'dynamic' \\| 'static' \\| 'kinematic' \\| true` **or** `{ body?, shape?: 'auto' \\| 'box' \\| 'sphere' \\| 'cylinder', mass?, restitution?, friction?, linearDamping?, angularDamping?, gravityScale?, velocity?, angularVelocity?, lockRotation? }`                                                                      | Steps 60 Hz deterministic Sequential Impulse rigid-body physics (gravity, restitution bounce, friction, stacking, sleeping, character push, projectile knockback, and depth heightfield collisions); emits `xrcollision` and `xrsleep`.\n`orbit`                  | `{ target: [x,y,z] \\| 'nodeName', radius, speed, height, phase, faceCenter }`                                                                                                                                                                                                                                         | Orbits around a 3D point or named target mesh at `speed` rad\u002Fs.\n`handles`                | `{ rotateAxis?: 'y' \\| 'none', minScale?: number, maxScale?: number } \\| true`                                                                                                                                                                                                                                        | Spawns 4 top-corner uniform-scale handles and a bottom pedestal yaw-rotation bar; emits `xr-handles-change`.\n`dimensions`             | `{ unit?: 'auto' \\| 'm' \\| 'cm' \\| 'mm' \\| 'in' \\| 'ft-in', axes?: Array\u003C'x' \\| 'y' \\| 'z'>, color?: string, showOnSelect?: boolean } \\| true`                                                                                                                                                                        | Renders live `W × H × D` bounding-box dimension guide bars and 3D vector-glyph labels (`spatial-measure`).\n`snapTo`                 | `{ grid?: number \\| [x,y,z], angleDeg?: number, surface?: 'none' \\| 'floor' \\| 'wall' \\| 'ceiling' \\| 'any', socketTag?: string, radius?: number } \\| true`                                                                                                                                                           | Snaps grabbed meshes to matching `snapSocket` anchors (`1.25×` breakaway hysteresis), grids, surfaces, and yaw angles (`magnetic-snap`).\n`snapSocket`             | `string` **or** `{ tag: string, radius?: number, alignRotation?: boolean, highlightColor?: string }`                                                                                                                                                                                                                  | Marks a node as a magnetic snap target socket with a pulsing proximity ring (`magnetic-snap`).\n`gaze`                   | `{ dwellMs?: number, action?: 'select' \\| 'ask', repeat?: boolean } \\| true`                                                                                                                                                                                                                                          | Opts mesh into hands-free eye\u002Fhead gaze dwell (`250..10000ms`, default `1200ms`), routing to `meshclick` or `gemini-live` (`gaze-dwell`).\n`explode`                | `{ direction?: [x,y,z], distance?: number, layer?: number, leaderLine?: boolean } \\| boolean`                                                                                                                                                                                                                         | Configures per-part explosion vector, distance, staggered `layer` (`1..10`), and dashed leader lines (`exploded-view`); `false` pins base parts.\n`navigable`              | `boolean \\| 'walkable' \\| 'blocked'`                                                                                                                                                                                                                                                                                  | Marks floor\u002Fdeck meshes as valid (`'walkable'`) or blocked landing surfaces for parabolic XR teleportation (`spatial-locomotion`).\n`sync`                   | `boolean`                                                                                                                                                                                                                                                                                                             | Controls whether user manipulations sync across peers in `shared-room` (defaults to `true` on grabbable nodes).\n`particles`              | `{ preset: 'rain' \\| 'snow' \\| 'sparks' \\| 'confetti', count?: number, area?: [x,y,z], speed?: number }`                                                                                                                                                                                                              | Emits up to `2,000` depth-colliding particles inside `area`.\n`holdToAsk`              | `{ prompt?: string, holdMs?: number } \\| true`                                                                                                                                                                                                                                                                        | Press-and-hold on the mesh starts speech recognition and queries Gemini Live; emits `xr-hold-to-ask`.\n`worldUnderstanding`     | `{ planes?: boolean, meshes?: boolean, reticle?: boolean, objects?: boolean }`                                                                                                                                                                                                                                        | Enables WebXR plane\u002Fmesh detection and gaze surface reticle (`__xr_reticle__`).\n`splatUrl`               | `'https:\u002F\u002F...\u002Fscene.splat'` or `'.spz'`                                                                                                                                                                                                                                                                               | Streams and depth-sorts 3D Gaussian Splats (`.splat` or Niantic `.spz` v2\u002Fv3 with 3D covariance + SH degree 1–3).\n`splat`                  | `{ url: string, shDegree?: 0 \\| 1 \\| 2 \\| 3, maxSplats?: number }`                                                                                                                                                                                                                                                    | Structured 3D Gaussian Splat trait controlling Spherical Harmonics degree (`0..3`) and splat cap.\n`bloom`                  | `{ strength?: number, threshold?: number, radius?: number } \\| boolean \\| number`                                                                                                                                                                                                                                     | Enables HDR emissive bloom on the scene\u002Fnode (`strength` in `[0, 5]`, `threshold` in `[0, 2]`, `radius` in `[0, 1]`).\n`outline`                | `{ color?: string, thickness?: number } \\| boolean \\| string`                                                                                                                                                                                                                                                         | Renders an inverted-hull or screen-space silhouette outline (`thickness` in `[0.002, 0.25]`) around the node.\n`ik`                     | `{ root: string, mid?: string, effector: string, target: string \\| [x, y, z], pole?: string \\| [x, y, z], solver?: 'two-bone' \\| 'fabrik', iterations?: number, tolerance?: number, weight?: number }`                                                                                                                | Solves analytical 2-bone (`root` → `mid` → `effector`) or FABRIK inverse kinematics toward `target` (and optional `pole`, alias `poleTarget`).\n`lod`                    | `boolean \\| number[] \\| { distances?: number[], ratios?: number[], levels?: Array\u003C{ distance: number, ratio?: number, node?: string }>, cullDistance?: number, hysteresis?: number }`                                                                                                                                 | Distance-based Level-of-Detail switching with hysteresis, far-distance culling, and automatic vertex-clustering decimation (also `new THREE.LOD()`).\n`text`                   | `{ text: string, size?: number, depth?: number, bevelEnabled?: boolean, bevelThickness?: number, bevelSize?: number }`                                                                                                                                                                                                | Extruded 3D vector text metadata exported to glTF `extras.xr.text` and USDZ `customData.xr`.\n`audioEmitter` \u002F `audio` | `'hum' \\| 'reactor' \\| 'wind' \\| 'beacon' \\| 'geiger' \\| 'chimeLoop' \\| 'machinery' \\| 'water'` or `'https:\u002F\u002F...\u002Fsound.mp3'` or `{ preset?, src?, volume?, loop?, autoplay?, playOnSelect?, distanceModel?, refDistance?, maxDistance?, rolloffFactor?, coneInnerAngle?, coneOuterAngle?, coneOuterGain?, pitchHz? }` | Attaches a 3D positional and directional spatial audio emitter (`spatial-audio`), exporting `KHR_audio_emitter` and USDZ `SpatialAudio`.\n`character`              | `true \\| 'third-person' \\| 'first-person' \\| 'top-down' \\| 'fixed'` **or** `{ speed, jumpVelocity, radius, height, cameraMode, clips }`                                                                                                                                                                               | (`xr-live-sim`) Keyboard, gamepad, or touch-joystick character that slides along `collidable` nodes.\n`agent`                  | `'patrol' \\| 'chase' \\| 'flee' \\| 'follow' \\| 'wander'` **or** `{ mode, target, speed, sightRadius, waypoints }`                                                                                                                                                                                                      | (`xr-live-sim`) Steering agent; `target: 'user'` means the character, else the viewer.\n`integrity`              | `number` **or** `{ max, group, showBar, scoreValue, contactAmount, hideOnDepleted }`                                                                                                                                                                                                                                  | (`xr-live-sim`) Takes hits from other groups; emits `xrhit` and `xrdepleted`.\n`zone`                   | `'box' \\| 'sphere'` **or** `{ shape, size, radius, watchGroups, color }`                                                                                                                                                                                                                                              | (`xr-live-sim`) Emits `xrzoneenter` \u002F `xrzoneexit` for characters, agents, and integrity nodes.\n`spawner`                | `'TemplateName'` **or** `{ template, intervalSec, maxActive, totalCount, spawnRadius }`                                                                                                                                                                                                                               | (`xr-live-sim`) Clones a hidden template node; emits `xrspawn`.\n`objective`              | `'pickup' \\| 'checkpoint' \\| 'key' \\| 'time-bonus' \\| 'restore'` **or** `{ type, amount, order, required, radius, respawnSec }`                                                                                                                                                                                       | (`xr-live-sim`) Completed by proximity to the character, or by tap without one; `order > 0` enforces sequence.\n`audioCues`              | `{ onTap?, onObjective?, onHit?, onDepleted?, onZoneEnter?, onZoneExit?, onSpawn?, onJump?, onLand? }` (cue names such as `'confirm'`, `'alarm'`)                                                                                                                                                                     | (`xr-live-sim`) Procedural cues with `synth-audio`; separate from the file-based `audio` trait.\n`collidable`             | `true`                                                                                                                                                                                                                                                                                                                | (`xr-live-sim`) Wall or floor for characters and agents.\n`pointerEvents`          | `'none'`                                                                                                                                                                                                                                                                                                              | Excludes the mesh from raycast picking so rays pass through to objects behind it.\n\n---\n\n## 4. Progressive Disclosure References\n\nRead these reference files when you need detailed schemas, copy-pasteable recipes, or debugging steps:\n\n-   **[`references\u002Fxr-traits-and-plugins.md`](references\u002Fxr-traits-and-plugins.md)**:\n    Complete attribute tables, clamping ranges, DOM events,\n    `userData.interactivity` (`KHR_interactivity`) actions, all 15 spatial\n    plugin controllers, the 6 `xr-live-sim` simulation plugins, Gemini Live API,\n    and WebMCP tool schemas.\n-   **[`references\u002Frecipes.md`](references\u002Frecipes.md)**: 10 production-ready,\n    copy-pasteable code templates (E-commerce configurator, Physics ballpit &\n    spatial HTML UI, manipulation handles & lazy HUD, Gemini Live + World\n    Understanding, Spatial Paint + Particles + Gaussian Splats, Native\n    Android\u002FiOS integration, CAD Exploded View + Measure + Gaze Dwell, Magnetic\n    Snapping + Persistent `#xr-state` + Locomotion, Multi-User `shared-room`\n    Co-Presence, and an `xr-live-sim` training drill).\n-   **[`references\u002Fdebugging-and-csp.md`](references\u002Fdebugging-and-csp.md)**:\n    Diagnosing blank scenes, inspecting `THREE.getAuthorWarnings()`, running\n    closed-loop `three-live-cli validate --json` \u002F `render --view=quad` \u002F\n    `sim --json` checks (`TL100–TL402`), configuring Worker\u002Fiframe sandboxes &\n    `connect-src wss:` under strict CSP \u002F Trusted Types, and verifying bundle\n    budgets.\n\n--------------------------------------------------------------------------------\n\n## 5. Closed-Loop CLI Verification (`three-live-cli`)\n\nAlways verify authored `.js`, `.html`, or `.glb` scenes headlessly using\n`three-live-cli`:\n\n1.  **Validate & Spatial Lint:** `three-live-cli validate scene.js --json` — fix\n    all `TL100–TL402` errors and spatial warnings (`inFrustum`,\n    `screenCoveragePct`, `grounded`, broken target references) before rendering.\n2.  **Render 4-Up Quad Contact Sheet:** `three-live-cli render scene.js -o\n    preview.png --view=quad --grid --annotations` — inspect perspective camera\n    framing (`CAMERA`), front\u002Fright elevation (`FRONT`, `RIGHT`), and top-down\n    layout (`TOP`) with `1 m` gridlines and AABB labels.\n3.  **Match a Reference (when given a photo, mockup, sketch, or blueprint):**\n    `three-live-cli render scene.js -o compare.png --reference=ref.jpg\n    --view=camera` (or `--view=front|right|top` for blueprints) — iterate until\n    `silhouetteIou >= 0.85` and `|aspectError| \u003C 0.05` when `silhouetteReliable`\n    is true, otherwise compare the aligned OVERLAY panel.\n4.  **Simulate Interactivity & Temporal Motion:** `three-live-cli render\n    scene.js -o anim.png --frames=4 --duration=2.0 --trigger-select=\u003Cnode>` or\n    `three-live-cli sim scene.js --duration=5.0 --actions='[...]' --json`. For\n    games, play the level closed-loop with\n    `three-live-cli gym reset scene.js --session ep.json` and\n    `three-live-cli gym step --session ep.json --actions='[...]'` (or the\n    `three_live_gym_*` MCP tools) to check it is winnable.\n",{"name":5,"description":7},"main","c6f7ee2d5c1aefabdde231e27784b0f4f8cfd2ef","skills\u002Fthree-live-authoring",43,"https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fthree-live","https:\u002F\u002Fgoogle.github.io\u002Fthree-live\u002F","https:\u002F\u002Fgithub.com\u002Fgoogle","https:\u002F\u002Fopensource.google\u002F","Google ❤️ Open Source","2026-11-14 00:22:42",{"source":8,"skillName":5,"commands":55,"prompt":65,"zipAvailable":66},[56,59,62],{"tool":57,"command":58},"npx","npx skills add google\u002Fthree-live --skill three-live-authoring",{"tool":60,"command":61},"bunx","bunx skills add google\u002Fthree-live --skill three-live-authoring",{"tool":63,"command":64},"pnpm","pnpm dlx skills add google\u002Fthree-live --skill three-live-authoring","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fthree-live\u002Fblob\u002Fmain\u002Fskills\u002Fthree-live-authoring\u002FSKILL.md",true,[68,74,78],{"path":69,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":72,"sourceHtmlUrl":73},"references\u002Fdebugging-and-csp.md","REFERENCE","参考文档",8910,"https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fthree-live\u002Fblob\u002Fmain\u002Fskills\u002Fthree-live-authoring\u002Freferences\u002Fdebugging-and-csp.md",{"path":75,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":76,"sourceHtmlUrl":77},"references\u002Frecipes.md",20795,"https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fthree-live\u002Fblob\u002Fmain\u002Fskills\u002Fthree-live-authoring\u002Freferences\u002Frecipes.md",{"path":79,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":80,"sourceHtmlUrl":81},"references\u002Fxr-traits-and-plugins.md",26256,"https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fthree-live\u002Fblob\u002Fmain\u002Fskills\u002Fthree-live-authoring\u002Freferences\u002Fxr-traits-and-plugins.md",[83],{"skillNo":84,"name":85,"nameZh":6,"description":86,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":89,"publishedAt":39},"01M6FQM6P3CC2RY9XE1Q9CCA13","xr-live-plugin-dev","Adds or modifies \u003Cthree-live> and \u003Cxr-live> plugins, userData.xr spatial traits, glTF ANDROID_xr_scenecore extensions, USDZ customData.xr metadata, and native Android (Filament \u002F SceneCore) or iOS\u002FvisionOS (RealityKit) runtime features. Use when contributing new capabilities to the three-live monorepo or keeping Web, Rust, Android, and iOS\u002FvisionOS runtimes in parity.","https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fthree-live\u002Fblob\u002Fmain\u002Fskills\u002Fxr-live-plugin-dev\u002FSKILL.md",[],[90,91,92,21,93,94,95,26,96,97,27,98,99,100,101,31,33,102,103,104,19,105],"dev","plugin dev","plugin","xr live plugin dev","usdz","new","extensions","contributing","web","gltf","android","capabilities","rust","runtime","monorepo","runtimes"]