summer-engine 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +27 -5
  3. package/.codex-plugin/plugin.json +28 -6
  4. package/.cursor-plugin/plugin.json +27 -5
  5. package/.factory-plugin/plugin.json +27 -5
  6. package/.opencode/plugins/summer.js +1 -1
  7. package/CHANGELOG.md +102 -0
  8. package/README.md +18 -3
  9. package/assets/audit/scene_audit.gd +4136 -0
  10. package/assets/seeing/seeing_probe.gd +1873 -0
  11. package/dist/cli/commands/skills.js +20 -2
  12. package/dist/core/api-client.d.ts +9 -1
  13. package/dist/core/api-client.js +21 -4
  14. package/dist/core/capabilities/agent-playbook.js +46 -0
  15. package/dist/core/capabilities/audit/accept.d.ts +55 -0
  16. package/dist/core/capabilities/audit/accept.js +147 -0
  17. package/dist/core/capabilities/audit/args.d.ts +95 -0
  18. package/dist/core/capabilities/audit/args.js +89 -0
  19. package/dist/core/capabilities/audit/audit.d.ts +56 -0
  20. package/dist/core/capabilities/audit/audit.js +287 -0
  21. package/dist/core/capabilities/audit/frame.d.ts +14 -0
  22. package/dist/core/capabilities/audit/frame.js +35 -0
  23. package/dist/core/capabilities/audit/gaps.d.ts +96 -0
  24. package/dist/core/capabilities/audit/gaps.js +257 -0
  25. package/dist/core/capabilities/audit/judge.d.ts +162 -0
  26. package/dist/core/capabilities/audit/judge.js +1134 -0
  27. package/dist/core/capabilities/audit/math.d.ts +110 -0
  28. package/dist/core/capabilities/audit/math.js +263 -0
  29. package/dist/core/capabilities/audit/summary.d.ts +74 -0
  30. package/dist/core/capabilities/audit/summary.js +212 -0
  31. package/dist/core/capabilities/board.d.ts +31 -0
  32. package/dist/core/capabilities/board.js +43 -0
  33. package/dist/core/capabilities/camera-view.d.ts +4 -2
  34. package/dist/core/capabilities/camera-view.js +6 -3
  35. package/dist/core/capabilities/connect-signal.d.ts +85 -0
  36. package/dist/core/capabilities/connect-signal.js +285 -0
  37. package/dist/core/capabilities/engine-fallbacks.d.ts +5 -0
  38. package/dist/core/capabilities/engine-fallbacks.js +5 -0
  39. package/dist/core/capabilities/engine-ops.d.ts +5 -1
  40. package/dist/core/capabilities/engine-ops.js +0 -3
  41. package/dist/core/capabilities/engine-receipt.d.ts +12 -0
  42. package/dist/core/capabilities/engine-receipt.js +26 -0
  43. package/dist/core/capabilities/file-read.d.ts +64 -0
  44. package/dist/core/capabilities/file-read.js +325 -0
  45. package/dist/core/capabilities/game-task-plan.js +4 -2
  46. package/dist/core/capabilities/grep.d.ts +60 -0
  47. package/dist/core/capabilities/grep.js +190 -0
  48. package/dist/core/capabilities/inspect-node.d.ts +56 -0
  49. package/dist/core/capabilities/inspect-node.js +225 -0
  50. package/dist/core/capabilities/inspect-resource.d.ts +61 -0
  51. package/dist/core/capabilities/inspect-resource.js +376 -0
  52. package/dist/core/capabilities/math3d.d.ts +28 -0
  53. package/dist/core/capabilities/math3d.js +88 -0
  54. package/dist/core/capabilities/motion-generation.d.ts +62 -0
  55. package/dist/core/capabilities/motion-generation.js +138 -0
  56. package/dist/core/capabilities/placement-batch.d.ts +102 -0
  57. package/dist/core/capabilities/placement-batch.js +483 -0
  58. package/dist/core/capabilities/placement-math.d.ts +70 -0
  59. package/dist/core/capabilities/placement-math.js +209 -0
  60. package/dist/core/capabilities/placement-script.d.ts +42 -0
  61. package/dist/core/capabilities/placement-script.js +1096 -0
  62. package/dist/core/capabilities/placement.d.ts +485 -0
  63. package/dist/core/capabilities/placement.js +1731 -0
  64. package/dist/core/capabilities/project-context.d.ts +33 -2
  65. package/dist/core/capabilities/project-context.js +87 -4
  66. package/dist/core/capabilities/replace-node.d.ts +91 -0
  67. package/dist/core/capabilities/replace-node.js +423 -0
  68. package/dist/core/capabilities/runtime-control.d.ts +18 -2
  69. package/dist/core/capabilities/runtime-control.js +67 -2
  70. package/dist/core/capabilities/scene-batch.d.ts +63 -0
  71. package/dist/core/capabilities/scene-batch.js +394 -0
  72. package/dist/core/capabilities/scene-readback.d.ts +36 -0
  73. package/dist/core/capabilities/scene-readback.js +54 -0
  74. package/dist/core/capabilities/seeing/args.d.ts +348 -0
  75. package/dist/core/capabilities/seeing/args.js +178 -0
  76. package/dist/core/capabilities/seeing/candidates.d.ts +127 -0
  77. package/dist/core/capabilities/seeing/candidates.js +282 -0
  78. package/dist/core/capabilities/seeing/math.d.ts +134 -0
  79. package/dist/core/capabilities/seeing/math.js +269 -0
  80. package/dist/core/capabilities/seeing/probe.d.ts +62 -0
  81. package/dist/core/capabilities/seeing/probe.js +188 -0
  82. package/dist/core/capabilities/seeing/scoring.d.ts +235 -0
  83. package/dist/core/capabilities/seeing/scoring.js +639 -0
  84. package/dist/core/capabilities/seeing/seeing.d.ts +233 -0
  85. package/dist/core/capabilities/seeing/seeing.js +1341 -0
  86. package/dist/core/capabilities/seeing/shot-store.d.ts +52 -0
  87. package/dist/core/capabilities/seeing/shot-store.js +204 -0
  88. package/dist/core/capabilities/surface-snap-mesh.d.ts +88 -0
  89. package/dist/core/capabilities/surface-snap-mesh.js +425 -0
  90. package/dist/core/capabilities/surface-snap.d.ts +77 -0
  91. package/dist/core/capabilities/surface-snap.js +461 -0
  92. package/dist/core/capabilities/tool-dispatch.js +231 -72
  93. package/dist/core/capabilities/tscn.d.ts +85 -0
  94. package/dist/core/capabilities/tscn.js +391 -0
  95. package/dist/core/capabilities/world-snapshot.d.ts +58 -0
  96. package/dist/core/capabilities/world-snapshot.js +150 -0
  97. package/dist/core/capability-skew.d.ts +5 -5
  98. package/dist/core/capability-skew.js +14 -6
  99. package/dist/core/headless/worker-engine-client.d.ts +1 -1
  100. package/dist/core/headless/worker-engine-client.js +2 -2
  101. package/dist/core/library-read.d.ts +37 -5
  102. package/dist/core/library-read.js +264 -33
  103. package/dist/core/library-search.d.ts +2 -2
  104. package/dist/installer/agent-config.js +5 -3
  105. package/dist/installer/agent-table.d.ts +16 -0
  106. package/dist/installer/agent-table.js +52 -17
  107. package/dist/mcp/server.js +9 -3
  108. package/dist/mcp/tools/asset-tools.js +21 -3
  109. package/dist/mcp/tools/audit-tools.d.ts +23 -0
  110. package/dist/mcp/tools/audit-tools.js +60 -0
  111. package/dist/mcp/tools/debug-tools.js +3 -1
  112. package/dist/mcp/tools/file-tools.js +17 -4
  113. package/dist/mcp/tools/generate-tools.js +74 -66
  114. package/dist/mcp/tools/library-tools.js +2 -0
  115. package/dist/mcp/tools/perception-tools.js +6 -19
  116. package/dist/mcp/tools/placement-tools.d.ts +24 -0
  117. package/dist/mcp/tools/placement-tools.js +91 -0
  118. package/dist/mcp/tools/project-tools.js +18 -15
  119. package/dist/mcp/tools/scene-tools.js +71 -83
  120. package/dist/mcp/tools/seeing-tools.d.ts +24 -0
  121. package/dist/mcp/tools/seeing-tools.js +64 -0
  122. package/dist/mcp/tools/spatial-tools.js +17 -9
  123. package/dist/mcp/tools/visual-tools.js +59 -7
  124. package/gemini-extension.json +26 -4
  125. package/integrations/amp/README.md +1 -1
  126. package/integrations/crush/README.md +1 -1
  127. package/integrations/grok-build/README.md +1 -1
  128. package/integrations/hermes/README.md +1 -1
  129. package/integrations/kimi-code/README.md +1 -1
  130. package/integrations/mistral-vibe/README.md +1 -1
  131. package/integrations/opencode/README.md +1 -1
  132. package/integrations/rovo-dev/README.md +1 -1
  133. package/integrations/vscode-copilot/README.md +1 -1
  134. package/integrations/warp/README.md +1 -1
  135. package/integrations/windsurf/README.md +1 -1
  136. package/library/references/mcp-tools-reference/mcp-tools-reference.md +59 -15
  137. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  138. package/library/references/summer-folder/resource.yaml +1 -1
  139. package/library/references/summer-folder/summer-folder.md +1 -1
  140. package/library/skills/3d-lighting/SKILL.md +1 -1
  141. package/library/skills/README.md +36 -14
  142. package/library/skills/adaptive-music/SKILL.md +1 -1
  143. package/library/skills/agent-playtesting/SKILL.md +1 -1
  144. package/library/skills/ai-characters-in-games/SKILL.md +220 -0
  145. package/library/skills/ai-characters-in-games/resource.yaml +30 -0
  146. package/library/skills/ambient-bed/SKILL.md +1 -1
  147. package/library/skills/animated-loop/SKILL.md +1 -1
  148. package/library/skills/animation-tree/SKILL.md +1 -1
  149. package/library/skills/art-direction/SKILL.md +1 -1
  150. package/library/skills/asset-strategy/SKILL.md +2 -1
  151. package/library/skills/asset-strategy/resource.yaml +2 -1
  152. package/library/skills/audio-direction/SKILL.md +1 -1
  153. package/library/skills/auto-fire-targeting/SKILL.md +1 -1
  154. package/library/skills/brainstorm-game/SKILL.md +1 -1
  155. package/library/skills/brainstorming/SKILL.md +1 -1
  156. package/library/skills/browse-templates/SKILL.md +3 -3
  157. package/library/skills/browse-templates/resource.yaml +1 -1
  158. package/library/skills/camera-rigs/SKILL.md +128 -0
  159. package/library/skills/camera-rigs/resource.yaml +29 -0
  160. package/library/skills/celeste-momentum-platforming/SKILL.md +1 -1
  161. package/library/skills/character-animation-wiring/SKILL.md +1 -1
  162. package/library/skills/character-model/SKILL.md +1 -1
  163. package/library/skills/character-movement/SKILL.md +326 -0
  164. package/library/skills/character-movement/references/default-third-person-controller.gd +201 -0
  165. package/library/skills/character-movement/references/default-third-person-verification-probe.gd +154 -0
  166. package/library/skills/character-movement/references/movement-3d.md +136 -0
  167. package/library/skills/character-movement/references/platformer-feel.md +83 -0
  168. package/library/skills/character-movement/resource.yaml +40 -0
  169. package/library/skills/character-portrait/SKILL.md +1 -1
  170. package/library/skills/cinematic-cutscene/SKILL.md +1 -1
  171. package/library/skills/combat-basics/SKILL.md +159 -0
  172. package/library/skills/combat-basics/references/projectiles-and-aoe.md +100 -0
  173. package/library/skills/combat-basics/resource.yaml +34 -0
  174. package/library/skills/concept-art/SKILL.md +1 -1
  175. package/library/skills/create-asset-sheet/SKILL.md +1 -1
  176. package/library/skills/debug/SKILL.md +1 -1
  177. package/library/skills/debugging-game-feel/SKILL.md +1 -1
  178. package/library/skills/design-level/SKILL.md +1 -1
  179. package/library/skills/design-mechanic/SKILL.md +1 -1
  180. package/library/skills/design-npc/SKILL.md +1 -1
  181. package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
  182. package/library/skills/dispatching-parallel-agents/SKILL.md +1 -1
  183. package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
  184. package/library/skills/environment-kit/SKILL.md +1 -1
  185. package/library/skills/export-and-ship/SKILL.md +1 -1
  186. package/library/skills/fabricating-assets/SKILL.md +1 -1
  187. package/library/skills/facial-and-lipsync/SKILL.md +1 -1
  188. package/library/skills/fps-controller/SKILL.md +9 -7
  189. package/library/skills/fps-controller/resource.yaml +4 -1
  190. package/library/skills/game-feel/SKILL.md +1 -1
  191. package/library/skills/gameskill/SKILL.md +1 -1
  192. package/library/skills/gdscript-patterns/SKILL.md +1 -1
  193. package/library/skills/generate-motion/SKILL.md +9 -9
  194. package/library/skills/generate-motion/resource.yaml +2 -1
  195. package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
  196. package/library/skills/headless-scripting/SKILL.md +1 -1
  197. package/library/skills/in-game-purchases/SKILL.md +254 -0
  198. package/library/skills/in-game-purchases/resource.yaml +29 -0
  199. package/library/skills/instantiate-asset-pack/SKILL.md +1 -1
  200. package/library/skills/investigating-bugs/SKILL.md +1 -1
  201. package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +1 -1
  202. package/library/skills/make-game/SKILL.md +25 -3
  203. package/library/skills/make-game/references/2d-platformer-polish.md +93 -0
  204. package/library/skills/make-game/references/2d-platformer.md +117 -0
  205. package/library/skills/make-game/references/2d-rpg-content.md +234 -0
  206. package/library/skills/make-game/references/2d-rpg.md +241 -0
  207. package/library/skills/make-game/references/2d-survivors-progression.md +201 -0
  208. package/library/skills/make-game/references/2d-survivors.md +237 -0
  209. package/library/skills/make-game/references/3d-fps-systems.md +216 -0
  210. package/library/skills/make-game/references/3d-fps.md +177 -0
  211. package/library/skills/make-game/references/3d-horror-systems.md +186 -0
  212. package/library/skills/make-game/references/3d-horror.md +201 -0
  213. package/library/skills/make-game/references/3d-third-person-systems.md +220 -0
  214. package/library/skills/make-game/references/3d-third-person.md +215 -0
  215. package/library/skills/make-game/resource.yaml +6 -1
  216. package/library/skills/multiplayer/SKILL.md +150 -0
  217. package/library/skills/multiplayer/resource.yaml +33 -0
  218. package/library/skills/multiplayer-movement/SKILL.md +510 -0
  219. package/library/skills/multiplayer-movement/files.md +501 -0
  220. package/library/skills/multiplayer-movement/resource.yaml +30 -0
  221. package/library/skills/multiplayer-project/SKILL.md +521 -0
  222. package/library/skills/multiplayer-project/files.md +448 -0
  223. package/library/skills/multiplayer-project/resource.yaml +36 -0
  224. package/library/skills/multiplayer-publish/SKILL.md +229 -0
  225. package/library/skills/multiplayer-publish/export-errors.md +89 -0
  226. package/library/skills/multiplayer-publish/resource.yaml +28 -0
  227. package/library/skills/multiplayer-state/SKILL.md +438 -0
  228. package/library/skills/multiplayer-state/files.md +592 -0
  229. package/library/skills/multiplayer-state/resource.yaml +35 -0
  230. package/library/skills/multiplayer-testing/SKILL.md +236 -0
  231. package/library/skills/multiplayer-testing/resource.yaml +39 -0
  232. package/library/skills/music-track/SKILL.md +1 -1
  233. package/library/skills/navigate-summer/SKILL.md +1 -1
  234. package/library/skills/new-project/SKILL.md +1 -1
  235. package/library/skills/organic-model/SKILL.md +1 -1
  236. package/library/skills/pixel-art/SKILL.md +1 -1
  237. package/library/skills/play/SKILL.md +1 -1
  238. package/library/skills/playtesting-a-feature/SKILL.md +1 -1
  239. package/library/skills/procedural-animation/SKILL.md +2 -2
  240. package/library/skills/procedural-animation/resource.yaml +1 -1
  241. package/library/skills/prop-model/SKILL.md +1 -1
  242. package/library/skills/psx-retro-rendering/SKILL.md +1 -1
  243. package/library/skills/realtime-wet-surfaces/SKILL.md +2 -2
  244. package/library/skills/remote-deploy/SKILL.md +1 -1
  245. package/library/skills/retarget/SKILL.md +1 -1
  246. package/library/skills/running-in-the-cloud/SKILL.md +1 -1
  247. package/library/skills/save-load/SKILL.md +156 -0
  248. package/library/skills/save-load/resource.yaml +27 -0
  249. package/library/skills/scene-composition/SKILL.md +1 -1
  250. package/library/skills/scene-hierarchy-design/SKILL.md +1 -1
  251. package/library/skills/scene-scripting/SKILL.md +1 -1
  252. package/library/skills/scene-to-level/SKILL.md +1 -1
  253. package/library/skills/skill-create/SKILL.md +1 -1
  254. package/library/skills/skill-improve/SKILL.md +1 -1
  255. package/library/skills/skill-test/SKILL.md +1 -1
  256. package/library/skills/skintokens-auto-rigging/SKILL.md +1 -1
  257. package/library/skills/skybox-panorama/SKILL.md +1 -1
  258. package/library/skills/sound-effect/SKILL.md +1 -1
  259. package/library/skills/spatial-placement/SKILL.md +134 -3
  260. package/library/skills/spatial-placement/references/kit-placement-tools.md +364 -0
  261. package/library/skills/spatial-placement/resource.yaml +16 -2
  262. package/library/skills/sprite-sheet/SKILL.md +1 -1
  263. package/library/skills/summer-analytics/SKILL.md +147 -0
  264. package/library/skills/summer-analytics/resource.yaml +28 -0
  265. package/library/skills/summer-friends/SKILL.md +226 -0
  266. package/library/skills/summer-friends/resource.yaml +28 -0
  267. package/library/skills/summer-leaderboards/SKILL.md +231 -0
  268. package/library/skills/summer-leaderboards/resource.yaml +30 -0
  269. package/library/skills/summer-match-results/SKILL.md +286 -0
  270. package/library/skills/summer-match-results/resource.yaml +32 -0
  271. package/library/skills/summer-matchmaking/SKILL.md +301 -0
  272. package/library/skills/summer-matchmaking/resource.yaml +32 -0
  273. package/library/skills/summer-parties/SKILL.md +253 -0
  274. package/library/skills/summer-parties/resource.yaml +30 -0
  275. package/library/skills/summer-player-data/SKILL.md +322 -0
  276. package/library/skills/summer-player-data/resource.yaml +30 -0
  277. package/library/skills/summer-store/SKILL.md +271 -0
  278. package/library/skills/summer-store/resource.yaml +29 -0
  279. package/library/skills/summer-world-chat/SKILL.md +195 -0
  280. package/library/skills/summer-world-chat/resource.yaml +30 -0
  281. package/library/skills/summer-world-saves/SKILL.md +284 -0
  282. package/library/skills/summer-world-saves/resource.yaml +29 -0
  283. package/library/skills/text-to-motion/SKILL.md +99 -0
  284. package/library/skills/text-to-motion/prompts-and-controls.md +34 -0
  285. package/library/skills/text-to-motion/resource.yaml +41 -0
  286. package/library/skills/text-to-motion/rigging-for-text-motion.md +54 -0
  287. package/library/skills/tileable-texture/SKILL.md +1 -1
  288. package/library/skills/trailer-shot/SKILL.md +1 -1
  289. package/library/skills/tune-performance/SKILL.md +1 -1
  290. package/library/skills/ui-basics/SKILL.md +10 -1
  291. package/library/skills/ui-graphics/SKILL.md +1 -1
  292. package/library/skills/use-widget-asset/SKILL.md +1 -1
  293. package/library/skills/using-summer/SKILL.md +2 -2
  294. package/library/skills/using-summer/resource.yaml +2 -2
  295. package/library/skills/vehicle-model/SKILL.md +1 -1
  296. package/library/skills/verification-before-completion/SKILL.md +1 -1
  297. package/library/skills/verifying-scenes/SKILL.md +76 -2
  298. package/library/skills/verifying-scenes/resource.yaml +13 -2
  299. package/library/skills/vfx-dissolve/SKILL.md +1 -1
  300. package/library/skills/vfx-fire/SKILL.md +1 -1
  301. package/library/skills/vfx-hit-spark/SKILL.md +1 -1
  302. package/library/skills/vfx-lightning/SKILL.md +1 -1
  303. package/library/skills/vfx-magic-glow/SKILL.md +1 -1
  304. package/library/skills/vfx-muzzle-flash/SKILL.md +1 -1
  305. package/library/skills/vfx-smoke/SKILL.md +1 -1
  306. package/library/skills/vfx-water-ripple/SKILL.md +1 -1
  307. package/library/skills/voice-line/SKILL.md +1 -1
  308. package/library/skills/web-and-touch-input/SKILL.md +38 -0
  309. package/library/skills/web-and-touch-input/resource.yaml +28 -0
  310. package/library/skills/web-compatibility-look/SKILL.md +62 -0
  311. package/library/skills/web-compatibility-look/resource.yaml +30 -0
  312. package/library/skills/world-building-3d/SKILL.md +8 -1
  313. package/library/skills/world-building-3d/references/spatial-tools.md +1 -1
  314. package/library/skills/world-building-3d/resource.yaml +2 -1
  315. package/library/skills/writing-plans/SKILL.md +1 -1
  316. package/library/skills/writing-skills/SKILL.md +1 -1
  317. package/library/templates/3d-lan-multiplayer-starter/resource.yaml +2 -2
  318. package/library/tools/attach-to-surface/resource.yaml +142 -0
  319. package/library/tools/batch/resource.yaml +9 -3
  320. package/library/tools/connect-ports/resource.yaml +120 -0
  321. package/library/tools/connect-signal/resource.yaml +3 -2
  322. package/library/tools/debug-views/resource.yaml +94 -0
  323. package/library/tools/frame-nodes/resource.yaml +104 -0
  324. package/library/tools/frame-shot/resource.yaml +134 -0
  325. package/library/tools/generate-motion/resource.yaml +44 -9
  326. package/library/tools/get-board/resource.yaml +50 -0
  327. package/library/tools/get-project-context/resource.yaml +13 -2
  328. package/library/tools/grep/resource.yaml +77 -0
  329. package/library/tools/inspect-asset/resource.yaml +71 -0
  330. package/library/tools/inspect-node/resource.yaml +9 -2
  331. package/library/tools/inspect-resource/resource.yaml +16 -5
  332. package/library/tools/instantiate-scene/resource.yaml +27 -2
  333. package/library/tools/measure/resource.yaml +96 -0
  334. package/library/tools/place-adjacent/resource.yaml +113 -0
  335. package/library/tools/play/resource.yaml +15 -2
  336. package/library/tools/raycast/resource.yaml +101 -0
  337. package/library/tools/read-file/resource.yaml +36 -2
  338. package/library/tools/read-library/resource.yaml +2 -2
  339. package/library/tools/repeat-along/resource.yaml +129 -0
  340. package/library/tools/replace-node/resource.yaml +11 -5
  341. package/library/tools/scene-audit/resource.yaml +144 -0
  342. package/library/tools/screenshot/resource.yaml +13 -2
  343. package/library/tools/search-assets/resource.yaml +18 -0
  344. package/library/tools/shot-sheet/resource.yaml +110 -0
  345. package/library/tools/snap-to-surface/resource.yaml +4 -1
  346. package/library/tools/world-snapshot/resource.yaml +24 -3
  347. package/library/tools/zoom/resource.yaml +105 -0
  348. package/package.json +1 -1
  349. package/registry/generated/aliases.json +17 -3
  350. package/registry/generated/counts.json +3 -3
  351. package/registry/generated/gemini-extension.json +26 -4
  352. package/registry/generated/index.json +2154 -469
  353. package/registry/generated/marketplace.claude.json +2 -2
  354. package/registry/generated/plugin.claude.json +27 -5
  355. package/registry/generated/plugin.codex.json +28 -6
  356. package/registry/generated/plugin.cursor.json +27 -5
  357. package/registry/generated/plugin.factory.json +27 -5
  358. package/registry/generated/skills-index.md +36 -14
  359. package/registry/generated/skills-registry.json +421 -124
  360. package/registry/generated/templates-registry.json +2 -2
  361. package/library/skills/host-authoritative-state/SKILL.md +0 -332
  362. package/library/skills/host-authoritative-state/resource.yaml +0 -28
  363. package/library/skills/peer-to-peer-multiplayer/SKILL.md +0 -373
  364. package/library/skills/peer-to-peer-multiplayer/resource.yaml +0 -28
  365. package/library/skills/setup-multiplayer/SKILL.md +0 -336
  366. package/library/skills/setup-multiplayer/resource.yaml +0 -28
@@ -0,0 +1,376 @@
1
+ /**
2
+ * inspect-resource — ONE implementation of `summer_inspect_resource` for both
3
+ * faces (src/mcp/tools/scene-tools.ts and tool-dispatch.ts).
4
+ *
5
+ * The engine's state:resource (StateProvider::resource_properties_state)
6
+ * reads a resource a NODE holds: it takes nodePath + property and answers
7
+ * "missing nodePath or property" to anything else. The tool used to send it
8
+ * only `path`, so every call failed, on a mesh .res or a .glb alike. Two forms
9
+ * now:
10
+ *
11
+ * path a resource FILE, loaded in the editor by a read-only
12
+ * RunSceneScript probe (undo none, no checkpoint; the
13
+ * path travels as base64 data, never as source):
14
+ * Mesh AABB, surfaces (primitive, vertex and
15
+ * index counts, attributes, triangles,
16
+ * material), materials, blend shapes
17
+ * PackedScene node count, the first nodes with their
18
+ * types, instanced scenes and meshes, and
19
+ * a pointer to summer_inspect_asset
20
+ * Texture2D size
21
+ * every other editor properties that differ from the
22
+ * class default (defaults are counted)
23
+ * nodePath+property the engine endpoint, for a resource a node of the
24
+ * active scene holds (e.g. Floor + mesh).
25
+ */
26
+ import { z } from "zod";
27
+ import { missingEngineOpResult } from "../capability-skew.js";
28
+ import { ToolInputError } from "../tool-errors.js";
29
+ import { asRecord } from "../util/json.js";
30
+ import { extractOpError, withOldEngineHint } from "./engine-receipt.js";
31
+ import { buildRunSceneScriptOp } from "./scene-script.js";
32
+ import { encodeScriptArgs } from "./placement-script.js";
33
+ import { fitToBudget } from "./placement.js";
34
+ export const INSPECT_RESOURCE_ARGS_TOKEN = "__SUMMER_RESOURCE_ARGS__";
35
+ export const INSPECT_RESOURCE_FALLBACK = "read a text resource (.tres/.tscn) with summer_read_file, or pass nodePath + property for a resource a node of the open scene holds";
36
+ const RES_FILE = /^res:\/\/[^\u0000-\u001f]+$/;
37
+ // Mirrors library/tools/inspect-resource/resource.yaml input_schema (parity-tested).
38
+ export const inspectResourceInputShape = {
39
+ path: z
40
+ .string()
41
+ .trim()
42
+ .min(1)
43
+ .max(512)
44
+ .refine((value) => RES_FILE.test(value) && !value.includes(".."), "path must be a res:// resource file without '..'")
45
+ .optional()
46
+ .describe("A resource FILE: 'res://materials/ground.tres', a mesh 'res://kit/meshes/wall_01.res', a texture, a shape, or a scene/model 'res://models/player.glb'. Loaded read-only in the editor."),
47
+ nodePath: z
48
+ .string()
49
+ .trim()
50
+ .min(1)
51
+ .max(256)
52
+ .optional()
53
+ .describe("With property: a node of the ACTIVE scene tab whose resource to read, e.g. 'Floor'. Do not combine with path."),
54
+ property: z
55
+ .string()
56
+ .trim()
57
+ .min(1)
58
+ .max(128)
59
+ .optional()
60
+ .describe("With nodePath: the node property holding the resource, e.g. 'mesh', 'material_override', 'shape', 'environment'."),
61
+ };
62
+ export const inspectResourceInputSchema = z.object(inspectResourceInputShape).strict();
63
+ const TOOL = "summer_inspect_resource";
64
+ const RESULT_TARGET_BYTES = 6000;
65
+ function fail(failureReason, error, extra = {}) {
66
+ return { ok: false, tool: TOOL, failure_reason: failureReason, error, ...extra };
67
+ }
68
+ export async function inspectResource(client, args) {
69
+ const hasNodeForm = args.nodePath !== undefined || args.property !== undefined;
70
+ if (args.path !== undefined && hasNodeForm) {
71
+ throw new ToolInputError("Pass either path (a resource file) or nodePath + property (a resource a node holds), not both.");
72
+ }
73
+ if (args.path !== undefined)
74
+ return inspectResourceFile(client, args.path);
75
+ if (args.nodePath !== undefined && args.property !== undefined) {
76
+ return client.inspectNodeResource(args.nodePath, args.property);
77
+ }
78
+ if (hasNodeForm)
79
+ throw new ToolInputError("nodePath and property go together, e.g. nodePath 'Floor' + property 'mesh'.");
80
+ throw new ToolInputError("Pass path (a resource file, e.g. 'res://materials/ground.tres' or a mesh 'res://kit/meshes/wall_01.res'), or nodePath + property (e.g. 'Floor' + 'mesh').");
81
+ }
82
+ /** Load a resource file read-only in the editor and describe it compactly. */
83
+ export async function inspectResourceFile(client, path) {
84
+ const missing = missingEngineOpResult(client, "RunSceneScript", INSPECT_RESOURCE_FALLBACK);
85
+ if (missing)
86
+ return { ...missing, tool: TOOL };
87
+ const { op, timeoutMs } = buildRunSceneScriptOp({
88
+ source: buildInspectResourceScript({ path }),
89
+ max_seconds: 20,
90
+ checkpoint: false,
91
+ undo: "none",
92
+ });
93
+ const receipt = await client.executeIdentityBoundOps([op], undefined, timeoutMs);
94
+ const hinted = asRecord(withOldEngineHint(receipt, "RunSceneScript", INSPECT_RESOURCE_FALLBACK));
95
+ if (hinted?.failure_reason === "engine_lacks_op")
96
+ return fail("engine_lacks_op", String(hinted.error), { op: "RunSceneScript" });
97
+ const envelope = asRecord(receipt) ?? {};
98
+ const results = Array.isArray(envelope.results) ? envelope.results : [];
99
+ const entry = asRecord(results.find((item) => asRecord(item)?.op === "RunSceneScript") ?? results[0]);
100
+ const envelopeError = extractOpError(receipt);
101
+ if (!entry || entry.ok === false || envelopeError) {
102
+ return fail("resource_probe_failed", `The resource probe (RunSceneScript) failed: ${String(entry?.error ?? envelopeError ?? "no result")}`);
103
+ }
104
+ const result = asRecord(entry.result);
105
+ if (!result)
106
+ return fail("resource_probe_failed", "The resource probe ran but returned no result.");
107
+ if (result.ok !== true) {
108
+ return fail(typeof result.failure_reason === "string" ? result.failure_reason : "resource_probe_failed", typeof result.error === "string" ? result.error : "The resource probe reported a failure.");
109
+ }
110
+ const { ok: _ok, ...rest } = result;
111
+ const out = { ok: true, tool: TOOL, source: "file", ...rest, evidence: "resource_loader" };
112
+ const mesh = asRecord(out.mesh);
113
+ const scene = asRecord(out.scene);
114
+ if (mesh)
115
+ out.mesh = fitToBudget(mesh, ["surfaces", "materials"], RESULT_TARGET_BYTES - 600);
116
+ if (scene)
117
+ out.scene = fitToBudget(scene, ["nodes", "meshes"], RESULT_TARGET_BYTES - 600);
118
+ return trimProps(out, RESULT_TARGET_BYTES);
119
+ }
120
+ function bytes(value) {
121
+ return Buffer.byteLength(JSON.stringify(value), "utf8");
122
+ }
123
+ /** Drop trailing props until the result fits; declare the cut. */
124
+ function trimProps(out, target) {
125
+ const props = asRecord(out.props);
126
+ if (!props || bytes(out) <= target)
127
+ return out;
128
+ const keys = Object.keys(props);
129
+ const kept = (n) => Object.fromEntries(keys.slice(0, n).map((key) => [key, props[key]]));
130
+ let n = keys.length;
131
+ while (n > 0 && bytes({ ...out, props: kept(n) }) > target)
132
+ n--;
133
+ return { ...out, props: kept(n), truncated: { ...(asRecord(out.truncated) ?? {}), props: { shown: n, total: keys.length } } };
134
+ }
135
+ export function buildInspectResourceScript(args) {
136
+ return INSPECT_RESOURCE_PROBE_SOURCE.split(INSPECT_RESOURCE_ARGS_TOKEN).join(`"${encodeScriptArgs(args)}"`);
137
+ }
138
+ /** The probe source with its placeholder, for tests. */
139
+ export function inspectResourceProbeTemplate() {
140
+ return INSPECT_RESOURCE_PROBE_SOURCE;
141
+ }
142
+ // Tabs are significant: GDScript indentation. String.raw keeps backslashes
143
+ // literal; the source never contains a template placeholder.
144
+ const INSPECT_RESOURCE_PROBE_SOURCE = String.raw `@tool
145
+ extends RefCounted
146
+
147
+ const ARGS_B64 = __SUMMER_RESOURCE_ARGS__
148
+ const MAX_SURFACES = 48
149
+ const MAX_PROPS = 80
150
+ const MAX_NODES = 40
151
+ const MAX_SCENE_MESHES = 24
152
+ const MAX_VALUE_CHARS = 160
153
+ const PRIMITIVES = ["points", "lines", "line_strip", "triangles", "triangle_strip"]
154
+
155
+
156
+ func run(_ctx):
157
+ var args = JSON.parse_string(Marshalls.base64_to_utf8(ARGS_B64))
158
+ if typeof(args) != TYPE_DICTIONARY:
159
+ return _fail("bad_args", "resource probe arguments did not parse")
160
+ var path = String(args.get("path", ""))
161
+ if not ResourceLoader.exists(path):
162
+ return _fail("resource_not_found", "No resource at " + path)
163
+ var res = ResourceLoader.load(path)
164
+ if res == null:
165
+ return _fail("resource_load_failed", "ResourceLoader could not load " + path)
166
+ var out = {"ok": true, "path": path, "resource_type": res.get_class()}
167
+ if String(res.resource_name) != "":
168
+ out["resource_name"] = String(res.resource_name)
169
+ if res.get_script() != null:
170
+ out["script"] = String(res.get_script().resource_path)
171
+ if res is Mesh:
172
+ out["mesh"] = _mesh(res)
173
+ elif res is PackedScene:
174
+ out["scene"] = _scene(res)
175
+ out["next"] = "summer_inspect_asset measures this scene (AABB, origin, planes, ports, anchors, collision); summer_inspect_resource on one of its mesh paths lists that mesh's surfaces and materials"
176
+ return out
177
+ elif res is Texture2D:
178
+ out["texture"] = {"width": res.get_width(), "height": res.get_height()}
179
+ var pr = _props(res)
180
+ out["props"] = pr["props"]
181
+ out["props_at_default"] = pr["defaults"]
182
+ if pr["cut"] > 0:
183
+ out["props_cut"] = pr["cut"]
184
+ return out
185
+
186
+
187
+ func _fail(reason, message):
188
+ return {"ok": false, "failure_reason": reason, "error": message}
189
+
190
+
191
+ func _v3(v):
192
+ return [snappedf(v.x, 0.0001), snappedf(v.y, 0.0001), snappedf(v.z, 0.0001)]
193
+
194
+
195
+ func _ref(r):
196
+ if r == null:
197
+ return null
198
+ var rec = {"class": r.get_class()}
199
+ var p = String(r.resource_path)
200
+ if p != "" and not p.contains("::"):
201
+ rec["path"] = p
202
+ else:
203
+ rec["embedded"] = true
204
+ if String(r.resource_name) != "":
205
+ rec["name"] = String(r.resource_name)
206
+ return rec
207
+
208
+
209
+ func _material(mat):
210
+ if mat == null:
211
+ return null
212
+ var rec = _ref(mat)
213
+ if mat is BaseMaterial3D:
214
+ rec["albedo_color"] = var_to_str(mat.albedo_color)
215
+ if mat.albedo_texture != null:
216
+ rec["albedo_texture"] = _ref(mat.albedo_texture)
217
+ rec["transparency"] = int(mat.transparency)
218
+ rec["cull_mode"] = int(mat.cull_mode)
219
+ elif mat is ShaderMaterial and mat.shader != null:
220
+ rec["shader"] = _ref(mat.shader)
221
+ return rec
222
+
223
+
224
+ func _format(f):
225
+ var names = []
226
+ var flags = [[Mesh.ARRAY_FORMAT_NORMAL, "normal"], [Mesh.ARRAY_FORMAT_TANGENT, "tangent"], [Mesh.ARRAY_FORMAT_COLOR, "color"], [Mesh.ARRAY_FORMAT_TEX_UV, "uv"], [Mesh.ARRAY_FORMAT_TEX_UV2, "uv2"], [Mesh.ARRAY_FORMAT_BONES, "bones"], [Mesh.ARRAY_FORMAT_WEIGHTS, "weights"], [Mesh.ARRAY_FORMAT_INDEX, "index"]]
227
+ for fl in flags:
228
+ if (int(f) & int(fl[0])) != 0:
229
+ names.append(fl[1])
230
+ return names
231
+
232
+
233
+ func _mesh(mesh):
234
+ var bb = mesh.get_aabb()
235
+ var out = {"aabb": {"min": _v3(bb.position), "max": _v3(bb.end), "size": _v3(bb.size)}}
236
+ var count = mesh.get_surface_count()
237
+ out["surface_count"] = count
238
+ var surfaces = []
239
+ var materials = []
240
+ var seen = {}
241
+ var tris = 0
242
+ var verts_total = 0
243
+ for s in range(count):
244
+ var rec = {"index": s}
245
+ var prim = Mesh.PRIMITIVE_TRIANGLES
246
+ var vc = 0
247
+ var ic = 0
248
+ if mesh is ArrayMesh:
249
+ prim = mesh.surface_get_primitive_type(s)
250
+ vc = mesh.surface_get_array_len(s)
251
+ ic = mesh.surface_get_array_index_len(s)
252
+ if String(mesh.surface_get_name(s)) != "":
253
+ rec["name"] = String(mesh.surface_get_name(s))
254
+ rec["attributes"] = _format(mesh.surface_get_format(s))
255
+ else:
256
+ var arr = mesh.surface_get_arrays(s)
257
+ if arr.size() > Mesh.ARRAY_INDEX:
258
+ var va = arr[Mesh.ARRAY_VERTEX]
259
+ var ia = arr[Mesh.ARRAY_INDEX]
260
+ vc = va.size() if va != null else 0
261
+ ic = ia.size() if ia != null else 0
262
+ rec["primitive"] = PRIMITIVES[prim] if prim >= 0 and prim < PRIMITIVES.size() else str(prim)
263
+ rec["vertices"] = vc
264
+ rec["indices"] = ic
265
+ var n = ic if ic > 0 else vc
266
+ var t = 0
267
+ if prim == Mesh.PRIMITIVE_TRIANGLES:
268
+ t = floori(n / 3.0)
269
+ elif prim == Mesh.PRIMITIVE_TRIANGLE_STRIP:
270
+ t = maxi(n - 2, 0)
271
+ rec["triangles"] = t
272
+ tris += t
273
+ verts_total += vc
274
+ var mat = mesh.surface_get_material(s)
275
+ rec["material"] = _material(mat)
276
+ if mat != null:
277
+ var key = String(mat.resource_path) if String(mat.resource_path) != "" else str(mat.get_instance_id())
278
+ if not seen.has(key):
279
+ seen[key] = true
280
+ materials.append(_material(mat))
281
+ if surfaces.size() < MAX_SURFACES:
282
+ surfaces.append(rec)
283
+ out["surfaces"] = surfaces
284
+ if count > surfaces.size():
285
+ out["surfaces_cut"] = count - surfaces.size()
286
+ out["triangles"] = tris
287
+ out["vertices"] = verts_total
288
+ out["materials"] = materials
289
+ if mesh is ArrayMesh:
290
+ out["blend_shapes"] = mesh.get_blend_shape_count()
291
+ return out
292
+
293
+
294
+ func _scene(ps):
295
+ var st = ps.get_state()
296
+ var n = st.get_node_count()
297
+ var nodes = []
298
+ var meshes = []
299
+ var seen = {}
300
+ var mesh_nodes = 0
301
+ for i in range(n):
302
+ var rec = {"path": String(st.get_node_path(i)), "type": String(st.get_node_type(i))}
303
+ var inst = st.get_node_instance(i)
304
+ if inst != null:
305
+ rec["instance"] = String(inst.resource_path)
306
+ for k in range(st.get_node_property_count(i)):
307
+ if String(st.get_node_property_name(i, k)) != "mesh":
308
+ continue
309
+ var m = st.get_node_property_value(i, k)
310
+ if not (m is Mesh):
311
+ continue
312
+ mesh_nodes += 1
313
+ var mref = _ref(m)
314
+ rec["mesh"] = mref
315
+ var key = String(m.resource_path) if String(m.resource_path) != "" else str(m.get_instance_id())
316
+ if not seen.has(key) and meshes.size() < MAX_SCENE_MESHES:
317
+ seen[key] = true
318
+ var bb = m.get_aabb()
319
+ var mrec = mref.duplicate()
320
+ mrec["surfaces"] = m.get_surface_count()
321
+ mrec["aabb_size"] = _v3(bb.size)
322
+ meshes.append(mrec)
323
+ if nodes.size() < MAX_NODES:
324
+ nodes.append(rec)
325
+ var out = {"node_count": n, "root_type": String(st.get_node_type(0)) if n > 0 else "", "nodes": nodes, "mesh_nodes": mesh_nodes, "meshes": meshes}
326
+ if n > nodes.size():
327
+ out["nodes_cut"] = n - nodes.size()
328
+ return out
329
+
330
+
331
+ func _same(a, b):
332
+ if typeof(a) != typeof(b):
333
+ return false
334
+ return a == b
335
+
336
+
337
+ func _value(v):
338
+ var t = typeof(v)
339
+ if t == TYPE_NIL or t == TYPE_BOOL or t == TYPE_INT or t == TYPE_FLOAT or t == TYPE_STRING or t == TYPE_STRING_NAME:
340
+ return v if t != TYPE_STRING_NAME else String(v)
341
+ if t == TYPE_OBJECT:
342
+ if v is Resource:
343
+ return _ref(v)
344
+ return v.get_class() if v != null else null
345
+ if t >= TYPE_PACKED_BYTE_ARRAY:
346
+ return type_string(t) + "(" + str(v.size()) + " items)"
347
+ var s = var_to_str(v)
348
+ if s.length() > MAX_VALUE_CHARS:
349
+ s = s.substr(0, MAX_VALUE_CHARS) + "..."
350
+ return s
351
+
352
+
353
+ func _props(res):
354
+ var props = {}
355
+ var defaults = 0
356
+ var cut = 0
357
+ var cls = res.get_class()
358
+ var builtin = res.get_script() == null
359
+ var skip = PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY | PROPERTY_USAGE_SUBGROUP
360
+ for p in res.get_property_list():
361
+ var usage = int(p["usage"])
362
+ if (usage & PROPERTY_USAGE_EDITOR) == 0 or (usage & skip) != 0:
363
+ continue
364
+ var name = String(p["name"])
365
+ if name == "resource_path" or name == "resource_name" or name == "script":
366
+ continue
367
+ var v = res.get(name)
368
+ if builtin and _same(v, ClassDB.class_get_property_default_value(cls, name)):
369
+ defaults += 1
370
+ continue
371
+ if props.size() >= MAX_PROPS:
372
+ cut += 1
373
+ continue
374
+ props[name] = _value(v)
375
+ return {"props": props, "defaults": defaults, "cut": cut}
376
+ `;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * math3d — the little 3D math the read and placement helpers need, in
3
+ * Godot's conventions: a Basis is three ROWS (Transform3D literals list
4
+ * xx, xy, xz, yx, ... then the origin), Euler angles default to YXZ order,
5
+ * and a Node3D's local basis is rotation * scale.
6
+ */
7
+ export type Vec3 = [number, number, number];
8
+ export type Mat3 = [Vec3, Vec3, Vec3];
9
+ export declare const IDENTITY3: Mat3;
10
+ export declare function mulMat3(a: Mat3, b: Mat3): Mat3;
11
+ export declare function applyMat3(m: Mat3, v: Vec3): Vec3;
12
+ /** Inverse, or null for a singular basis. */
13
+ export declare function invertMat3(m: Mat3): Mat3 | null;
14
+ /** Godot Basis::from_euler (YXZ order, degrees) times scale: R * S. */
15
+ export declare function basisFromEulerScale(rotDeg: Vec3, scale: Vec3): Mat3;
16
+ /** "(1, 2, 3)" / "Vector3(1, 2, 3)" -> [1, 2, 3]. */
17
+ export declare function parseVec3(value: unknown): Vec3 | null;
18
+ /** A `Transform3D(12 numbers)` literal -> basis rows + origin. */
19
+ export declare function parseTransform3D(value: string): {
20
+ basis: Mat3;
21
+ origin: Vec3;
22
+ } | null;
23
+ /** Vector3 literal at 3 decimals (for reports). */
24
+ export declare function vec3Literal(v: Vec3): string;
25
+ /** Vector3 literal for writing a position back: 12 significant digits
26
+ * (beyond Godot's float32 storage) without binary-arithmetic noise. */
27
+ export declare function vec3LiteralExact(v: Vec3): string;
28
+ export declare function transformLiteral(basis: Mat3, origin: Vec3): string;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * math3d — the little 3D math the read and placement helpers need, in
3
+ * Godot's conventions: a Basis is three ROWS (Transform3D literals list
4
+ * xx, xy, xz, yx, ... then the origin), Euler angles default to YXZ order,
5
+ * and a Node3D's local basis is rotation * scale.
6
+ */
7
+ export const IDENTITY3 = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
8
+ export function mulMat3(a, b) {
9
+ const out = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
10
+ for (let i = 0; i < 3; i++) {
11
+ for (let j = 0; j < 3; j++)
12
+ out[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
13
+ }
14
+ return out;
15
+ }
16
+ export function applyMat3(m, v) {
17
+ return [
18
+ m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2],
19
+ m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2],
20
+ m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2],
21
+ ];
22
+ }
23
+ /** Inverse, or null for a singular basis. */
24
+ export function invertMat3(m) {
25
+ const [[a, b, c], [d, e, f], [g, h, i]] = m;
26
+ const A = e * i - f * h;
27
+ const B = -(d * i - f * g);
28
+ const C = d * h - e * g;
29
+ const det = a * A + b * B + c * C;
30
+ if (!Number.isFinite(det) || Math.abs(det) < 1e-12)
31
+ return null;
32
+ return [
33
+ [A / det, -(b * i - c * h) / det, (b * f - c * e) / det],
34
+ [B / det, (a * i - c * g) / det, -(a * f - c * d) / det],
35
+ [C / det, -(a * h - b * g) / det, (a * e - b * d) / det],
36
+ ];
37
+ }
38
+ /** Godot Basis::from_euler (YXZ order, degrees) times scale: R * S. */
39
+ export function basisFromEulerScale(rotDeg, scale) {
40
+ const [x, y, z] = rotDeg.map((d) => (d * Math.PI) / 180);
41
+ const xm = [[1, 0, 0], [0, Math.cos(x), -Math.sin(x)], [0, Math.sin(x), Math.cos(x)]];
42
+ const ym = [[Math.cos(y), 0, Math.sin(y)], [0, 1, 0], [-Math.sin(y), 0, Math.cos(y)]];
43
+ const zm = [[Math.cos(z), -Math.sin(z), 0], [Math.sin(z), Math.cos(z), 0], [0, 0, 1]];
44
+ const s = [[scale[0], 0, 0], [0, scale[1], 0], [0, 0, scale[2]]];
45
+ return mulMat3(mulMat3(mulMat3(ym, xm), zm), s);
46
+ }
47
+ /** "(1, 2, 3)" / "Vector3(1, 2, 3)" -> [1, 2, 3]. */
48
+ export function parseVec3(value) {
49
+ if (typeof value !== "string")
50
+ return null;
51
+ const match = /^\s*(?:Vector3)?\(\s*([-+0-9.eE]+)\s*,\s*([-+0-9.eE]+)\s*,\s*([-+0-9.eE]+)\s*\)\s*$/.exec(value);
52
+ if (!match)
53
+ return null;
54
+ const out = [Number(match[1]), Number(match[2]), Number(match[3])];
55
+ return out.every(Number.isFinite) ? out : null;
56
+ }
57
+ /** A `Transform3D(12 numbers)` literal -> basis rows + origin. */
58
+ export function parseTransform3D(value) {
59
+ const match = /^\s*Transform3D\(([^)]*)\)\s*$/.exec(value);
60
+ if (!match)
61
+ return null;
62
+ const n = match[1].split(",").map((part) => Number(part.trim()));
63
+ if (n.length !== 12 || !n.every(Number.isFinite))
64
+ return null;
65
+ return {
66
+ basis: [[n[0], n[1], n[2]], [n[3], n[4], n[5]], [n[6], n[7], n[8]]],
67
+ origin: [n[9], n[10], n[11]],
68
+ };
69
+ }
70
+ function num3(value) {
71
+ const rounded = Math.round(value * 1000) / 1000;
72
+ return String(Object.is(rounded, -0) ? 0 : rounded);
73
+ }
74
+ /** Vector3 literal at 3 decimals (for reports). */
75
+ export function vec3Literal(v) {
76
+ return `Vector3(${v.map(num3).join(", ")})`;
77
+ }
78
+ /** Vector3 literal for writing a position back: 12 significant digits
79
+ * (beyond Godot's float32 storage) without binary-arithmetic noise. */
80
+ export function vec3LiteralExact(v) {
81
+ return `Vector3(${v.map((value) => {
82
+ const clean = Number(value.toPrecision(12));
83
+ return String(Object.is(clean, -0) ? 0 : clean);
84
+ }).join(", ")})`;
85
+ }
86
+ export function transformLiteral(basis, origin) {
87
+ return `Transform3D(${[...basis[0], ...basis[1], ...basis[2], ...origin].map(num3).join(", ")})`;
88
+ }
@@ -0,0 +1,62 @@
1
+ import { z } from "zod";
2
+ /** Shared MCP/CLI contract for POST /api/mcp/generate/motion.
3
+ *
4
+ * Two backends are exposed:
5
+ * - meshy-library: curated mocap clip by name on a Summer-rigged humanoid.
6
+ * - text-to-motion: Summer-hosted text-to-motion model; animates any of the
7
+ * caller's own rigged models (5-70 bones) from text prompts.
8
+ * The Studio route also has "hunyuan-custom"; it stays hidden (it returns a
9
+ * generic skeleton that is not retargeted onto the caller's rig). */
10
+ export declare const MOTION_BACKENDS: readonly ["meshy-library", "text-to-motion"];
11
+ export type MotionBackend = (typeof MOTION_BACKENDS)[number];
12
+ export declare const motionGenerationArgsSchema: z.ZodObject<{
13
+ rigAssetId: z.ZodString;
14
+ backend: z.ZodDefault<z.ZodEnum<["meshy-library", "text-to-motion"]>>;
15
+ motionName: z.ZodOptional<z.ZodString>;
16
+ prompt: z.ZodOptional<z.ZodString>;
17
+ prompts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
18
+ takes: z.ZodOptional<z.ZodNumber>;
19
+ lockJoints: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
20
+ cfgScale: z.ZodOptional<z.ZodNumber>;
21
+ idempotencyKey: z.ZodOptional<z.ZodString>;
22
+ wait: z.ZodDefault<z.ZodBoolean>;
23
+ options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
24
+ }, "strip", z.ZodTypeAny, {
25
+ wait: boolean;
26
+ rigAssetId: string;
27
+ backend: "meshy-library" | "text-to-motion";
28
+ options?: Record<string, any> | undefined;
29
+ prompt?: string | undefined;
30
+ motionName?: string | undefined;
31
+ prompts?: string[] | undefined;
32
+ takes?: number | undefined;
33
+ lockJoints?: string[] | undefined;
34
+ cfgScale?: number | undefined;
35
+ idempotencyKey?: string | undefined;
36
+ }, {
37
+ rigAssetId: string;
38
+ options?: Record<string, any> | undefined;
39
+ wait?: boolean | undefined;
40
+ prompt?: string | undefined;
41
+ backend?: "meshy-library" | "text-to-motion" | undefined;
42
+ motionName?: string | undefined;
43
+ prompts?: string[] | undefined;
44
+ takes?: number | undefined;
45
+ lockJoints?: string[] | undefined;
46
+ cfgScale?: number | undefined;
47
+ idempotencyKey?: string | undefined;
48
+ }>;
49
+ export type MotionGenerationArgs = z.input<typeof motionGenerationArgsSchema>;
50
+ /** Validate the backend-specific rules zod cannot express on a flat shape and
51
+ * build the request body. Returns an error message instead of throwing so
52
+ * each face renders it its own way. */
53
+ export declare function buildMotionRequestBody(args: MotionGenerationArgs): {
54
+ body: Record<string, unknown>;
55
+ } | {
56
+ error: string;
57
+ };
58
+ /** Actionable hint for a server error code, if we know one. */
59
+ export declare function motionErrorHint(code: unknown): string | undefined;
60
+ /** Hint for a failed text-to-motion job ("text_motion: ..." failures are input
61
+ * problems and the charge is refunded). */
62
+ export declare function motionJobFailureHint(message: unknown): string | undefined;