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,425 @@
1
+ /**
2
+ * surface-snap-mesh — the visible-mesh measurement behind
3
+ * `summer_snap_to_surface` when colliders cannot answer.
4
+ *
5
+ * The engine's SnapToSurface sweeps the subject's colliders against body
6
+ * colliders. When the subject or the support has no collider it falls back to
7
+ * visual_aabb: the subject's visible AABB swept against the AABB of every
8
+ * other visible geometry in the scene. One large AABB anywhere around the
9
+ * subject (a tree, a building block, a full-screen post quad whose mesh
10
+ * carries a huge custom AABB) then counts as an overlap that no back-off
11
+ * clears: collider-less ferns on a ground PlaneMesh all failed with
12
+ * overlap_recovery_exceeded, "starts in contact with or inside (unnamed)".
13
+ *
14
+ * This probe measures the same move from triangles instead. It is one
15
+ * read-only GDScript sent through RunSceneScript (undo "none", no
16
+ * checkpoint), with its arguments as base64 data, never source:
17
+ *
18
+ * - the subject's visible mesh triangles in scene space; its vertices are
19
+ * cast along the direction, each from the subject's top plane (the
20
+ * subject's extreme against the direction) above it, onto the
21
+ * triangles of every other visible mesh whose bounds meet the swept
22
+ * column. A surface between that plane and the vertex means the subject
23
+ * is sunk into it (negative travel);
24
+ * - the support's vertices inside the subject's footprint are cast back
25
+ * against the subject's triangles, for support peaks between subject
26
+ * vertices;
27
+ * - travel = the smallest of those distances; the new local position is
28
+ * the current one plus (travel - gap) along the direction, mapped
29
+ * through the parent's transform.
30
+ *
31
+ * Meshes whose shader writes POSITION (screen-space quads) and non-mesh
32
+ * geometry (CSG, MultiMesh, sprites) are skipped and counted. It reads the
33
+ * scene only; the mutation is an ordinary SetProp + SaveScene sent by
34
+ * surface-snap.ts.
35
+ */
36
+ import { missingEngineOpResult } from "../capability-skew.js";
37
+ import { asRecord } from "../util/json.js";
38
+ import { extractOpError } from "./engine-receipt.js";
39
+ import { encodeScriptArgs } from "./placement-script.js";
40
+ import { buildRunSceneScriptOp } from "./scene-script.js";
41
+ export const SNAP_MESH_ARGS_TOKEN = "__SUMMER_SNAP_MESH_ARGS__";
42
+ /** Measure the visible-mesh snap from the subject's current pose. */
43
+ export async function measureMeshSnap(client, args) {
44
+ if (missingEngineOpResult(client, "RunSceneScript", "")) {
45
+ return { ok: false, failure_reason: "engine_lacks_op", error: "this engine build has no RunSceneScript, so the visible-mesh measurement cannot run" };
46
+ }
47
+ const { op, timeoutMs } = buildRunSceneScriptOp({
48
+ source: buildSnapMeshScript({
49
+ scene_path: args.scenePath,
50
+ subject: args.subjectPath,
51
+ direction: args.direction,
52
+ max_distance: args.maxDistance,
53
+ gap: args.gap,
54
+ }),
55
+ max_seconds: 30,
56
+ checkpoint: false,
57
+ undo: "none",
58
+ });
59
+ let receipt;
60
+ try {
61
+ receipt = await client.executeIdentityBoundOps([op], undefined, timeoutMs);
62
+ }
63
+ catch (err) {
64
+ return { ok: false, failure_reason: "mesh_probe_failed", error: `the visible-mesh probe failed: ${err instanceof Error ? err.message : String(err)}` };
65
+ }
66
+ const results = asRecord(receipt)?.results;
67
+ const entry = asRecord(Array.isArray(results) ? results.find((r) => asRecord(r)?.op === "RunSceneScript") ?? results[0] : undefined);
68
+ const envelopeError = extractOpError(receipt);
69
+ if (!entry || entry.ok === false || envelopeError) {
70
+ return { ok: false, failure_reason: "mesh_probe_failed", error: `the visible-mesh probe (RunSceneScript) failed: ${String(entry?.error ?? envelopeError ?? "no result")}` };
71
+ }
72
+ const result = asRecord(entry.result);
73
+ if (!result)
74
+ return { ok: false, failure_reason: "mesh_probe_failed", error: "the visible-mesh probe ran but returned no result" };
75
+ if (result.ok !== true) {
76
+ return {
77
+ ok: false,
78
+ failure_reason: typeof result.failure_reason === "string" ? result.failure_reason : "mesh_probe_failed",
79
+ error: typeof result.error === "string" ? result.error : "the visible-mesh probe reported a failure",
80
+ };
81
+ }
82
+ return result;
83
+ }
84
+ export function buildSnapMeshScript(args) {
85
+ return SNAP_MESH_PROBE_SOURCE.split(SNAP_MESH_ARGS_TOKEN).join(`"${encodeScriptArgs(args)}"`);
86
+ }
87
+ /** The probe source with its placeholder, for tests. */
88
+ export function snapMeshProbeTemplate() {
89
+ return SNAP_MESH_PROBE_SOURCE;
90
+ }
91
+ // Tabs are significant: GDScript indentation. String.raw keeps backslashes
92
+ // literal; the source never contains a template placeholder.
93
+ const SNAP_MESH_PROBE_SOURCE = String.raw `@tool
94
+ extends RefCounted
95
+
96
+ const ARGS_B64 = __SUMMER_SNAP_MESH_ARGS__
97
+ const MAX_NODES = 60000
98
+ const MAX_SUPPORT_TRIS = 400000
99
+ const MAX_SUBJECT_SAMPLES = 6000
100
+ const MAX_REVERSE_VERTS = 150000
101
+ const EPS = 0.0001
102
+
103
+
104
+ func run(_ctx):
105
+ var args = JSON.parse_string(Marshalls.base64_to_utf8(ARGS_B64))
106
+ if typeof(args) != TYPE_DICTIONARY:
107
+ return _fail("bad_args", "snap probe arguments did not parse")
108
+ var scene = _open_scene(String(args.get("scene_path", "")))
109
+ if scene.has("fail"):
110
+ return scene["fail"]
111
+ var root = scene["root"]
112
+ var subject = _node(root, String(args.get("subject", "")))
113
+ if subject == null:
114
+ return _fail("node_not_found", "subject not found: " + String(args.get("subject", "")))
115
+ if not (subject is Node3D) or subject == root:
116
+ return _fail("not_snappable", "the subject must be a Node3D below the scene root")
117
+ var dv = _vec(args.get("direction", [0, -1, 0]))
118
+ if dv.length() < 0.000001:
119
+ return _fail("bad_args", "direction must be non-zero")
120
+ var d = dv.normalized()
121
+ var max_distance = float(args.get("max_distance", 20.0))
122
+ var gap = float(args.get("gap", 0.0))
123
+ var skipped = {"screen_space": 0, "not_mesh": 0}
124
+ var sub_faces = PackedVector3Array()
125
+ for it in _mesh_items(subject, root, null, skipped):
126
+ sub_faces.append_array(it[1] * it[0].mesh.get_faces())
127
+ if sub_faces.size() < 3:
128
+ return _fail("no_subject_mesh", "the subject has no visible mesh triangles to measure")
129
+ # The subject's unique vertices, its extent along d and its bounds.
130
+ var uniq = {}
131
+ var verts = []
132
+ var lo = INF
133
+ var hi = -INF
134
+ var bb = AABB(sub_faces[0], Vector3.ZERO)
135
+ for p in sub_faces:
136
+ var key = Vector3i(roundi(p.x * 10000.0), roundi(p.y * 10000.0), roundi(p.z * 10000.0))
137
+ if uniq.has(key):
138
+ continue
139
+ uniq[key] = true
140
+ verts.append(p)
141
+ var s = p.dot(d)
142
+ lo = minf(lo, s)
143
+ hi = maxf(hi, s)
144
+ bb = bb.expand(p)
145
+ var u = d.cross(Vector3.UP if absf(d.y) < 0.9 else Vector3.RIGHT).normalized()
146
+ var v = d.cross(u).normalized()
147
+ var umin = INF
148
+ var umax = -INF
149
+ var vmin = INF
150
+ var vmax = -INF
151
+ for p in verts:
152
+ umin = minf(umin, p.dot(u))
153
+ umax = maxf(umax, p.dot(u))
154
+ vmin = minf(vmin, p.dot(v))
155
+ vmax = maxf(vmax, p.dot(v))
156
+ # Visible meshes outside the subject whose bounds meet the swept column.
157
+ var column = bb.merge(AABB(bb.position + d * max_distance, bb.size)).grow(0.001)
158
+ var sup_faces = PackedVector3Array()
159
+ var ranges = []
160
+ var tris = 0
161
+ for it in _mesh_items(root, root, subject, skipped):
162
+ var wb = it[1] * it[0].get_aabb()
163
+ if not column.intersects(wb.grow(0.001)):
164
+ continue
165
+ var faces = it[1] * it[0].mesh.get_faces()
166
+ if faces.size() < 3:
167
+ continue
168
+ tris += floori(faces.size() / 3.0)
169
+ if tris > MAX_SUPPORT_TRIS:
170
+ return _fail("mesh_budget_exceeded", "the meshes around the subject have more than " + str(MAX_SUPPORT_TRIS) + " triangles; the visible-mesh measurement stops rather than miss a surface")
171
+ sup_faces.append_array(faces)
172
+ ranges.append([tris, it[0]])
173
+ var stats = {"samples": 0, "subject_vertices": verts.size(), "support_meshes": ranges.size(), "support_triangles": tris, "extent": hi - lo, "skipped": skipped, "subject_colliders": _count_colliders(subject)}
174
+ if tris == 0:
175
+ return _done(stats, false)
176
+ var tm = TriangleMesh.new()
177
+ if not tm.create_from_faces(sup_faces):
178
+ return _fail("mesh_build_failed", "could not build a triangle tree from the support meshes")
179
+ # Subject samples: every vertex up to the cap, the leading band first.
180
+ var samples = verts
181
+ if verts.size() > MAX_SUBJECT_SAMPLES:
182
+ samples = []
183
+ var edge = hi - maxf(0.01, (hi - lo) * 0.1)
184
+ var lead = []
185
+ var rest = []
186
+ for p in verts:
187
+ if p.dot(d) >= edge:
188
+ lead.append(p)
189
+ else:
190
+ rest.append(p)
191
+ var half = floori(MAX_SUBJECT_SAMPLES * 0.5)
192
+ var lstep = maxi(1, ceili(lead.size() / float(half)))
193
+ for i in range(0, lead.size(), lstep):
194
+ samples.append(lead[i])
195
+ var room = maxi(1, MAX_SUBJECT_SAMPLES - samples.size())
196
+ var rstep = maxi(1, ceili(rest.size() / float(room)))
197
+ for i in range(0, rest.size(), rstep):
198
+ samples.append(rest[i])
199
+ stats["samples"] = samples.size()
200
+ var best = INF
201
+ var best_hit = {}
202
+ # Subject vertices cast along d, each from the subject's top plane above it.
203
+ for p in samples:
204
+ var back = p.dot(d) - lo + EPS
205
+ var begin = p - d * back
206
+ var hit = tm.intersect_ray(begin, d)
207
+ if hit.is_empty():
208
+ continue
209
+ var travel = (hit["position"] - begin).dot(d) - back
210
+ if travel < best:
211
+ best = travel
212
+ best_hit = {"point": hit["position"], "normal": hit["normal"], "face": int(hit["face_index"]), "from": "subject_vertex"}
213
+ # Support vertices inside the footprint cast back onto the subject.
214
+ var stm = TriangleMesh.new()
215
+ if stm.create_from_faces(sub_faces):
216
+ var checked = 0
217
+ for i in range(sup_faces.size()):
218
+ var q = sup_faces[i]
219
+ var sq = q.dot(d)
220
+ if sq < lo or sq > hi + max_distance:
221
+ continue
222
+ var qu = q.dot(u)
223
+ var qv = q.dot(v)
224
+ if qu < umin or qu > umax or qv < vmin or qv > vmax:
225
+ continue
226
+ checked += 1
227
+ if checked > MAX_REVERSE_VERTS:
228
+ stats["reverse_partial"] = true
229
+ break
230
+ var down = maxf(0.0, hi - sq) + EPS
231
+ var begin = q + d * down
232
+ var hit = stm.intersect_ray(begin, -d)
233
+ if hit.is_empty():
234
+ continue
235
+ var travel = (begin - hit["position"]).dot(d) - down
236
+ if travel < best:
237
+ best = travel
238
+ best_hit = {"point": q, "normal": -hit["normal"], "face": floori(i / 3.0), "from": "support_vertex"}
239
+ if best_hit.is_empty() or best > max_distance:
240
+ return _done(stats, false)
241
+ var shift = best - gap
242
+ var world_delta = d * shift
243
+ var parent_basis = Basis.IDENTITY
244
+ if not subject.top_level and subject.get_parent() != null:
245
+ parent_basis = _xf(subject.get_parent(), root).basis
246
+ if absf(parent_basis.determinant()) < 0.0000001:
247
+ return _fail("singular_parent", "the subject's parent transform is singular")
248
+ var after = subject.position + parent_basis.inverse() * world_delta
249
+ var support = _support_of(ranges, int(best_hit["face"]))
250
+ var origin = _xf(subject, root).origin
251
+ stats["travel"] = best
252
+ stats["shift"] = shift
253
+ stats["support"] = _rel(root, support) if support != null else ""
254
+ stats["support_has_collider"] = _has_collider(support, root)
255
+ stats["hit_point"] = _raw3(best_hit["point"])
256
+ stats["hit_normal"] = _raw3(Vector3(best_hit["normal"]).normalized())
257
+ stats["contact_from"] = best_hit["from"]
258
+ stats["position"] = var_to_str(subject.position)
259
+ stats["position_after"] = var_to_str(after)
260
+ stats["origin_before"] = _raw3(origin)
261
+ stats["origin_after"] = _raw3(origin + world_delta)
262
+ return _done(stats, true)
263
+
264
+
265
+ func _done(stats, found):
266
+ var out = {"ok": true, "found": found}
267
+ for k in stats:
268
+ out[k] = stats[k]
269
+ return out
270
+
271
+
272
+ func _fail(reason, message):
273
+ return {"ok": false, "failure_reason": reason, "error": message}
274
+
275
+
276
+ func _vec(a):
277
+ return Vector3(float(a[0]), float(a[1]), float(a[2]))
278
+
279
+
280
+ func _raw3(v):
281
+ return [v.x, v.y, v.z]
282
+
283
+
284
+ func _open_scene(scene_path):
285
+ var wanted = scene_path.simplify_path()
286
+ for r in EditorInterface.get_open_scene_roots():
287
+ if r != null and String(r.scene_file_path).simplify_path() == wanted:
288
+ return {"root": r}
289
+ return {"fail": _fail("scene_not_open", "Scene " + wanted + " is not open in the editor")}
290
+
291
+
292
+ func _node(root, path):
293
+ var p = String(path).strip_edges()
294
+ if p == "" or p == "." or p == "./":
295
+ return root
296
+ if p.begins_with("./"):
297
+ p = p.substr(2)
298
+ var n = root.get_node_or_null(NodePath(p))
299
+ if n == null and p.begins_with(String(root.name) + "/"):
300
+ n = root.get_node_or_null(NodePath(p.substr(String(root.name).length() + 1)))
301
+ return n
302
+
303
+
304
+ func _rel(root, n):
305
+ if n == root:
306
+ return "."
307
+ return String(root.get_path_to(n))
308
+
309
+
310
+ # Scene-space transform: Node3D.transform accumulated up to and including root.
311
+ func _xf(node, root):
312
+ var t = Transform3D.IDENTITY
313
+ var cur = node
314
+ while cur != null:
315
+ if cur is Node3D:
316
+ t = cur.transform * t
317
+ if cur.top_level and cur != root:
318
+ break
319
+ if cur == root:
320
+ break
321
+ cur = cur.get_parent()
322
+ return t
323
+
324
+
325
+ func _visible(node, root):
326
+ var cur = node
327
+ while cur != null:
328
+ if cur is Node3D and not cur.visible:
329
+ return false
330
+ if cur == root:
331
+ break
332
+ cur = cur.get_parent()
333
+ return true
334
+
335
+
336
+ # Visible MeshInstance3D nodes under start (inclusive) with their scene-space
337
+ # transform; exclude is a subtree root to skip.
338
+ func _mesh_items(start, root, exclude, skipped):
339
+ var base_xf = Transform3D.IDENTITY
340
+ var base_vis = true
341
+ if start != root and start.get_parent() != null:
342
+ base_xf = _xf(start.get_parent(), root)
343
+ base_vis = _visible(start.get_parent(), root)
344
+ var out = []
345
+ var stack = [[start, base_xf, base_vis]]
346
+ var visited = 0
347
+ while stack.size() > 0:
348
+ visited += 1
349
+ if visited > MAX_NODES:
350
+ skipped["node_budget"] = true
351
+ break
352
+ var item = stack.pop_back()
353
+ var n = item[0]
354
+ if exclude != null and n == exclude:
355
+ continue
356
+ var t = item[1]
357
+ var vis = item[2]
358
+ if n is Node3D:
359
+ if n.top_level and n != root:
360
+ t = n.transform
361
+ else:
362
+ t = t * n.transform
363
+ vis = vis and n.visible
364
+ if vis and n is GeometryInstance3D:
365
+ if n is MeshInstance3D:
366
+ if n.mesh != null:
367
+ if _screen_space(n):
368
+ skipped["screen_space"] += 1
369
+ else:
370
+ out.append([n, t])
371
+ else:
372
+ skipped["not_mesh"] += 1
373
+ for c in n.get_children():
374
+ stack.append([c, t, vis])
375
+ return out
376
+
377
+
378
+ # A mesh whose shader writes POSITION is drawn in screen space (a post quad):
379
+ # its triangles are not where the scene shows anything.
380
+ func _screen_space(mi):
381
+ var mats = []
382
+ if mi.material_override != null:
383
+ mats.append(mi.material_override)
384
+ for s in range(mi.mesh.get_surface_count()):
385
+ var m = mi.get_active_material(s)
386
+ if m != null:
387
+ mats.append(m)
388
+ for m in mats:
389
+ if m is ShaderMaterial and m.shader != null:
390
+ var code = String(m.shader.code)
391
+ if code.contains("POSITION") and code.contains("vertex"):
392
+ return true
393
+ return false
394
+
395
+
396
+ func _support_of(ranges, face):
397
+ for r in ranges:
398
+ if face < int(r[0]):
399
+ return r[1]
400
+ return null
401
+
402
+
403
+ func _count_colliders(node):
404
+ var count = 0
405
+ var stack = [node]
406
+ while stack.size() > 0:
407
+ var n = stack.pop_back()
408
+ if (n is CollisionShape3D or n is CollisionPolygon3D) and not n.disabled and n.get_parent() is CollisionObject3D:
409
+ count += 1
410
+ for c in n.get_children():
411
+ stack.append(c)
412
+ return count
413
+
414
+
415
+ # The support mesh sits in a collision body, or carries one below it.
416
+ func _has_collider(node, root):
417
+ if node == null:
418
+ return false
419
+ var cur = node
420
+ while cur != null and cur != root:
421
+ if cur is CollisionObject3D:
422
+ return true
423
+ cur = cur.get_parent()
424
+ return _count_colliders(node) > 0
425
+ `;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * surface-snap — ONE implementation of `summer_snap_to_surface` for both faces
3
+ * (src/mcp/tools/spatial-tools.ts and tool-dispatch.ts), around the engine's
4
+ * SnapToSurface op (modules/1summer_engine/editor/ops/surface_snap_ops.cpp).
5
+ *
6
+ * Two gaps in the engine op, closed here with ops main already ships:
7
+ *
8
+ * 1. Its two recovery failures say nothing about WHY. gap_exceeds_hit_travel
9
+ * and overlap_recovery_exceeded name neither the node in the way nor
10
+ * whether the subject started out overlapping. After either failure a
11
+ * read-only Starcast3D at the subject's current pose names the contacts,
12
+ * the start-overlap state and what is below, and the failure gains a
13
+ * concrete next_step.
14
+ *
15
+ * 2. It cannot lift a prop SUNK into its support. When the start pose
16
+ * overlaps, the engine backs the subject off against the cast direction,
17
+ * sweeps, and measures hitTravel from the ORIGINAL pose — negative for a
18
+ * sunk prop — then refuses any gap above it ("would move opposite the
19
+ * verified sweep"), although the backed-off sweep did verify that space
20
+ * (_solve_physics compares p_gap with hit_travel instead of with the swept
21
+ * distance from the backed-off start). So on gap_exceeds_hit_travel with a
22
+ * start overlap this module lifts the subject against the cast direction
23
+ * by the overlap depth plus a margin (exact local position from the saved
24
+ * scene), snaps again from there, and keeps the result only when it
25
+ * settles back on a node the subject was sunk into. Otherwise the original
26
+ * position is restored and the failure is reported.
27
+ *
28
+ * 3. Without a collider on the subject or the support it falls back to
29
+ * visual_aabb: AABBs swept against AABBs. One big AABB around the subject
30
+ * (a tree, a building block, a post quad with a huge custom AABB) is an
31
+ * overlap no back-off clears, so collider-less props on a PlaneMesh failed
32
+ * with overlap_recovery_exceeded, and a success can rest on an AABB above
33
+ * the real surface. Whenever the engine answers with visual_aabb evidence
34
+ * (overlap_recovery_exceeded, gap_exceeds_hit_travel, surface_not_found,
35
+ * or a seat), a read-only probe measures the move from visible triangles
36
+ * instead (surface-snap-mesh.ts), one SetProp places the subject, a second
37
+ * read verifies the gap and SaveScene saves it: evidence visual_mesh.
38
+ */
39
+ import { type CapabilityAdvertisingClient } from "../capability-skew.js";
40
+ import { type JsonRecord } from "../util/json.js";
41
+ import { type Vec3 } from "./math3d.js";
42
+ /** Clearance added above the support before the second sweep. */
43
+ export declare const SNAP_LIFT_MARGIN = 0.02;
44
+ /** Never lift further than this automatically (a deeper overlap is a placement mistake to report). */
45
+ export declare const SNAP_MAX_AUTO_LIFT = 0.5;
46
+ export interface SnapToSurfaceArgs {
47
+ scenePath: string;
48
+ subjectPath: string;
49
+ direction: Vec3;
50
+ maxDistance: number;
51
+ gap: number;
52
+ alignUp: boolean;
53
+ }
54
+ export interface SnapClient extends CapabilityAdvertisingClient {
55
+ executeIdentityBoundOps(ops: Record<string, unknown>[], options?: Record<string, unknown>, timeoutMs?: number): Promise<unknown>;
56
+ readProjectFile(path: string, maxBytes?: number): Promise<unknown>;
57
+ }
58
+ /** A visible-mesh gap this close to the requested one needs no move. */
59
+ export declare const MESH_SNAP_TOLERANCE = 0.001;
60
+ /** The verify read must find the requested gap within this, or the move is undone. */
61
+ export declare const MESH_SNAP_VERIFY_TOLERANCE = 0.005;
62
+ export declare function buildSnapToSurfaceOp(args: SnapToSurfaceArgs): JsonRecord;
63
+ export interface SnapDiagnosis {
64
+ available: boolean;
65
+ /** true / false from the starcast contact state; null when it could not run. */
66
+ startOverlap: boolean | null;
67
+ contacts: string[];
68
+ below?: {
69
+ status?: unknown;
70
+ object?: unknown;
71
+ distance?: unknown;
72
+ };
73
+ /** World AABB size of the subject. */
74
+ size?: Vec3;
75
+ note?: string;
76
+ }
77
+ export declare function snapToSurface(client: SnapClient, args: SnapToSurfaceArgs): Promise<unknown>;