summer-engine 3.0.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 (413) 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 +120 -0
  8. package/README.md +22 -7
  9. package/assets/audit/scene_audit.gd +4136 -0
  10. package/assets/seeing/seeing_probe.gd +1873 -0
  11. package/dist/cli/commands/setup.js +6 -19
  12. package/dist/cli/commands/skills.js +57 -32
  13. package/dist/core/api-client.d.ts +9 -1
  14. package/dist/core/api-client.js +21 -4
  15. package/dist/core/capabilities/agent-playbook.js +46 -0
  16. package/dist/core/capabilities/audit/accept.d.ts +55 -0
  17. package/dist/core/capabilities/audit/accept.js +147 -0
  18. package/dist/core/capabilities/audit/args.d.ts +95 -0
  19. package/dist/core/capabilities/audit/args.js +89 -0
  20. package/dist/core/capabilities/audit/audit.d.ts +56 -0
  21. package/dist/core/capabilities/audit/audit.js +287 -0
  22. package/dist/core/capabilities/audit/frame.d.ts +14 -0
  23. package/dist/core/capabilities/audit/frame.js +35 -0
  24. package/dist/core/capabilities/audit/gaps.d.ts +96 -0
  25. package/dist/core/capabilities/audit/gaps.js +257 -0
  26. package/dist/core/capabilities/audit/judge.d.ts +162 -0
  27. package/dist/core/capabilities/audit/judge.js +1134 -0
  28. package/dist/core/capabilities/audit/math.d.ts +110 -0
  29. package/dist/core/capabilities/audit/math.js +263 -0
  30. package/dist/core/capabilities/audit/summary.d.ts +74 -0
  31. package/dist/core/capabilities/audit/summary.js +212 -0
  32. package/dist/core/capabilities/board.d.ts +31 -0
  33. package/dist/core/capabilities/board.js +43 -0
  34. package/dist/core/capabilities/camera-view.d.ts +4 -2
  35. package/dist/core/capabilities/camera-view.js +6 -3
  36. package/dist/core/capabilities/connect-signal.d.ts +85 -0
  37. package/dist/core/capabilities/connect-signal.js +285 -0
  38. package/dist/core/capabilities/engine-fallbacks.d.ts +5 -0
  39. package/dist/core/capabilities/engine-fallbacks.js +5 -0
  40. package/dist/core/capabilities/engine-ops.d.ts +5 -1
  41. package/dist/core/capabilities/engine-ops.js +0 -3
  42. package/dist/core/capabilities/engine-receipt.d.ts +12 -0
  43. package/dist/core/capabilities/engine-receipt.js +26 -0
  44. package/dist/core/capabilities/file-read.d.ts +64 -0
  45. package/dist/core/capabilities/file-read.js +325 -0
  46. package/dist/core/capabilities/game-task-plan.js +4 -2
  47. package/dist/core/capabilities/grep.d.ts +60 -0
  48. package/dist/core/capabilities/grep.js +190 -0
  49. package/dist/core/capabilities/inspect-node.d.ts +56 -0
  50. package/dist/core/capabilities/inspect-node.js +225 -0
  51. package/dist/core/capabilities/inspect-resource.d.ts +61 -0
  52. package/dist/core/capabilities/inspect-resource.js +376 -0
  53. package/dist/core/capabilities/math3d.d.ts +28 -0
  54. package/dist/core/capabilities/math3d.js +88 -0
  55. package/dist/core/capabilities/motion-generation.d.ts +62 -0
  56. package/dist/core/capabilities/motion-generation.js +138 -0
  57. package/dist/core/capabilities/placement-batch.d.ts +102 -0
  58. package/dist/core/capabilities/placement-batch.js +483 -0
  59. package/dist/core/capabilities/placement-math.d.ts +70 -0
  60. package/dist/core/capabilities/placement-math.js +209 -0
  61. package/dist/core/capabilities/placement-script.d.ts +42 -0
  62. package/dist/core/capabilities/placement-script.js +1096 -0
  63. package/dist/core/capabilities/placement.d.ts +485 -0
  64. package/dist/core/capabilities/placement.js +1731 -0
  65. package/dist/core/capabilities/project-context.d.ts +33 -2
  66. package/dist/core/capabilities/project-context.js +87 -4
  67. package/dist/core/capabilities/replace-node.d.ts +91 -0
  68. package/dist/core/capabilities/replace-node.js +423 -0
  69. package/dist/core/capabilities/runtime-control.d.ts +20 -4
  70. package/dist/core/capabilities/runtime-control.js +67 -2
  71. package/dist/core/capabilities/scene-batch.d.ts +63 -0
  72. package/dist/core/capabilities/scene-batch.js +394 -0
  73. package/dist/core/capabilities/scene-readback.d.ts +36 -0
  74. package/dist/core/capabilities/scene-readback.js +54 -0
  75. package/dist/core/capabilities/seeing/args.d.ts +348 -0
  76. package/dist/core/capabilities/seeing/args.js +178 -0
  77. package/dist/core/capabilities/seeing/candidates.d.ts +127 -0
  78. package/dist/core/capabilities/seeing/candidates.js +282 -0
  79. package/dist/core/capabilities/seeing/math.d.ts +134 -0
  80. package/dist/core/capabilities/seeing/math.js +269 -0
  81. package/dist/core/capabilities/seeing/probe.d.ts +62 -0
  82. package/dist/core/capabilities/seeing/probe.js +188 -0
  83. package/dist/core/capabilities/seeing/scoring.d.ts +235 -0
  84. package/dist/core/capabilities/seeing/scoring.js +639 -0
  85. package/dist/core/capabilities/seeing/seeing.d.ts +233 -0
  86. package/dist/core/capabilities/seeing/seeing.js +1341 -0
  87. package/dist/core/capabilities/seeing/shot-store.d.ts +52 -0
  88. package/dist/core/capabilities/seeing/shot-store.js +204 -0
  89. package/dist/core/capabilities/surface-snap-mesh.d.ts +88 -0
  90. package/dist/core/capabilities/surface-snap-mesh.js +425 -0
  91. package/dist/core/capabilities/surface-snap.d.ts +77 -0
  92. package/dist/core/capabilities/surface-snap.js +461 -0
  93. package/dist/core/capabilities/tool-dispatch.js +231 -72
  94. package/dist/core/capabilities/tscn.d.ts +85 -0
  95. package/dist/core/capabilities/tscn.js +391 -0
  96. package/dist/core/capabilities/world-snapshot.d.ts +58 -0
  97. package/dist/core/capabilities/world-snapshot.js +150 -0
  98. package/dist/core/capability-skew.d.ts +5 -5
  99. package/dist/core/capability-skew.js +14 -6
  100. package/dist/core/headless/worker-engine-client.d.ts +1 -1
  101. package/dist/core/headless/worker-engine-client.js +2 -2
  102. package/dist/core/library-read.d.ts +37 -5
  103. package/dist/core/library-read.js +264 -33
  104. package/dist/core/library-search.d.ts +2 -2
  105. package/dist/core/skills-registry.d.ts +9 -1
  106. package/dist/core/skills-registry.js +25 -2
  107. package/dist/installer/agent-config.d.ts +9 -4
  108. package/dist/installer/agent-config.js +194 -392
  109. package/dist/installer/agent-table.d.ts +119 -0
  110. package/dist/installer/agent-table.js +619 -0
  111. package/dist/installer/setup.js +4 -2
  112. package/dist/installer/skill-locations.d.ts +8 -17
  113. package/dist/installer/skill-locations.js +22 -101
  114. package/dist/installer/version-check.d.ts +5 -1
  115. package/dist/installer/version-check.js +38 -28
  116. package/dist/mcp/server.js +9 -3
  117. package/dist/mcp/tools/asset-tools.js +21 -3
  118. package/dist/mcp/tools/audit-tools.d.ts +23 -0
  119. package/dist/mcp/tools/audit-tools.js +60 -0
  120. package/dist/mcp/tools/debug-tools.js +3 -1
  121. package/dist/mcp/tools/file-tools.js +17 -4
  122. package/dist/mcp/tools/generate-tools.js +74 -66
  123. package/dist/mcp/tools/library-tools.js +2 -0
  124. package/dist/mcp/tools/perception-tools.js +6 -19
  125. package/dist/mcp/tools/placement-tools.d.ts +24 -0
  126. package/dist/mcp/tools/placement-tools.js +91 -0
  127. package/dist/mcp/tools/project-tools.js +18 -15
  128. package/dist/mcp/tools/scene-tools.js +71 -83
  129. package/dist/mcp/tools/seeing-tools.d.ts +24 -0
  130. package/dist/mcp/tools/seeing-tools.js +64 -0
  131. package/dist/mcp/tools/spatial-tools.js +17 -9
  132. package/dist/mcp/tools/visual-tools.js +59 -7
  133. package/gemini-extension.json +26 -4
  134. package/integrations/README.md +48 -19
  135. package/integrations/amp/README.md +12 -0
  136. package/integrations/amp/manifest-target.json +3 -0
  137. package/integrations/antigravity/README.md +12 -0
  138. package/integrations/antigravity/manifest-target.json +3 -0
  139. package/integrations/claude-desktop/README.md +12 -0
  140. package/integrations/claude-desktop/manifest-target.json +3 -0
  141. package/integrations/cline/README.md +8 -9
  142. package/integrations/cline-cli/README.md +12 -0
  143. package/integrations/cline-cli/manifest-target.json +3 -0
  144. package/integrations/copilot-jetbrains/README.md +12 -0
  145. package/integrations/copilot-jetbrains/manifest-target.json +3 -0
  146. package/integrations/crush/README.md +12 -0
  147. package/integrations/crush/manifest-target.json +3 -0
  148. package/integrations/github-copilot/README.md +8 -8
  149. package/integrations/goose/README.md +12 -0
  150. package/integrations/goose/manifest-target.json +3 -0
  151. package/integrations/grok-build/README.md +12 -0
  152. package/integrations/grok-build/manifest-target.json +3 -0
  153. package/integrations/hermes/README.md +12 -0
  154. package/integrations/hermes/manifest-target.json +3 -0
  155. package/integrations/junie/README.md +12 -0
  156. package/integrations/junie/manifest-target.json +3 -0
  157. package/integrations/kilo-code/README.md +6 -10
  158. package/integrations/kimi-code/README.md +12 -0
  159. package/integrations/kimi-code/manifest-target.json +3 -0
  160. package/integrations/kiro/README.md +12 -0
  161. package/integrations/kiro/manifest-target.json +3 -0
  162. package/integrations/lm-studio/README.md +8 -8
  163. package/integrations/mistral-vibe/README.md +12 -0
  164. package/integrations/mistral-vibe/manifest-target.json +3 -0
  165. package/integrations/opencode/README.md +9 -12
  166. package/integrations/qoder/README.md +12 -0
  167. package/integrations/qoder/manifest-target.json +3 -0
  168. package/integrations/qwen-code/README.md +12 -0
  169. package/integrations/qwen-code/manifest-target.json +3 -0
  170. package/integrations/roo-code/README.md +8 -7
  171. package/integrations/rovo-dev/README.md +12 -0
  172. package/integrations/rovo-dev/manifest-target.json +3 -0
  173. package/integrations/trae/README.md +12 -0
  174. package/integrations/trae/manifest-target.json +3 -0
  175. package/integrations/visual-studio/README.md +12 -0
  176. package/integrations/visual-studio/manifest-target.json +3 -0
  177. package/integrations/vscode-copilot/README.md +9 -9
  178. package/integrations/warp/README.md +12 -0
  179. package/integrations/warp/manifest-target.json +3 -0
  180. package/integrations/windsurf/README.md +8 -9
  181. package/integrations/zed/README.md +12 -0
  182. package/integrations/zed/manifest-target.json +3 -0
  183. package/library/references/mcp-tools-reference/mcp-tools-reference.md +59 -15
  184. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  185. package/library/references/summer-folder/resource.yaml +1 -1
  186. package/library/references/summer-folder/summer-folder.md +1 -1
  187. package/library/skills/3d-lighting/SKILL.md +1 -1
  188. package/library/skills/README.md +264 -0
  189. package/library/skills/adaptive-music/SKILL.md +1 -1
  190. package/library/skills/agent-playtesting/SKILL.md +1 -1
  191. package/library/skills/ai-characters-in-games/SKILL.md +220 -0
  192. package/library/skills/ai-characters-in-games/resource.yaml +30 -0
  193. package/library/skills/ambient-bed/SKILL.md +1 -1
  194. package/library/skills/animated-loop/SKILL.md +1 -1
  195. package/library/skills/animation-tree/SKILL.md +1 -1
  196. package/library/skills/art-direction/SKILL.md +1 -1
  197. package/library/skills/asset-strategy/SKILL.md +2 -1
  198. package/library/skills/asset-strategy/resource.yaml +2 -1
  199. package/library/skills/audio-direction/SKILL.md +1 -1
  200. package/library/skills/auto-fire-targeting/SKILL.md +1 -1
  201. package/library/skills/brainstorm-game/SKILL.md +1 -1
  202. package/library/skills/brainstorming/SKILL.md +1 -1
  203. package/library/skills/browse-templates/SKILL.md +3 -3
  204. package/library/skills/browse-templates/resource.yaml +1 -1
  205. package/library/skills/camera-rigs/SKILL.md +128 -0
  206. package/library/skills/camera-rigs/resource.yaml +29 -0
  207. package/library/skills/celeste-momentum-platforming/SKILL.md +1 -1
  208. package/library/skills/character-animation-wiring/SKILL.md +1 -1
  209. package/library/skills/character-model/SKILL.md +1 -1
  210. package/library/skills/character-movement/SKILL.md +326 -0
  211. package/library/skills/character-movement/references/default-third-person-controller.gd +201 -0
  212. package/library/skills/character-movement/references/default-third-person-verification-probe.gd +154 -0
  213. package/library/skills/character-movement/references/movement-3d.md +136 -0
  214. package/library/skills/character-movement/references/platformer-feel.md +83 -0
  215. package/library/skills/character-movement/resource.yaml +40 -0
  216. package/library/skills/character-portrait/SKILL.md +1 -1
  217. package/library/skills/cinematic-cutscene/SKILL.md +1 -1
  218. package/library/skills/combat-basics/SKILL.md +159 -0
  219. package/library/skills/combat-basics/references/projectiles-and-aoe.md +100 -0
  220. package/library/skills/combat-basics/resource.yaml +34 -0
  221. package/library/skills/concept-art/SKILL.md +1 -1
  222. package/library/skills/create-asset-sheet/SKILL.md +1 -1
  223. package/library/skills/debug/SKILL.md +1 -1
  224. package/library/skills/debugging-game-feel/SKILL.md +1 -1
  225. package/library/skills/design-level/SKILL.md +1 -1
  226. package/library/skills/design-mechanic/SKILL.md +1 -1
  227. package/library/skills/design-npc/SKILL.md +1 -1
  228. package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
  229. package/library/skills/dispatching-parallel-agents/SKILL.md +1 -1
  230. package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
  231. package/library/skills/environment-kit/SKILL.md +1 -1
  232. package/library/skills/export-and-ship/SKILL.md +1 -1
  233. package/library/skills/fabricating-assets/SKILL.md +1 -1
  234. package/library/skills/facial-and-lipsync/SKILL.md +1 -1
  235. package/library/skills/fps-controller/SKILL.md +9 -7
  236. package/library/skills/fps-controller/resource.yaml +4 -1
  237. package/library/skills/game-feel/SKILL.md +1 -1
  238. package/library/skills/gameskill/SKILL.md +1 -1
  239. package/library/skills/gdscript-patterns/SKILL.md +1 -1
  240. package/library/skills/generate-motion/SKILL.md +9 -9
  241. package/library/skills/generate-motion/resource.yaml +2 -1
  242. package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
  243. package/library/skills/headless-scripting/SKILL.md +1 -1
  244. package/library/skills/in-game-purchases/SKILL.md +254 -0
  245. package/library/skills/in-game-purchases/resource.yaml +29 -0
  246. package/library/skills/instantiate-asset-pack/SKILL.md +1 -1
  247. package/library/skills/investigating-bugs/SKILL.md +1 -1
  248. package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +1 -1
  249. package/library/skills/make-game/SKILL.md +25 -3
  250. package/library/skills/make-game/references/2d-platformer-polish.md +93 -0
  251. package/library/skills/make-game/references/2d-platformer.md +117 -0
  252. package/library/skills/make-game/references/2d-rpg-content.md +234 -0
  253. package/library/skills/make-game/references/2d-rpg.md +241 -0
  254. package/library/skills/make-game/references/2d-survivors-progression.md +201 -0
  255. package/library/skills/make-game/references/2d-survivors.md +237 -0
  256. package/library/skills/make-game/references/3d-fps-systems.md +216 -0
  257. package/library/skills/make-game/references/3d-fps.md +177 -0
  258. package/library/skills/make-game/references/3d-horror-systems.md +186 -0
  259. package/library/skills/make-game/references/3d-horror.md +201 -0
  260. package/library/skills/make-game/references/3d-third-person-systems.md +220 -0
  261. package/library/skills/make-game/references/3d-third-person.md +215 -0
  262. package/library/skills/make-game/resource.yaml +6 -1
  263. package/library/skills/multiplayer/SKILL.md +150 -0
  264. package/library/skills/multiplayer/resource.yaml +33 -0
  265. package/library/skills/multiplayer-movement/SKILL.md +510 -0
  266. package/library/skills/multiplayer-movement/files.md +501 -0
  267. package/library/skills/multiplayer-movement/resource.yaml +30 -0
  268. package/library/skills/multiplayer-project/SKILL.md +521 -0
  269. package/library/skills/multiplayer-project/files.md +448 -0
  270. package/library/skills/multiplayer-project/resource.yaml +36 -0
  271. package/library/skills/multiplayer-publish/SKILL.md +229 -0
  272. package/library/skills/multiplayer-publish/export-errors.md +89 -0
  273. package/library/skills/multiplayer-publish/resource.yaml +28 -0
  274. package/library/skills/multiplayer-state/SKILL.md +438 -0
  275. package/library/skills/multiplayer-state/files.md +592 -0
  276. package/library/skills/multiplayer-state/resource.yaml +35 -0
  277. package/library/skills/multiplayer-testing/SKILL.md +236 -0
  278. package/library/skills/multiplayer-testing/resource.yaml +39 -0
  279. package/library/skills/music-track/SKILL.md +1 -1
  280. package/library/skills/navigate-summer/SKILL.md +1 -1
  281. package/library/skills/new-project/SKILL.md +1 -1
  282. package/library/skills/organic-model/SKILL.md +1 -1
  283. package/library/skills/pixel-art/SKILL.md +1 -1
  284. package/library/skills/play/SKILL.md +1 -1
  285. package/library/skills/playtesting-a-feature/SKILL.md +1 -1
  286. package/library/skills/procedural-animation/SKILL.md +2 -2
  287. package/library/skills/procedural-animation/resource.yaml +1 -1
  288. package/library/skills/prop-model/SKILL.md +1 -1
  289. package/library/skills/psx-retro-rendering/SKILL.md +1 -1
  290. package/library/skills/realtime-wet-surfaces/SKILL.md +2 -2
  291. package/library/skills/remote-deploy/SKILL.md +1 -1
  292. package/library/skills/retarget/SKILL.md +1 -1
  293. package/library/skills/running-in-the-cloud/SKILL.md +1 -1
  294. package/library/skills/save-load/SKILL.md +156 -0
  295. package/library/skills/save-load/resource.yaml +27 -0
  296. package/library/skills/scene-composition/SKILL.md +1 -1
  297. package/library/skills/scene-hierarchy-design/SKILL.md +1 -1
  298. package/library/skills/scene-scripting/SKILL.md +1 -1
  299. package/library/skills/scene-to-level/SKILL.md +1 -1
  300. package/library/skills/skill-create/SKILL.md +1 -1
  301. package/library/skills/skill-improve/SKILL.md +1 -1
  302. package/library/skills/skill-test/SKILL.md +1 -1
  303. package/library/skills/skintokens-auto-rigging/SKILL.md +1 -1
  304. package/library/skills/skybox-panorama/SKILL.md +1 -1
  305. package/library/skills/sound-effect/SKILL.md +1 -1
  306. package/library/skills/spatial-placement/SKILL.md +134 -3
  307. package/library/skills/spatial-placement/references/kit-placement-tools.md +364 -0
  308. package/library/skills/spatial-placement/resource.yaml +16 -2
  309. package/library/skills/sprite-sheet/SKILL.md +1 -1
  310. package/library/skills/summer-analytics/SKILL.md +147 -0
  311. package/library/skills/summer-analytics/resource.yaml +28 -0
  312. package/library/skills/summer-friends/SKILL.md +226 -0
  313. package/library/skills/summer-friends/resource.yaml +28 -0
  314. package/library/skills/summer-leaderboards/SKILL.md +231 -0
  315. package/library/skills/summer-leaderboards/resource.yaml +30 -0
  316. package/library/skills/summer-match-results/SKILL.md +286 -0
  317. package/library/skills/summer-match-results/resource.yaml +32 -0
  318. package/library/skills/summer-matchmaking/SKILL.md +301 -0
  319. package/library/skills/summer-matchmaking/resource.yaml +32 -0
  320. package/library/skills/summer-parties/SKILL.md +253 -0
  321. package/library/skills/summer-parties/resource.yaml +30 -0
  322. package/library/skills/summer-player-data/SKILL.md +322 -0
  323. package/library/skills/summer-player-data/resource.yaml +30 -0
  324. package/library/skills/summer-store/SKILL.md +271 -0
  325. package/library/skills/summer-store/resource.yaml +29 -0
  326. package/library/skills/summer-world-chat/SKILL.md +195 -0
  327. package/library/skills/summer-world-chat/resource.yaml +30 -0
  328. package/library/skills/summer-world-saves/SKILL.md +284 -0
  329. package/library/skills/summer-world-saves/resource.yaml +29 -0
  330. package/library/skills/text-to-motion/SKILL.md +99 -0
  331. package/library/skills/text-to-motion/prompts-and-controls.md +34 -0
  332. package/library/skills/text-to-motion/resource.yaml +41 -0
  333. package/library/skills/text-to-motion/rigging-for-text-motion.md +54 -0
  334. package/library/skills/tileable-texture/SKILL.md +1 -1
  335. package/library/skills/trailer-shot/SKILL.md +1 -1
  336. package/library/skills/tune-performance/SKILL.md +1 -1
  337. package/library/skills/ui-basics/SKILL.md +10 -1
  338. package/library/skills/ui-graphics/SKILL.md +1 -1
  339. package/library/skills/use-widget-asset/SKILL.md +1 -1
  340. package/library/skills/using-summer/SKILL.md +2 -2
  341. package/library/skills/using-summer/resource.yaml +2 -2
  342. package/library/skills/vehicle-model/SKILL.md +1 -1
  343. package/library/skills/verification-before-completion/SKILL.md +1 -1
  344. package/library/skills/verifying-scenes/SKILL.md +76 -2
  345. package/library/skills/verifying-scenes/resource.yaml +13 -2
  346. package/library/skills/vfx-dissolve/SKILL.md +1 -1
  347. package/library/skills/vfx-fire/SKILL.md +1 -1
  348. package/library/skills/vfx-hit-spark/SKILL.md +1 -1
  349. package/library/skills/vfx-lightning/SKILL.md +1 -1
  350. package/library/skills/vfx-magic-glow/SKILL.md +1 -1
  351. package/library/skills/vfx-muzzle-flash/SKILL.md +1 -1
  352. package/library/skills/vfx-smoke/SKILL.md +1 -1
  353. package/library/skills/vfx-water-ripple/SKILL.md +1 -1
  354. package/library/skills/voice-line/SKILL.md +1 -1
  355. package/library/skills/web-and-touch-input/SKILL.md +38 -0
  356. package/library/skills/web-and-touch-input/resource.yaml +28 -0
  357. package/library/skills/web-compatibility-look/SKILL.md +62 -0
  358. package/library/skills/web-compatibility-look/resource.yaml +30 -0
  359. package/library/skills/world-building-3d/SKILL.md +8 -1
  360. package/library/skills/world-building-3d/references/spatial-tools.md +1 -1
  361. package/library/skills/world-building-3d/resource.yaml +2 -1
  362. package/library/skills/writing-plans/SKILL.md +1 -1
  363. package/library/skills/writing-skills/SKILL.md +1 -1
  364. package/library/templates/3d-lan-multiplayer-starter/resource.yaml +2 -2
  365. package/library/tools/attach-to-surface/resource.yaml +142 -0
  366. package/library/tools/batch/resource.yaml +9 -3
  367. package/library/tools/connect-ports/resource.yaml +120 -0
  368. package/library/tools/connect-signal/resource.yaml +3 -2
  369. package/library/tools/debug-views/resource.yaml +94 -0
  370. package/library/tools/frame-nodes/resource.yaml +104 -0
  371. package/library/tools/frame-shot/resource.yaml +134 -0
  372. package/library/tools/generate-motion/resource.yaml +44 -9
  373. package/library/tools/get-board/resource.yaml +50 -0
  374. package/library/tools/get-project-context/resource.yaml +13 -2
  375. package/library/tools/grep/resource.yaml +77 -0
  376. package/library/tools/inspect-asset/resource.yaml +71 -0
  377. package/library/tools/inspect-node/resource.yaml +9 -2
  378. package/library/tools/inspect-resource/resource.yaml +16 -5
  379. package/library/tools/instantiate-scene/resource.yaml +27 -2
  380. package/library/tools/measure/resource.yaml +96 -0
  381. package/library/tools/place-adjacent/resource.yaml +113 -0
  382. package/library/tools/play/resource.yaml +15 -2
  383. package/library/tools/raycast/resource.yaml +101 -0
  384. package/library/tools/read-file/resource.yaml +36 -2
  385. package/library/tools/read-library/resource.yaml +2 -2
  386. package/library/tools/repeat-along/resource.yaml +129 -0
  387. package/library/tools/replace-node/resource.yaml +11 -5
  388. package/library/tools/scene-audit/resource.yaml +144 -0
  389. package/library/tools/screenshot/resource.yaml +13 -2
  390. package/library/tools/search-assets/resource.yaml +18 -0
  391. package/library/tools/shot-sheet/resource.yaml +110 -0
  392. package/library/tools/snap-to-surface/resource.yaml +4 -1
  393. package/library/tools/world-snapshot/resource.yaml +24 -3
  394. package/library/tools/zoom/resource.yaml +105 -0
  395. package/package.json +3 -3
  396. package/registry/generated/aliases.json +17 -3
  397. package/registry/generated/counts.json +3 -3
  398. package/registry/generated/gemini-extension.json +26 -4
  399. package/registry/generated/index.json +2154 -469
  400. package/registry/generated/marketplace.claude.json +2 -2
  401. package/registry/generated/plugin.claude.json +27 -5
  402. package/registry/generated/plugin.codex.json +28 -6
  403. package/registry/generated/plugin.cursor.json +27 -5
  404. package/registry/generated/plugin.factory.json +27 -5
  405. package/registry/generated/skills-index.md +264 -0
  406. package/registry/generated/skills-registry.json +901 -206
  407. package/registry/generated/templates-registry.json +2 -2
  408. package/library/skills/host-authoritative-state/SKILL.md +0 -332
  409. package/library/skills/host-authoritative-state/resource.yaml +0 -28
  410. package/library/skills/peer-to-peer-multiplayer/SKILL.md +0 -373
  411. package/library/skills/peer-to-peer-multiplayer/resource.yaml +0 -28
  412. package/library/skills/setup-multiplayer/SKILL.md +0 -336
  413. package/library/skills/setup-multiplayer/resource.yaml +0 -28
@@ -1,5 +1,7 @@
1
1
  import { z } from "zod";
2
+ import { BOARD_ENDPOINT, boardArgsSchema, boardContent, boardQuery } from "../../core/capabilities/board.js";
2
3
  import { imageGenerationArgsSchema } from "../../core/capabilities/image-generation.js";
4
+ import { buildMotionRequestBody, motionErrorHint, motionGenerationArgsSchema, motionJobFailureHint, } from "../../core/capabilities/motion-generation.js";
3
5
  import { writeFile, mkdir } from "fs/promises";
4
6
  import { tmpdir } from "os";
5
7
  import { join } from "path";
@@ -16,6 +18,7 @@ const TOOL_BY_ENDPOINT = {
16
18
  "/api/mcp/generate/motion": "summer_generate_motion",
17
19
  "/api/mcp/generate/slice-asset-sheet": "summer_slice_asset_sheet",
18
20
  "/api/mcp/workflows": "summer_get_studio_workflow",
21
+ [BOARD_ENDPOINT]: "summer_get_board",
19
22
  };
20
23
  // ---------------------------------------------------------------------------
21
24
  // Shared helpers
@@ -253,6 +256,26 @@ handoff that MCP cannot perform automatically; do not pretend that stage ran.`,
253
256
  return successResult(result.data);
254
257
  });
255
258
  // ========================================================================
259
+ // summer_get_board
260
+ // ========================================================================
261
+ server.tool("summer_get_board", `Read the person's approved planning board for this game: the look (palette,
262
+ description, picture), the characters, the place, the first-minute storyboard
263
+ and the cards they picked, with a version that changes when the board does.
264
+
265
+ The look and the picked cards come back as images you can see. Read the board at
266
+ the start of each build step and compare your screenshot against its images
267
+ (palette, shapes and proportions, camera angle, composition); fix the biggest
268
+ difference. Use the picked card pictures as referenceImageUrl for
269
+ summer_generate_image to make sprites and backgrounds in the same look.
270
+
271
+ Cloud tool — runs on Summer's servers and works WITHOUT the Summer Engine app open.
272
+ Requires authentication: run 'npx -y summer-engine@latest login' first.`, boardArgsSchema.shape, async (args) => {
273
+ const result = await mcpGet(BOARD_ENDPOINT, boardQuery(args), 45_000);
274
+ if (result.error)
275
+ return errorResult(result.error, result.data);
276
+ return { content: boardContent(result.data ?? {}) };
277
+ });
278
+ // ========================================================================
256
279
  // summer_generate_image
257
280
  // ========================================================================
258
281
  server.tool("summer_generate_image", `Generate an image using AI models via Summer Engine Studio.
@@ -651,89 +674,74 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
651
674
  // ========================================================================
652
675
  // summer_generate_motion
653
676
  //
654
- // NOTE (2026-05-10): only the "meshy-library" backend is exposed today.
655
- // The "hunyuan-custom" path exists in the Studio route but has not been
656
- // tested end-to-end on a user's rig (Hunyuan returns a generic skeleton
657
- // FBX that isn't retargeted onto the caller's character). The schema and
658
- // call are kept commented-out below — re-enable by restoring the wider
659
- // zod enum, the prompt/durationSeconds params, the validation branch, and
660
- // the relevant description lines once the path is verified.
677
+ // Backends exposed: "meshy-library" (curated humanoid mocap by name) and
678
+ // "text-to-motion" (Summer-hosted model, any of the caller's own rigs, from
679
+ // text prompts; default-off on the server until enabled, which answers 400
680
+ // backend_unavailable). The Studio route's "hunyuan-custom" stays hidden: it
681
+ // returns a generic skeleton FBX that is not retargeted onto the caller's
682
+ // rig. The shared zod shape + body builder live in
683
+ // core/capabilities/motion-generation.ts so `summer tool generate-motion`
684
+ // validates identically.
661
685
  // ========================================================================
662
- server.tool("summer_generate_motion", `Generate an animation clip for a Meshy-rigged humanoid character via Summer Engine Studio.
663
-
664
- Backend:
665
- - "meshy-library" — picks a clip from a curated mocap set by name (idle, walk,
666
- run, attack_sword, jump, ~70 standard names). Fast (~30s), cheap (~$0.10),
667
- real mocap quality.
686
+ server.tool("summer_generate_motion", `Generate animation clips for a rigged 3D model via Summer Engine Studio.
687
+
688
+ Backends (pick one):
689
+ - "meshy-library" (default) — a curated mocap clip by motionName on a
690
+ Summer-rigged humanoid (rigAssetId from summer_generate_3d with
691
+ options.rig=true). Fast (~30s), cheap (~$0.10), real mocap quality.
692
+ Names that always work: idle, walk, run, jump, attack; anything else must
693
+ be an exact library name.
694
+ - "text-to-motion" — custom 2-second clips (60 frames) from text prompts on
695
+ ANY of your own rigged models: humanoid, animal, creature, cartoon plant,
696
+ prop (GLB/FBX 3d_model, one skinned armature, 5-70 bones). Use it for
697
+ actions the library lacks (nod, bow, shrug, wave with the right arm) and
698
+ for non-humanoid rigs. Pass prompt or prompts (1-8), optional takes (1-4),
699
+ cfgScale (1.5-8, default 3; 5 for clearer gestures), and lockJoints for
700
+ rooted characters (e.g. ["Hips","Spine"] on a plant; never on characters
701
+ that walk). Human-style bone names (Hips, Spine, LeftArm...) animate far
702
+ better, even on non-humans. Jobs take ~1-2 min; result.assets lists one
703
+ animation asset per prompt x take.
704
+
705
+ Each clip (meshy: each motion; text-to-motion: each prompt x take) is billed.
706
+ State the clip list and estimated cost and confirm with the user before
707
+ spending.
668
708
 
669
- Requires a Meshy-rigged humanoid as the target. The 'rigAssetId' must come from
670
- a prior summer_generate_3d call with options.rig=true.
671
-
672
- By default, waits for completion (up to 5 min) and returns the result directly.
673
- Set wait=false to get the jobId immediately and poll manually with summer_check_job.
674
-
675
- Common motion names:
676
- Locomotion: idle, idle_alert, idle_combat, walk, walk_back, run, sprint,
677
- crouch_idle, crouch_walk, jump, jump_loop, jump_land
678
- Combat: attack_sword, attack_punch, attack_kick, attack_bow, attack_cast,
679
- block, dodge_left, dodge_right, hit_react, death
680
- Social: wave, dance, sit_idle
681
-
682
- Cost: ~$0.10 per clip. Confirm with user before spending.
709
+ By default, waits for completion (up to 10 min) and returns the result directly.
710
+ Set wait=false to get the jobId immediately and poll with summer_check_job.
711
+ Import finished clips with summer_import_asset_by_id.
683
712
 
684
- Custom prompt-driven motion is on the roadmap; not yet shipped. For one-off
685
- signature moves not on the curated list, fall back to hand-authoring in the
686
- Summer Engine or importing from Mixamo.
713
+ Errors: backend_unavailable means text-to-motion is not enabled on this server
714
+ yet — use meshy-library for humanoids and do not retry. Job failures starting
715
+ "text_motion:" (no skinned armature, too many/few joints, unknown joint) are
716
+ input problems and are refunded; fix the rig or request instead of retrying.
687
717
 
688
718
  Cloud tool — runs on Summer's servers and works WITHOUT the Summer Engine app open.
689
- Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
690
- rigAssetId: z
691
- .string()
692
- .describe("Asset ID of a rigged character (from summer_generate_3d with options.rig=true)"),
693
- backend: z
694
- .enum(["meshy-library"])
695
- .default("meshy-library")
696
- .describe("Backend: meshy-library (only option today)"),
697
- motionName: z
698
- .string()
699
- .describe("Curated motion name: walk, run, attack_sword, idle, jump, etc."),
700
- // prompt + durationSeconds reserved for the hunyuan-custom backend (not
701
- // shipped yet — see header comment).
702
- wait: z
703
- .boolean()
704
- .default(true)
705
- .describe("Wait for completion (default true, up to 5 min). Set false to get jobId immediately."),
706
- options: z
707
- .record(z.any())
708
- .optional()
709
- .describe("Backend-specific passthrough"),
710
- }, async ({ rigAssetId, backend, motionName, wait, options }) => {
711
- // Client-side validation
712
- if (!motionName) {
713
- return errorResult("motionName is required (e.g. 'walk', 'run', 'attack_sword'). See the tool description for the curated list.");
719
+ Requires authentication: run 'npx -y summer-engine@latest login' first.`, motionGenerationArgsSchema.shape, async (args) => {
720
+ // Client-side validation of the backend-specific rules.
721
+ const built = buildMotionRequestBody(args);
722
+ if ("error" in built) {
723
+ return errorResult(built.error);
714
724
  }
715
- const body = {
716
- rigAssetId,
717
- backend,
718
- motionName,
719
- options,
720
- };
721
- const result = await mcpGenerate("/api/mcp/generate/motion", body);
725
+ const result = await mcpGenerate("/api/mcp/generate/motion", built.body);
722
726
  if (result.error) {
723
- return errorResult(result.error, result.data);
727
+ const hint = motionErrorHint(result.data?.error);
728
+ return errorResult(result.error, hint ? { ...result.data, hint } : result.data);
724
729
  }
725
730
  const jobId = result.data?.jobId;
726
- if (!wait || !jobId) {
731
+ if (!args.wait || !jobId) {
727
732
  return successResult(result.data);
728
733
  }
729
734
  const pollResult = await pollJob(jobId);
730
735
  if (pollResult.error) {
731
- return errorResult(pollResult.error, { ...pollResult.data, jobId });
736
+ const hint = motionJobFailureHint(pollResult.error);
737
+ return errorResult(pollResult.error, { ...pollResult.data, jobId, ...(hint ? { hint } : {}) });
732
738
  }
733
739
  return successResult({
734
740
  ...pollResult.data,
735
741
  jobId,
736
- message: "Motion generation complete. animationAssetId is in result.",
742
+ message: args.backend === "text-to-motion"
743
+ ? "Motion generation complete. result.assets lists one animation asset per prompt x take; import with summer_import_asset_by_id."
744
+ : "Motion generation complete. animationAssetId is in result.",
737
745
  });
738
746
  });
739
747
  }
@@ -15,6 +15,8 @@ export const READ_LIBRARY_DESCRIPTION = "Load one library entry by id (<kind>/<s
15
15
  "Skills: the SKILL.md body plus metadata (status, use_when, related) and how to invoke the skill in your host (bare slug). " +
16
16
  "Tools: how to call it (MCP name, `summer tool <slug> --args`, engine requirement, authority) plus the descriptor. " +
17
17
  "Templates: the pinned repo @ commit and tree digest (or built-in) and the `summer create <slug>` command. References: the markdown body. " +
18
+ "Linked files: a body ends with its relative links and the id that loads each; a file an entry links loads by <entry id>/<link as written> " +
19
+ "(e.g. skill/spatial-placement/references/kit-placement-tools.md), by the relative path alone when one entry ships it, inside library/ only. " +
18
20
  "part: 'skill' = body only, 'resource' = the resource.yaml descriptor only, 'all' (default) = both. " +
19
21
  "The LAST line of every load is the feedback footer `— entry_id: <id>@<content-hash>. If this entry is wrong, stale, or you deviate from it, report via summer_library_feedback.` " +
20
22
  "— copy that entry_id verbatim into summer_library_feedback once you have verified the outcome in-engine. " +
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import { withEngine, missingEngineOpResult, withOldEngineHint } from "./with-engine.js";
3
3
  // engine_lacks_op fallbacks: ONE copy for every face (E2E 2026-09-03 F-16).
4
4
  import { RUNTIME_NODE_FALLBACK, RUNTIME_TREE_FALLBACK, SNAPSHOT_DIFF_FALLBACK, WORLD_SNAPSHOT_FALLBACK, } from "../../core/capabilities/engine-fallbacks.js";
5
+ import { WORLD_SNAPSHOT_DEFAULT_MAX_NODES, buildWorldSnapshotOp, shapeWorldSnapshot, worldSnapshotInputShape, } from "../../core/capabilities/world-snapshot.js";
5
6
  /**
6
7
  * Perception tools. Two signals, two jobs: these ops return STRUCTURED state —
7
8
  * exact node paths, transforms, world AABBs, counts — while summer_screenshot
@@ -40,28 +41,14 @@ export function registerPerceptionTools(server) {
40
41
 
41
42
  THE LOOP: summer_world_snapshot (note snapshot_id) -> mutate (summer_run_script / scene tools / imports) -> summer_snapshot_diff from_id:<that id> -> summer_screenshot. The diff proves exactly what changed structurally; the screenshot proves it looks right. This is how you catch a node that silently vanished on save, a transform that landed at the origin, or an AABB clipping through the floor.
42
43
 
43
- Node lists are path-sorted and truncated DETERMINISTICALLY (result carries total_nodes + truncated) so two snapshots stay diffable without phantom adds/removes. The engine retains the last 8 snapshots per session, keyed by snapshot_id. Use this instead of summer_get_scene_tree when you need transforms/AABBs/fingerprints or a diffable baseline; the tree read remains the hierarchy-shaped view. On an engine build that predates GetWorldSnapshot the result is a structured engine_lacks_op failure naming the fallback.`, {
44
- scene_path: z
45
- .string()
46
- .optional()
47
- .describe("Scene to snapshot, e.g. 'res://main.tscn'. Omit for the currently edited scene."),
48
- max_nodes: z
49
- .number()
50
- .int()
51
- .positive()
52
- .optional()
53
- .describe("Node cap (engine default 4000). The result declares truncation — never assume a capped list is complete."),
54
- }, async ({ scene_path, max_nodes }) => withEngine(async (client) => {
44
+ Node lists are path-sorted and truncated DETERMINISTICALLY (result carries total_nodes + truncated) so two snapshots stay diffable without phantom adds/removes. The engine retains the last 8 snapshots per session, keyed by snapshot_id. Use this instead of summer_get_scene_tree when you need transforms/AABBs/fingerprints or a diffable baseline; the tree read remains the hierarchy-shaped view. On an engine build that predates GetWorldSnapshot the result is a structured engine_lacks_op failure naming the fallback.
45
+
46
+ KEEP IT SMALL (about 250 bytes per node): at most ${WORLD_SNAPSHOT_DEFAULT_MAX_NODES} nodes are listed by default. path_prefix reads one subtree ('House3', 'Lane2/Props'), classes keeps some node classes, fields keeps some per-node fields (e.g. ['pos','aabb']), offset/next_offset page the list. A filtered read adds matched_nodes and matched_counts (class counts of the subtree). counts and total_nodes always describe the whole scene, and snapshot_id always covers the whole scene, so summer_snapshot_diff still sees every change.`, worldSnapshotInputShape, async (args) => withEngine(async (client) => {
55
47
  const missing = missingEngineOpResult(client, "GetWorldSnapshot", WORLD_SNAPSHOT_FALLBACK);
56
48
  if (missing)
57
49
  return missing;
58
- const op = { op: "GetWorldSnapshot" };
59
- if (scene_path)
60
- op.scene_path = scene_path;
61
- if (max_nodes !== undefined)
62
- op.max_nodes = max_nodes;
63
- const result = await client.executeOps([op]);
64
- return withFailureReasonHint(withOldEngineHint(result, "GetWorldSnapshot", WORLD_SNAPSHOT_FALLBACK), {
50
+ const result = await client.executeOps([buildWorldSnapshotOp(args)]);
51
+ return withFailureReasonHint(withOldEngineHint(shapeWorldSnapshot(result, args), "GetWorldSnapshot", WORLD_SNAPSHOT_FALLBACK), {
65
52
  no_scene: "No scene is open to snapshot. Call summer_get_project_context, then summer_open_main_scene (or summer_open_scene with a known .tscn path), then retry.",
66
53
  scene_not_loaded: "scene_path resolves only a LIVE editor tab or an already-cached scene — never a disk load. Open that scene first (summer_open_scene), or omit scene_path to snapshot the currently edited scene.",
67
54
  });
@@ -0,0 +1,24 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type PlacementClient, type PlacementResult } from "../../core/capabilities/placement.js";
3
+ type Content = {
4
+ type: "text";
5
+ text: string;
6
+ };
7
+ export declare function renderPlacementResult(body: PlacementResult | Record<string, unknown>): {
8
+ content: Content[];
9
+ isError?: true;
10
+ };
11
+ /** withEngine wrapper that renders the placement result verbatim. */
12
+ export declare function runPlacement<T>(run: (client: PlacementClient, args: T) => Promise<PlacementResult>): (args: T) => Promise<{
13
+ content: ({
14
+ type: "text";
15
+ text: string;
16
+ } | {
17
+ type: "image";
18
+ data: string;
19
+ mimeType: string;
20
+ })[];
21
+ isError?: boolean;
22
+ }>;
23
+ export declare function registerPlacementTools(server: McpServer): void;
24
+ export {};
@@ -0,0 +1,91 @@
1
+ import { withEngine } from "./with-engine.js";
2
+ import { attachToSurface, attachToSurfaceArgsSchema, connectPorts, connectPortsArgsSchema, inspectAsset, inspectAssetArgsSchema, measure, measureArgsSchema, placeAdjacent, placeAdjacentArgsSchema, raycast, raycastArgsSchema, repeatAlong, repeatAlongArgsSchema, } from "../../core/capabilities/placement.js";
3
+ /**
4
+ * Kit-placement tools: measure an asset before instancing it, place pieces
5
+ * relative to each other, mount them on surfaces, repeat them along a line,
6
+ * join ports, and query the scene with arbitrary rays and per-axis measures.
7
+ *
8
+ * The implementations live in core/capabilities/placement.ts (shared with
9
+ * `summer tool <slug>`). They use only existing engine ops: the placement
10
+ * probe runs through RunSceneScript (read-only, undo "none", no checkpoint)
11
+ * and mutations are SetProp / SnapToSurface / InstantiateScene with the usual
12
+ * scene target, undo step and final SaveScene.
13
+ *
14
+ * Results are rendered here, not by withEngine's failure renderer: a placement
15
+ * failure carries structured fields (failure_reason, what already applied,
16
+ * the measured hit) that a plain error string would drop.
17
+ */
18
+ const RESULT_LIMIT_BYTES = 5 * 1024;
19
+ export function renderPlacementResult(body) {
20
+ let text = JSON.stringify(body);
21
+ if (Buffer.byteLength(text, "utf8") > RESULT_LIMIT_BYTES) {
22
+ text = JSON.stringify({
23
+ ok: false,
24
+ tool: body.tool,
25
+ failure_reason: "result_exceeded_byte_limit",
26
+ error: "The placement result was larger than 5 KB and was not forwarded. Narrow the request (fewer nodes or copies).",
27
+ ...(body.ok === true ? { mutationApplied: body.saved === true, retrySafe: false } : {}),
28
+ });
29
+ return { content: [{ type: "text", text }], isError: true };
30
+ }
31
+ return body.ok === true ? { content: [{ type: "text", text }] } : { content: [{ type: "text", text }], isError: true };
32
+ }
33
+ /** withEngine wrapper that renders the placement result verbatim. */
34
+ export function runPlacement(run) {
35
+ return async (args) => withEngine(async (client) => ({ placementResult: await run(client, args) }), {
36
+ onResult: (wrapped) => renderPlacementResult(wrapped.placementResult),
37
+ });
38
+ }
39
+ export function registerPlacementTools(server) {
40
+ server.tool("summer_inspect_asset", `Measure a 3D asset file (.tscn/.scn/.glb/.gltf, or a Mesh resource) WITHOUT adding it to any scene: it is loaded and instanced off-scene in the editor, measured, and freed. Call it once per kit piece before placing it, instead of guessing size, origin or facing.
41
+
42
+ Returns (all in the asset root's own frame, the frame position/rotation apply in), the facing evidence first:
43
+ - summary {aabb, origin {fraction, label e.g. "x:center y:min z:min"}, plane_pairs, port_like_loops [loop ids], triangles, mesh_count, anchor_count, collision_count, warnings?}. plane_pairs: the 2 largest pairs of opposite planes (a pair under 1% of the largest one's area is left out), each {larger, opposite (null for a single sheet), separation}; every plane {axis (e.g. "+z", only when the normal is within about 1 degree of it), normal, offset, area, one_sided}. one_sided true = its material culls back faces, so the plane is invisible from behind its normal: a single sheet that is one_sided faces along its normal and its back is the opposite axis. An oblique normal (no axis) means a baked yaw or a 45-degree corner face. warnings says when the triangle budget cut the analysis and which maxTriangles covers the whole mesh
44
+ - aabb, origin, meshes [{path, tris, min, max}], triangles total
45
+ - planes: the 6 largest planar face groups {normal, offset, area, tris, cull_back, one_sided}; normals follow the triangle winding (outward faces). You decide the front; the tool does not label facing
46
+ - open_loops: open boundary loops {id, index, mesh, center, direction (outward), radius, vertices, max_dev} in a stable order: grouped by the piece axis the direction is nearest (+X, -X, +Y, -Y, +Z, -Z; ~X/~Y/~Z when undecided), the outermost along that axis first, then by centre; never by radius. id names the loop by that order: "+Y" is the outermost loop facing +Y, "+Y#2" the next. summer_connect_ports accepts the id (or the index); the same id names the same loop on the placed node in any pose. detail "summary" (default) lists only port-like loops (radius over 2 cm with a partner loop facing more than 60 degrees away: the ends of a pipe, duct or bend; or the one opening of an end piece, such as an outlet's socket, on its bounding-box face) and says how many it omitted; detail "full" lists every loop, including the outline of flat sheets
47
+ - anchors: Marker3D nodes {name, path, position, forward (-Z), up}
48
+ - collision: CollisionShape3D nodes {path, shape, size/radius/height/faces, center, min, max}
49
+ - analysis {triangles_analyzed, triangle_budget, truncated}; a "truncated" object when a list was cut to fit 5 KB
50
+
51
+ maxTriangles 100-300000 (default 60000). Evidence is mesh_triangles. Uses the existing RunSceneScript op (in the live editor, read-only); an engine without it answers engine_lacks_op.`, inspectAssetArgsSchema.shape, runPlacement(inspectAsset));
52
+ server.tool("summer_place_adjacent", `Move one node so its bounds face sits against another node's bounds face along one axis: facade modules edge to edge, a storey stacked on the one below, a cornice on a wall. Optionally line up the other two axes (min, center or max), per axis.
53
+
54
+ Example: next module to the right, same base height, same front plane: {axis:"x", side:"max", gap:0, alignOtherAxes:{y:"min", z:"max"}}.
55
+
56
+ Bounds are the visible GeometryInstance3D AABBs (the definition summer_align_distribute_3d uses; evidence visual_aabb). space "local" uses the reference's own axes for rotated facades. When the subject is inside the reference, its geometry is left out of the reference's bounds. One SetProp on position, one undo step, then the scene is saved; a fresh read verifies the achieved gap and residuals (verify). Returns {moved_by, position, verify:{gap, residuals}}. The scene must be open in the editor (any tab).`, placeAdjacentArgsSchema.shape, runPlacement(placeAdjacent));
57
+ server.tool("summer_attach_to_surface", `Mount a piece on a surface: turn it so its given LOCAL backAxis faces into the surface (opposite the hit normal) with its upAxis kept toward worldUp, then seat its measured back face (the extreme of its visible bounds along backAxis, not its origin) at standoff from the surface. Pipes, gutters, lamps, AC units, signs, fire escapes. Place the piece near its mount first (summer_instantiate_scene with position); this tool turns it and pushes it onto the surface.
58
+
59
+ Find the surface with surface (a node: the ray runs from the subject's origin to the nearest point of that node's bounds) or ray {origin, direction} (both: the ray, and hits on other nodes are skipped). The ray is physics first; if physics finds nothing it falls back to visual AABBs and says so (the normal is then an AABB face normal). Get backAxis from summer_inspect_asset (the piece's back plane normal), not from a guess.
60
+
61
+ placeAt "current" (default): the piece keeps its height and its place along the surface and only moves along the surface normal. placeAt "hit": it also slides so the centre of its back face lands on the ray hit point.
62
+
63
+ Steps (existing ops): a read-only probe (RunSceneScript) reads the piece's bounds in its own axes and casts the ray; one SetProp turns the piece and puts its back face 5 cm in front of the planned seat; SnapToSurface sweeps it along -normal (at most standoff + 0.3) and seats it at standoff (its own physics/visual_aabb evidence). Before saving, the seat is checked:
64
+ - with surface: the seat must be on that node (or inside it), else it is refused;
65
+ - with a ray only: a seat on another node is refused unless it lies on the hit plane (a coplanar neighbour module, warned);
66
+ - the piece must end within maxMove (default 2) of where it started; a longer planned move is refused before anything changes, and so is (with placeAt "current") a ray hit farther than maxMove along the surface from the piece (hit_far_from_piece: aim at the piece, or pass placeAt "hit").
67
+ A refused or failed seat puts the piece back where it started (restored: true), saves nothing, and names the cause: seated_on, the seat's failure_reason, blockers {overlapping, overlaps, first_contact} and a next_step.
68
+
69
+ Returns {seated_on, final_gap (collider gap from SnapToSurface), back_face_gap (visible back face to the hit plane), moved_by, surface_hit, orientation, back_face_offset, seat {evidence, supportPath, finalGap, gapErrorBound, initiallyOverlapping, ...}, saved, warnings}. A warning visible_back_X_into_surface means the piece's collider sits behind its visible back: add X to standoff.`, attachToSurfaceArgsSchema.shape, runPlacement(attachToSurface));
70
+ server.tool("summer_repeat_along", `Instance copies of one scene along a straight line in one call: wall clamps every 0.45 m, braces every 0.8 m, fence posts, a row of window modules. Give start plus end (with spacing or count) or start plus direction (with count and spacing); positions are in the parent's local space. align (start|center|end) places the leftover length when spacing does not divide the line. Each copy is an InstantiateScene (the engine runs each alone), named <namePrefix>_<n>; the copies' transforms (position, rotationDegrees, scale) are then set in one request and the scene is saved once: N copies cost N + 2 engine requests. At most 64 copies per call.
71
+
72
+ Returns a compact receipt: {count, spacing, first, last, created [node paths], renamed, failures [{index, error}], saved}. Lists are cut to stay under 5 KB and the cut is declared.`, repeatAlongArgsSchema.shape, runPlacement(repeatAlong));
73
+ server.tool("summer_connect_ports", `Move and turn one piece so its port meets another piece's port, facing it: pipe to pipe, duct to duct, gutter section to funnel or outlet. A port is an open-loop id from summer_inspect_asset on that node's scene ("+Y" = the outermost open loop facing +Y in the piece's own axes, "+Y#2" the next one facing +Y; resolved on the live node's meshes in its own frame, so the id is the same in every pose), a Marker3D (or any Node3D) name under the node whose -Z axis points out of the port, or an open-loop index in the same stable order.
74
+
75
+ The subject turns by the shortest rotation that makes its port direction opposite the target's, then by rollDegrees about the joined axis, then moves so the ports coincide (gap along the target port's direction). rollDegrees: axis = roll_axis in the receipt (the target port direction reversed, pointing into the target); right-hand rule, positive = counter-clockwise seen from inside the target looking back at the subject; zero = the shortest turn from the subject's CURRENT orientation, so the same value differs between start poses. Once the ports are joined, a second call turns by exactly rollDegrees (180 flips a bend's free end to the other side).
76
+
77
+ Tilt guard: a join that would tilt the subject's up axis (its local +Y) more than maxTiltDegrees (default 5) is refused before anything changes (failure_reason tilt_exceeds_limit, with tilt_degrees and ports_within_limit: the subject ports that would join within the limit, least tilt first). Turning about the up axis is never tilt. Pass allowTilt true for an intended tilt (a bend laid on its side).
78
+
79
+ One SetProp on transform, saved; a fresh read verifies {distance, angle_degrees, tilt_degrees}. Returns {subject_port {kind, id|name, index, position, direction, radius}, target_port, roll_axis, roll_degrees, rotated_degrees, tilt_degrees, max_tilt_degrees, moved_by, other_ports, verify, warnings}. other_ports: every other port of the subject (its other Marker3D anchors, or its other open loops for an open-loop port) with world position and outward direction AFTER the move, measured by the verify read: read where a bend's free end now points instead of measuring it. Open-loop ports are only as exact as the mesh: check direction_ambiguous warnings and a screenshot.`, connectPortsArgsSchema.shape, runPlacement(connectPorts));
80
+ server.tool("summer_raycast", `Cast one ray from any point in an open scene, before anything is placed there: find the wall, floor or ceiling in front of a point and its normal. (summer_starcast casts from an existing node's bounds; this casts from an arbitrary origin.)
81
+
82
+ evidence auto (default): physics first (collider hit: exact point and normal); if physics hits nothing, the nearest visible-mesh AABB hit, declared with fallback:true and fallback_reason. Physics needs the scene to be the active editor tab (only that scene's bodies are in the editor's physics space); otherwise auto falls back to visual AABBs. When physics hits but a mesh-only object is nearer, nearer_visual_only names it.
83
+
84
+ Returns {hit, evidence, path, point, normal, distance, origin, direction, physics_available, warnings}. Read-only (RunSceneScript probe, undo "none"); never saves.`, raycastArgsSchema.shape, runPlacement(raycast));
85
+ server.tool("summer_measure", `Measure placement between specific nodes from their visible-mesh bounds (evidence visual_aabb). Read-only, never saves. Complements summer_starcast (which reports clearance around ONE node in 26 directions).
86
+
87
+ mode pair (a, b): per axis {gap (> 0 clearance, < 0 overlap depth), relation gap|touching|overlap, a/b intervals, delta_min/max/center (b minus a)} and boxes_overlap. Catches facade gaps and modules that overlap.
88
+ mode plane (nodes, face): whether that face of every node lies on one plane: {coplanar, plane (median), spread, nodes [{path, face, deviation, off_plane: proud|recessed}]}. Catches modules standing proud of a facade line. face '+z' = the face pointing along +z.
89
+
90
+ space "local" measures along the axes of a (pair) or nodes[0] (plane), for rotated facades. tolerance (default 5 mm) decides touching / coplanar.`, measureArgsSchema.shape, runPlacement(measure));
91
+ }
@@ -119,26 +119,29 @@ ladder, honesty rules, anti-patterns, and recovery steps.`, {}, async () => ({
119
119
  },
120
120
  ],
121
121
  }));
122
- server.tool("summer_get_project_context", `Get essential project context before editing. Returns:
123
- - engine health/status
124
- - project name and project path when exposed by project state
125
- - current scene path (if available)
126
- - main scene path from project settings
122
+ server.tool("summer_get_project_context", `Get essential project context before editing. The default payload is COMPACT (a few KB):
123
+ - project name and project path, current scene path, main scene path
124
+ - sceneSummary: the open scene's root node and node count (not its tree)
125
+ - health: the engine's scalar status fields plus capability COUNTS
127
126
  - projectMemory: the .summer summary — GameSoul/build-plan/memory files and
128
127
  \`pin\` (.summer/project.json: which template at which commit started this
129
128
  project, toolkit version, created_at)
130
- - capabilitySkewWarning (only when the engine build and this CLI have drifted
131
- apart — non-fatal; explains upcoming 'unknown op' failures)
129
+ - warnings: capabilitySkewWarning (only when the engine build and this CLI
130
+ have drifted apart — non-fatal; explains upcoming 'unknown op' failures),
131
+ rebindError, summerUpdateNotice
132
+ - omitted: how to ask for each heavy block that was left out
132
133
 
133
- Use this first in every fresh chat to avoid guessing scene filenames or editing the wrong scene.
134
+ Use this first in every fresh chat to avoid guessing scene filenames or editing the wrong scene. It also binds the session to the open project.
134
135
 
135
- Project settings in project.data.entries are trimmed to the curated default
136
- groups (application/, display/window/, the project's input/ actions, default
137
- gravity, rendering/renderer/, the 2D default texture filter) to bound payload
138
- size — the untrimmed dump is ~1000 entries. The payload declares the trim
139
- (settingsTruncated, totalSettings, settingsPrefixesIncluded,
140
- settingsPrefixesExcluded). Pass settingsPrefixes (e.g. ["audio/",
141
- "layer_names/"]) or settingsPrefix to read other groups instead.`, projectContextInputShape, async (args) => withEngine(async (client) =>
136
+ Heavy blocks are opt-in with include: 'scene_tree' (the open scene's tree, up
137
+ to 200 nodes; for one subtree prefer summer_world_snapshot path_prefix),
138
+ 'capabilities' (the engine's full op lists), 'settings' (project settings in
139
+ project.data.entries, trimmed to the curated default groups: application/,
140
+ display/window/, the project's input/ actions, default gravity,
141
+ rendering/renderer/, the 2D default texture filter; the trim is declared in
142
+ settingsTruncated / totalSettings / settingsPrefixesIncluded /
143
+ settingsPrefixesExcluded). settingsPrefixes (e.g. ["audio/", "layer_names/"])
144
+ or settingsPrefix read other settings groups and imply 'settings'.`, projectContextInputShape, async (args) => withEngine(async (client) =>
142
145
  // ONE builder for both faces (core/capabilities/project-context.ts);
143
146
  // the MCP surface contributes the boot drift notice it owns and logs
144
147
  // a capability skew once per process.