summer-engine 3.7.0 → 4.0.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 (501) hide show
  1. package/.claude-plugin/marketplace.json +2 -13
  2. package/.claude-plugin/plugin.json +25 -22
  3. package/.codex-plugin/plugin.json +8 -14
  4. package/.cursor-plugin/plugin.json +7 -13
  5. package/.factory-plugin/plugin.json +7 -13
  6. package/AGENTS.md +19 -12
  7. package/CHANGELOG.md +112 -0
  8. package/GEMINI.md +3 -3
  9. package/README.md +111 -31
  10. package/assets/icon.png +0 -0
  11. package/commands/start.md +71 -0
  12. package/commands/summer.md +5 -3
  13. package/dist/cli/banner.js +3 -0
  14. package/dist/cli/commands/login.d.ts +27 -0
  15. package/dist/cli/commands/login.js +58 -12
  16. package/dist/cli/commands/ops.d.ts +47 -0
  17. package/dist/cli/commands/ops.js +301 -0
  18. package/dist/cli/commands/setup.d.ts +2 -0
  19. package/dist/cli/commands/setup.js +37 -12
  20. package/dist/cli/commands/skills.js +11 -7
  21. package/dist/cli/index.js +7 -0
  22. package/dist/core/agent-host.d.ts +65 -0
  23. package/dist/core/agent-host.js +193 -0
  24. package/dist/core/capabilities/agent-playbook.d.ts +3 -0
  25. package/dist/core/capabilities/agent-playbook.js +54 -2
  26. package/dist/core/capabilities/apps.d.ts +341 -0
  27. package/dist/core/capabilities/apps.js +353 -0
  28. package/dist/core/capabilities/doctor.d.ts +3 -0
  29. package/dist/core/capabilities/doctor.js +20 -15
  30. package/dist/core/capabilities/enable-plugin.d.ts +27 -0
  31. package/dist/core/capabilities/enable-plugin.js +75 -0
  32. package/dist/core/capabilities/fabricate-mesh.d.ts +2 -2
  33. package/dist/core/capabilities/game-task-plan.d.ts +12 -6
  34. package/dist/core/capabilities/game-task-plan.js +80 -5
  35. package/dist/core/capabilities/motion-generation.js +2 -2
  36. package/dist/core/capabilities/navigation/open.d.ts +6 -2
  37. package/dist/core/capabilities/navigation/open.js +3 -0
  38. package/dist/core/capabilities/publish-build.js +2 -0
  39. package/dist/core/capabilities/runtime-control.d.ts +4 -4
  40. package/dist/core/capabilities/scene-script-target.d.ts +17 -0
  41. package/dist/core/capabilities/scene-script-target.js +70 -0
  42. package/dist/core/capabilities/sfx-choices.d.ts +4 -0
  43. package/dist/core/capabilities/sfx-choices.js +13 -6
  44. package/dist/core/capabilities/tool-dispatch.d.ts +12 -3
  45. package/dist/core/capabilities/tool-dispatch.js +130 -46
  46. package/dist/core/capability-skew.js +4 -0
  47. package/dist/core/embeddings.d.ts +2 -0
  48. package/dist/core/embeddings.js +1 -1
  49. package/dist/core/error-codes.d.ts +62 -0
  50. package/dist/core/error-codes.js +97 -0
  51. package/dist/core/format.d.ts +2 -0
  52. package/dist/core/format.js +2 -1
  53. package/dist/core/hosted-mcp.d.ts +22 -0
  54. package/dist/core/hosted-mcp.js +56 -1
  55. package/dist/core/library-read.js +5 -0
  56. package/dist/core/library-search.js +2 -1
  57. package/dist/core/oauth.js +4 -0
  58. package/dist/core/ops/catalog.d.ts +41 -0
  59. package/dist/core/ops/catalog.js +145 -0
  60. package/dist/core/ops/cloud.d.ts +56 -0
  61. package/dist/core/ops/cloud.js +175 -0
  62. package/dist/core/ops/contract.d.ts +119 -0
  63. package/dist/core/ops/contract.js +142 -0
  64. package/dist/core/ops/engine-answer.d.ts +25 -0
  65. package/dist/core/ops/engine-answer.js +117 -0
  66. package/dist/core/ops/engine.d.ts +55 -0
  67. package/dist/core/ops/engine.js +649 -0
  68. package/dist/core/ops/save-files.d.ts +78 -0
  69. package/dist/core/ops/save-files.js +419 -0
  70. package/dist/core/ops/search.d.ts +9 -0
  71. package/dist/core/ops/search.js +55 -0
  72. package/dist/core/skills-registry.d.ts +16 -1
  73. package/dist/core/skills-registry.js +35 -2
  74. package/dist/core/telemetry.d.ts +32 -0
  75. package/dist/core/telemetry.js +38 -10
  76. package/dist/core/tool-profiles.d.ts +25 -0
  77. package/dist/core/tool-profiles.js +41 -0
  78. package/dist/installer/agent-config.d.ts +17 -4
  79. package/dist/installer/agent-config.js +22 -6
  80. package/dist/installer/agent-table.d.ts +3 -0
  81. package/dist/installer/agent-table.js +10 -7
  82. package/dist/installer/setup.d.ts +2 -0
  83. package/dist/installer/setup.js +9 -4
  84. package/dist/installer/version-check.d.ts +29 -9
  85. package/dist/installer/version-check.js +81 -28
  86. package/dist/mcp/command.js +7 -0
  87. package/dist/mcp/hosted-mount.d.ts +27 -2
  88. package/dist/mcp/hosted-mount.js +66 -24
  89. package/dist/mcp/legacy-toolset.d.ts +27 -0
  90. package/dist/mcp/legacy-toolset.js +43 -0
  91. package/dist/mcp/ops-surface.d.ts +59 -0
  92. package/dist/mcp/ops-surface.js +443 -0
  93. package/dist/mcp/server.d.ts +35 -11
  94. package/dist/mcp/server.js +236 -89
  95. package/dist/mcp/tool-results.d.ts +26 -0
  96. package/dist/mcp/tool-results.js +81 -0
  97. package/dist/mcp/tool-surface.d.ts +65 -0
  98. package/dist/mcp/tool-surface.js +317 -0
  99. package/dist/mcp/tools/app-tools.d.ts +2 -0
  100. package/dist/mcp/tools/app-tools.js +71 -0
  101. package/dist/mcp/tools/asset-tools.js +55 -53
  102. package/dist/mcp/tools/audit-tools.js +21 -21
  103. package/dist/mcp/tools/debug-tools.js +6 -6
  104. package/dist/mcp/tools/fabricate-tools.js +6 -6
  105. package/dist/mcp/tools/generate-tools.js +76 -70
  106. package/dist/mcp/tools/project-tools.d.ts +9 -4
  107. package/dist/mcp/tools/project-tools.js +16 -10
  108. package/dist/mcp/tools/scene-tools.js +12 -23
  109. package/dist/mcp/tools/script-tools.js +9 -5
  110. package/dist/mcp/tools/with-engine.d.ts +6 -0
  111. package/dist/mcp/tools/with-engine.js +19 -0
  112. package/gemini-extension.json +6 -12
  113. package/hooks/pre-commit-doctor.sh +5 -4
  114. package/hooks/session-start.sh +24 -28
  115. package/integrations/claude-desktop/README.md +1 -1
  116. package/integrations/copilot-jetbrains/README.md +1 -1
  117. package/integrations/junie/README.md +1 -1
  118. package/integrations/lm-studio/README.md +1 -1
  119. package/integrations/trae/README.md +1 -1
  120. package/integrations/visual-studio/README.md +1 -1
  121. package/library/references/mcp-tools-reference/mcp-tools-reference.md +85 -35
  122. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  123. package/library/references/product-map/resource.yaml +2 -2
  124. package/library/skills/3d-lighting/SKILL.md +53 -28
  125. package/library/skills/3d-lighting/resource.yaml +1 -1
  126. package/library/skills/README.md +126 -116
  127. package/library/skills/adaptive-music/SKILL.md +19 -23
  128. package/library/skills/adaptive-music/resource.yaml +1 -1
  129. package/library/skills/agent-playtesting/SKILL.md +1 -1
  130. package/library/skills/agent-playtesting/resource.yaml +1 -1
  131. package/library/skills/ai-characters-in-games/SKILL.md +1 -1
  132. package/library/skills/ai-characters-in-games/resource.yaml +1 -1
  133. package/library/skills/ambient-bed/SKILL.md +22 -13
  134. package/library/skills/ambient-bed/resource.yaml +1 -1
  135. package/library/skills/animated-loop/SKILL.md +41 -32
  136. package/library/skills/animated-loop/resource.yaml +1 -1
  137. package/library/skills/animation-tree/SKILL.md +1 -1
  138. package/library/skills/animation-tree/resource.yaml +1 -1
  139. package/library/skills/art-direction/SKILL.md +3 -3
  140. package/library/skills/art-direction/resource.yaml +1 -1
  141. package/library/skills/asset-strategy/SKILL.md +21 -4
  142. package/library/skills/asset-strategy/resource.yaml +2 -1
  143. package/library/skills/audio-direction/SKILL.md +10 -10
  144. package/library/skills/audio-direction/resource.yaml +1 -1
  145. package/library/skills/auto-fire-targeting/SKILL.md +1 -1
  146. package/library/skills/auto-fire-targeting/resource.yaml +1 -1
  147. package/library/skills/bounded-engine-runs/SKILL.md +1 -1
  148. package/library/skills/bounded-engine-runs/resource.yaml +1 -1
  149. package/library/skills/brainstorm-game/SKILL.md +1 -1
  150. package/library/skills/brainstorm-game/resource.yaml +1 -1
  151. package/library/skills/brainstorming/SKILL.md +1 -1
  152. package/library/skills/brainstorming/resource.yaml +1 -1
  153. package/library/skills/browse-templates/SKILL.md +1 -1
  154. package/library/skills/browse-templates/resource.yaml +1 -1
  155. package/library/skills/camera-rigs/SKILL.md +2 -2
  156. package/library/skills/camera-rigs/resource.yaml +1 -1
  157. package/library/skills/celeste-momentum-platforming/resource.yaml +1 -0
  158. package/library/skills/character-animation-wiring/SKILL.md +4 -4
  159. package/library/skills/character-animation-wiring/resource.yaml +1 -1
  160. package/library/skills/character-model/SKILL.md +55 -47
  161. package/library/skills/character-model/resource.yaml +1 -1
  162. package/library/skills/character-movement/SKILL.md +3 -3
  163. package/library/skills/character-movement/resource.yaml +1 -1
  164. package/library/skills/character-portrait/SKILL.md +24 -19
  165. package/library/skills/character-portrait/resource.yaml +1 -1
  166. package/library/skills/cinematic-cutscene/SKILL.md +58 -46
  167. package/library/skills/cinematic-cutscene/resource.yaml +1 -1
  168. package/library/skills/combat-basics/SKILL.md +1 -1
  169. package/library/skills/combat-basics/resource.yaml +1 -1
  170. package/library/skills/compatibility-renderer-traps/SKILL.md +1 -1
  171. package/library/skills/compatibility-renderer-traps/resource.yaml +1 -1
  172. package/library/skills/concept-art/SKILL.md +16 -12
  173. package/library/skills/concept-art/resource.yaml +1 -1
  174. package/library/skills/concept-to-level/SKILL.md +239 -0
  175. package/library/skills/concept-to-level/references/technical-rules.md +150 -0
  176. package/library/skills/concept-to-level/resource.yaml +44 -0
  177. package/library/skills/create-asset-sheet/SKILL.md +19 -13
  178. package/library/skills/create-asset-sheet/resource.yaml +1 -1
  179. package/library/skills/debug/SKILL.md +2 -2
  180. package/library/skills/debug/resource.yaml +1 -1
  181. package/library/skills/debugging-game-feel/SKILL.md +1 -1
  182. package/library/skills/debugging-game-feel/resource.yaml +1 -1
  183. package/library/skills/design-level/SKILL.md +23 -35
  184. package/library/skills/design-level/resource.yaml +1 -1
  185. package/library/skills/design-mechanic/SKILL.md +1 -1
  186. package/library/skills/design-mechanic/resource.yaml +1 -1
  187. package/library/skills/design-npc/SKILL.md +22 -24
  188. package/library/skills/design-npc/resource.yaml +1 -1
  189. package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
  190. package/library/skills/diagnosing-perf-regressions/resource.yaml +1 -1
  191. package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
  192. package/library/skills/driving-the-editor-ui/resource.yaml +1 -1
  193. package/library/skills/environment-kit/SKILL.md +20 -16
  194. package/library/skills/environment-kit/resource.yaml +1 -1
  195. package/library/skills/export-and-ship/SKILL.md +6 -6
  196. package/library/skills/export-and-ship/resource.yaml +1 -1
  197. package/library/skills/fabricating-assets/SKILL.md +7 -7
  198. package/library/skills/fabricating-assets/resource.yaml +3 -3
  199. package/library/skills/facial-and-lipsync/SKILL.md +14 -15
  200. package/library/skills/facial-and-lipsync/resource.yaml +1 -1
  201. package/library/skills/fps-controller/SKILL.md +33 -41
  202. package/library/skills/fps-controller/resource.yaml +1 -1
  203. package/library/skills/game-feel/SKILL.md +8 -8
  204. package/library/skills/game-feel/resource.yaml +1 -1
  205. package/library/skills/gameskill/SKILL.md +4 -4
  206. package/library/skills/gameskill/resource.yaml +1 -1
  207. package/library/skills/gdscript-patterns/SKILL.md +1 -1
  208. package/library/skills/gdscript-patterns/resource.yaml +1 -1
  209. package/library/skills/generate-motion/SKILL.md +30 -21
  210. package/library/skills/generate-motion/resource.yaml +1 -1
  211. package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
  212. package/library/skills/godogen-visual-proof-game-generation/resource.yaml +1 -0
  213. package/library/skills/grow-analytics/SKILL.md +3 -3
  214. package/library/skills/grow-analytics/resource.yaml +1 -1
  215. package/library/skills/headless-scripting/SKILL.md +1 -1
  216. package/library/skills/headless-scripting/resource.yaml +1 -1
  217. package/library/skills/in-game-purchases/SKILL.md +1 -1
  218. package/library/skills/in-game-purchases/resource.yaml +1 -1
  219. package/library/skills/instantiate-asset-pack/SKILL.md +2 -2
  220. package/library/skills/instantiate-asset-pack/resource.yaml +1 -1
  221. package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +1 -0
  222. package/library/skills/make-game/SKILL.md +4 -4
  223. package/library/skills/make-game/references/2d-platformer.md +1 -1
  224. package/library/skills/make-game/references/3d-fps.md +1 -1
  225. package/library/skills/make-game/references/3d-horror.md +1 -1
  226. package/library/skills/make-game/references/3d-third-person.md +2 -2
  227. package/library/skills/make-game/resource.yaml +1 -1
  228. package/library/skills/multiplayer/SKILL.md +1 -1
  229. package/library/skills/multiplayer/resource.yaml +1 -1
  230. package/library/skills/multiplayer-movement/SKILL.md +1 -1
  231. package/library/skills/multiplayer-movement/resource.yaml +1 -1
  232. package/library/skills/multiplayer-project/SKILL.md +1 -1
  233. package/library/skills/multiplayer-project/resource.yaml +1 -1
  234. package/library/skills/multiplayer-publish/SKILL.md +8 -7
  235. package/library/skills/multiplayer-publish/resource.yaml +3 -3
  236. package/library/skills/multiplayer-state/SKILL.md +1 -1
  237. package/library/skills/multiplayer-state/resource.yaml +1 -1
  238. package/library/skills/multiplayer-testing/SKILL.md +1 -1
  239. package/library/skills/multiplayer-testing/resource.yaml +1 -1
  240. package/library/skills/music-track/SKILL.md +22 -13
  241. package/library/skills/music-track/resource.yaml +1 -1
  242. package/library/skills/navigate-summer/SKILL.md +11 -9
  243. package/library/skills/navigate-summer/resource.yaml +1 -1
  244. package/library/skills/new-project/SKILL.md +1 -1
  245. package/library/skills/new-project/resource.yaml +1 -1
  246. package/library/skills/organic-model/SKILL.md +24 -18
  247. package/library/skills/organic-model/resource.yaml +1 -1
  248. package/library/skills/pixel-art/SKILL.md +27 -23
  249. package/library/skills/pixel-art/resource.yaml +1 -1
  250. package/library/skills/play/SKILL.md +1 -1
  251. package/library/skills/play/resource.yaml +1 -1
  252. package/library/skills/playtesting-a-feature/SKILL.md +1 -1
  253. package/library/skills/playtesting-a-feature/resource.yaml +1 -1
  254. package/library/skills/procedural-animation/SKILL.md +20 -16
  255. package/library/skills/procedural-animation/resource.yaml +1 -1
  256. package/library/skills/prop-model/SKILL.md +25 -19
  257. package/library/skills/prop-model/resource.yaml +1 -1
  258. package/library/skills/psx-retro-rendering/resource.yaml +1 -0
  259. package/library/skills/publish-your-game/SKILL.md +16 -6
  260. package/library/skills/publish-your-game/resource.yaml +3 -3
  261. package/library/skills/realtime-wet-surfaces/resource.yaml +1 -0
  262. package/library/skills/release-readiness/SKILL.md +1 -1
  263. package/library/skills/release-readiness/resource.yaml +1 -1
  264. package/library/skills/remote-deploy/SKILL.md +1 -1
  265. package/library/skills/remote-deploy/resource.yaml +1 -1
  266. package/library/skills/retarget/SKILL.md +23 -20
  267. package/library/skills/retarget/resource.yaml +1 -1
  268. package/library/skills/running-in-the-cloud/SKILL.md +1 -1
  269. package/library/skills/running-in-the-cloud/resource.yaml +1 -1
  270. package/library/skills/save-load/SKILL.md +1 -1
  271. package/library/skills/save-load/resource.yaml +1 -1
  272. package/library/skills/scene-composition/SKILL.md +1 -1
  273. package/library/skills/scene-composition/resource.yaml +1 -1
  274. package/library/skills/scene-hierarchy-design/SKILL.md +2 -2
  275. package/library/skills/scene-hierarchy-design/resource.yaml +1 -1
  276. package/library/skills/scene-scripting/SKILL.md +66 -636
  277. package/library/skills/scene-scripting/references/ctx-api.md +184 -0
  278. package/library/skills/scene-scripting/references/recipes-2d-ui.md +193 -0
  279. package/library/skills/scene-scripting/references/recipes-3d.md +280 -0
  280. package/library/skills/scene-scripting/resource.yaml +4 -4
  281. package/library/skills/scene-to-level/SKILL.md +2 -2
  282. package/library/skills/scene-to-level/resource.yaml +1 -1
  283. package/library/skills/skill-create/resource.yaml +1 -0
  284. package/library/skills/skill-improve/resource.yaml +1 -0
  285. package/library/skills/skill-test/SKILL.md +2 -2
  286. package/library/skills/skill-test/resource.yaml +1 -0
  287. package/library/skills/skintokens-auto-rigging/resource.yaml +1 -0
  288. package/library/skills/skybox-panorama/SKILL.md +27 -21
  289. package/library/skills/skybox-panorama/resource.yaml +1 -1
  290. package/library/skills/sound-effect/SKILL.md +31 -20
  291. package/library/skills/sound-effect/resource.yaml +1 -1
  292. package/library/skills/spatial-placement/SKILL.md +14 -9
  293. package/library/skills/spatial-placement/resource.yaml +1 -1
  294. package/library/skills/sprite-sheet/SKILL.md +32 -27
  295. package/library/skills/sprite-sheet/resource.yaml +1 -1
  296. package/library/skills/store-art/SKILL.md +3 -3
  297. package/library/skills/store-art/resource.yaml +2 -2
  298. package/library/skills/store-listing/SKILL.md +3 -3
  299. package/library/skills/store-listing/resource.yaml +2 -2
  300. package/library/skills/summer-analytics/SKILL.md +7 -5
  301. package/library/skills/summer-analytics/resource.yaml +2 -2
  302. package/library/skills/summer-apps/SKILL.md +168 -0
  303. package/library/skills/summer-apps/manifest.md +57 -0
  304. package/library/skills/summer-apps/minimal-app.md +183 -0
  305. package/library/skills/summer-apps/resource.yaml +36 -0
  306. package/library/skills/summer-apps/sdk-reference.md +135 -0
  307. package/library/skills/summer-apps-design/SKILL.md +197 -0
  308. package/library/skills/summer-apps-design/resource.yaml +23 -0
  309. package/library/skills/summer-assets/SKILL.md +56 -0
  310. package/library/skills/summer-assets/resource.yaml +34 -0
  311. package/library/skills/summer-store/SKILL.md +1 -1
  312. package/library/skills/text-to-motion/SKILL.md +30 -23
  313. package/library/skills/text-to-motion/prompts-and-controls.md +5 -5
  314. package/library/skills/text-to-motion/resource.yaml +1 -1
  315. package/library/skills/text-to-motion/rigging-for-text-motion.md +2 -2
  316. package/library/skills/tileable-texture/SKILL.md +19 -15
  317. package/library/skills/tileable-texture/resource.yaml +1 -1
  318. package/library/skills/trailer-shot/SKILL.md +28 -24
  319. package/library/skills/trailer-shot/resource.yaml +1 -1
  320. package/library/skills/tune-performance/SKILL.md +6 -6
  321. package/library/skills/tune-performance/resource.yaml +1 -1
  322. package/library/skills/ui-basics/SKILL.md +41 -36
  323. package/library/skills/ui-basics/resource.yaml +1 -1
  324. package/library/skills/ui-graphics/SKILL.md +47 -38
  325. package/library/skills/ui-graphics/resource.yaml +1 -1
  326. package/library/skills/use-widget-asset/SKILL.md +1 -1
  327. package/library/skills/use-widget-asset/resource.yaml +1 -1
  328. package/library/skills/using-summer/SKILL.md +7 -5
  329. package/library/skills/using-summer/resource.yaml +1 -1
  330. package/library/skills/vehicle-model/SKILL.md +65 -57
  331. package/library/skills/vehicle-model/resource.yaml +1 -1
  332. package/library/skills/verification-before-completion/SKILL.md +1 -1
  333. package/library/skills/verification-before-completion/resource.yaml +1 -1
  334. package/library/skills/verifying-scenes/SKILL.md +2 -2
  335. package/library/skills/verifying-scenes/resource.yaml +1 -1
  336. package/library/skills/vfx-dissolve/SKILL.md +2 -2
  337. package/library/skills/vfx-dissolve/resource.yaml +1 -1
  338. package/library/skills/vfx-fire/SKILL.md +15 -41
  339. package/library/skills/vfx-fire/resource.yaml +1 -1
  340. package/library/skills/vfx-hit-spark/SKILL.md +1 -1
  341. package/library/skills/vfx-hit-spark/resource.yaml +1 -1
  342. package/library/skills/vfx-lightning/SKILL.md +7 -16
  343. package/library/skills/vfx-lightning/resource.yaml +1 -1
  344. package/library/skills/vfx-magic-glow/SKILL.md +23 -32
  345. package/library/skills/vfx-magic-glow/resource.yaml +1 -1
  346. package/library/skills/vfx-muzzle-flash/SKILL.md +20 -35
  347. package/library/skills/vfx-muzzle-flash/resource.yaml +1 -1
  348. package/library/skills/vfx-smoke/SKILL.md +13 -31
  349. package/library/skills/vfx-smoke/resource.yaml +1 -1
  350. package/library/skills/vfx-water-ripple/SKILL.md +12 -31
  351. package/library/skills/vfx-water-ripple/resource.yaml +1 -1
  352. package/library/skills/voice-line/SKILL.md +71 -40
  353. package/library/skills/voice-line/resource.yaml +1 -1
  354. package/library/skills/web-and-touch-input/SKILL.md +1 -1
  355. package/library/skills/web-and-touch-input/resource.yaml +1 -1
  356. package/library/skills/web-compatibility-look/SKILL.md +1 -1
  357. package/library/skills/web-compatibility-look/resource.yaml +1 -1
  358. package/library/skills/world-building-3d/SKILL.md +1 -1
  359. package/library/skills/world-building-3d/resource.yaml +1 -1
  360. package/library/skills/writing-skills/resource.yaml +1 -0
  361. package/library/tools/add-node/GUIDE.md +14 -0
  362. package/library/tools/align-distribute-3d/GUIDE.md +7 -0
  363. package/library/tools/app-call/resource.yaml +59 -0
  364. package/library/tools/app-create/resource.yaml +67 -0
  365. package/library/tools/app-data/resource.yaml +74 -0
  366. package/library/tools/app-dock/resource.yaml +59 -0
  367. package/library/tools/app-events/resource.yaml +68 -0
  368. package/library/tools/app-get/resource.yaml +46 -0
  369. package/library/tools/app-guide/resource.yaml +55 -0
  370. package/library/tools/app-list/resource.yaml +48 -0
  371. package/library/tools/app-page/resource.yaml +74 -0
  372. package/library/tools/app-publish/resource.yaml +90 -0
  373. package/library/tools/app-report-gap/resource.yaml +58 -0
  374. package/library/tools/app-screenshot/resource.yaml +103 -0
  375. package/library/tools/app-tools/resource.yaml +46 -0
  376. package/library/tools/app-update/resource.yaml +68 -0
  377. package/library/tools/attach-to-surface/GUIDE.md +15 -0
  378. package/library/tools/batch/GUIDE.md +27 -0
  379. package/library/tools/camera-bookmark/GUIDE.md +12 -0
  380. package/library/tools/capture-gameplay/GUIDE.md +3 -0
  381. package/library/tools/capture-gameplay/resource.yaml +3 -3
  382. package/library/tools/check-job/resource.yaml +1 -1
  383. package/library/tools/clear-console/GUIDE.md +3 -0
  384. package/library/tools/connect-ports/GUIDE.md +9 -0
  385. package/library/tools/connect-signal/GUIDE.md +14 -0
  386. package/library/tools/create-debug-report/GUIDE.md +10 -0
  387. package/library/tools/create-scene/GUIDE.md +10 -0
  388. package/library/tools/debug-views/GUIDE.md +7 -0
  389. package/library/tools/enable-plugin/GUIDE.md +3 -0
  390. package/library/tools/enable-plugin/resource.yaml +53 -0
  391. package/library/tools/export-game/GUIDE.md +3 -0
  392. package/library/tools/export-game/resource.yaml +3 -3
  393. package/library/tools/export-templates/GUIDE.md +3 -0
  394. package/library/tools/fabricate-3d/GUIDE.md +19 -0
  395. package/library/tools/frame-nodes/GUIDE.md +9 -0
  396. package/library/tools/frame-shot/GUIDE.md +9 -0
  397. package/library/tools/game-control/GUIDE.md +9 -0
  398. package/library/tools/game-input/GUIDE.md +9 -0
  399. package/library/tools/game-probe/GUIDE.md +9 -0
  400. package/library/tools/generate-3d/resource.yaml +3 -3
  401. package/library/tools/generate-motion/resource.yaml +2 -2
  402. package/library/tools/get-console/GUIDE.md +9 -0
  403. package/library/tools/get-console/resource.yaml +5 -0
  404. package/library/tools/get-debugger-errors/GUIDE.md +7 -0
  405. package/library/tools/get-debugger-errors/resource.yaml +5 -0
  406. package/library/tools/get-debugger-warnings/GUIDE.md +7 -0
  407. package/library/tools/get-debugger-warnings/resource.yaml +5 -0
  408. package/library/tools/get-diagnostics/GUIDE.md +13 -0
  409. package/library/tools/get-project-context/GUIDE.md +25 -0
  410. package/library/tools/get-runtime-tree/GUIDE.md +7 -0
  411. package/library/tools/get-runtime-tree/resource.yaml +5 -0
  412. package/library/tools/get-scene-tree/GUIDE.md +11 -0
  413. package/library/tools/get-scene-tree/resource.yaml +5 -0
  414. package/library/tools/get-script-errors/GUIDE.md +5 -0
  415. package/library/tools/grep/GUIDE.md +11 -0
  416. package/library/tools/import-asset/GUIDE.md +8 -0
  417. package/library/tools/import-asset-by-id/GUIDE.md +12 -0
  418. package/library/tools/import-from-url/GUIDE.md +10 -0
  419. package/library/tools/import-from-url-batch/GUIDE.md +3 -0
  420. package/library/tools/import-hdri/GUIDE.md +16 -0
  421. package/library/tools/input-map-bind/GUIDE.md +11 -0
  422. package/library/tools/inspect-asset/GUIDE.md +14 -0
  423. package/library/tools/inspect-asset/resource.yaml +5 -0
  424. package/library/tools/inspect-node/GUIDE.md +11 -0
  425. package/library/tools/inspect-node/resource.yaml +5 -0
  426. package/library/tools/inspect-resource/GUIDE.md +7 -0
  427. package/library/tools/inspect-resource/resource.yaml +5 -0
  428. package/library/tools/inspect-runtime-node/GUIDE.md +7 -0
  429. package/library/tools/inspect-runtime-node/resource.yaml +5 -0
  430. package/library/tools/instantiate-scene/GUIDE.md +12 -0
  431. package/library/tools/is-running/GUIDE.md +3 -0
  432. package/library/tools/measure/GUIDE.md +8 -0
  433. package/library/tools/navigation-probe/GUIDE.md +9 -0
  434. package/library/tools/open/resource.yaml +2 -2
  435. package/library/tools/open-main-scene/GUIDE.md +6 -0
  436. package/library/tools/open-scene/GUIDE.md +8 -0
  437. package/library/tools/place-adjacent/GUIDE.md +7 -0
  438. package/library/tools/play/GUIDE.md +13 -0
  439. package/library/tools/project-setting/GUIDE.md +9 -0
  440. package/library/tools/publish-build/resource.yaml +6 -6
  441. package/library/tools/raycast/GUIDE.md +7 -0
  442. package/library/tools/read-file/GUIDE.md +10 -0
  443. package/library/tools/read-library/resource.yaml +5 -0
  444. package/library/tools/recent-events/GUIDE.md +7 -0
  445. package/library/tools/remove-node/GUIDE.md +3 -0
  446. package/library/tools/repeat-along/GUIDE.md +5 -0
  447. package/library/tools/replace-node/GUIDE.md +9 -0
  448. package/library/tools/replace-text/GUIDE.md +5 -0
  449. package/library/tools/run-editor-script/GUIDE.md +16 -0
  450. package/library/tools/run-script/GUIDE.md +30 -0
  451. package/library/tools/run-script/resource.yaml +6 -3
  452. package/library/tools/runtime-animate/GUIDE.md +7 -0
  453. package/library/tools/runtime-call/GUIDE.md +7 -0
  454. package/library/tools/runtime-set/GUIDE.md +9 -0
  455. package/library/tools/runtime-spawn/GUIDE.md +9 -0
  456. package/library/tools/save-scene/GUIDE.md +3 -0
  457. package/library/tools/scene-audit/GUIDE.md +29 -0
  458. package/library/tools/screenshot/GUIDE.md +17 -0
  459. package/library/tools/select-node/GUIDE.md +3 -0
  460. package/library/tools/set-prop/GUIDE.md +23 -0
  461. package/library/tools/set-resource-property/GUIDE.md +8 -0
  462. package/library/tools/shot-sheet/GUIDE.md +7 -0
  463. package/library/tools/snap-to-surface/GUIDE.md +17 -0
  464. package/library/tools/snapshot-diff/GUIDE.md +7 -0
  465. package/library/tools/starcast/GUIDE.md +12 -0
  466. package/library/tools/stop/GUIDE.md +3 -0
  467. package/library/tools/test-placement/GUIDE.md +7 -0
  468. package/library/tools/ui-actions/GUIDE.md +12 -0
  469. package/library/tools/ui-activate/GUIDE.md +11 -0
  470. package/library/tools/ui-screenshot/GUIDE.md +9 -0
  471. package/library/tools/ui-tree/GUIDE.md +10 -0
  472. package/library/tools/wait-for-event/GUIDE.md +11 -0
  473. package/library/tools/world-snapshot/GUIDE.md +9 -0
  474. package/library/tools/write-file/GUIDE.md +5 -0
  475. package/library/tools/zoom/GUIDE.md +5 -0
  476. package/package.json +6 -4
  477. package/registry/generated/aliases.json +15 -0
  478. package/registry/generated/counts.json +3 -3
  479. package/registry/generated/gemini-extension.json +6 -12
  480. package/registry/generated/index.json +1155 -408
  481. package/registry/generated/marketplace.claude.json +2 -13
  482. package/registry/generated/plugin.claude.json +25 -22
  483. package/registry/generated/plugin.codex.json +8 -14
  484. package/registry/generated/plugin.cursor.json +7 -13
  485. package/registry/generated/plugin.factory.json +7 -13
  486. package/registry/generated/server.json +34 -0
  487. package/registry/generated/skills-index.md +126 -116
  488. package/registry/generated/skills-registry.json +178 -113
  489. package/registry/operations/fixtures/invalid-deprecated-without-replacement.json +60 -0
  490. package/registry/operations/fixtures/invalid-name.json +60 -0
  491. package/registry/operations/fixtures/invalid-publish-without-owner.json +82 -0
  492. package/registry/operations/fixtures/invalid-spend-without-estimate.json +42 -0
  493. package/registry/operations/fixtures/invalid-unknown-field.json +61 -0
  494. package/registry/operations/fixtures/valid-player-facing.json +82 -0
  495. package/registry/operations/fixtures/valid-read.json +60 -0
  496. package/registry/operations/fixtures/valid-spend.json +43 -0
  497. package/registry/operations/legacy-names.json +1206 -0
  498. package/registry/schemas/allowed-hosts.json +4 -2
  499. package/registry/schemas/operation.schema.json +318 -0
  500. package/registry/schemas/skill.schema.json +4 -0
  501. package/CLAUDE.md +0 -7
@@ -27,33 +27,33 @@ export function auditContent(result) {
27
27
  return { content };
28
28
  }
29
29
  export function registerAuditTools(server) {
30
- server.tool("summer_scene_audit", `Audit a 3D scene in one fast, read-only call: every node and subnode is walked and likely visual and placement problems come back as a short list, sorted by severity, so you know exactly where to look. Each issue is a flag to LOOK at, never an auto-fix.
30
+ server.tool("summer_scene_audit", `Audit a 3D scene in one fast, read-only call: it walks every node and subnode and lists likely visual and placement problems, sorted by severity. Each issue is a flag to LOOK at, never an auto-fix.
31
31
 
32
- Checks (each can be picked with checks):
33
- - through_hole: capped ray grids through every facade line (coplanar wall fronts); clusters of rays that pass the wall AND reach the far side of the building (a door insert narrower than its frame, a missing module, a seam). Walls, structure and inserts close an opening; props do not.
34
- - exposed_edge: open outline edges of walls and facade members (bands, piers, corner blocks; cached per mesh) that nothing covers within 4-7 mm, seen from walkable space (eye points over open-sky floor cells, flood-filled from the scene's cameras and characters, sight lines not through a building), with a 2-60 cm reveal behind them, or a coplanar sheet continuing within 4 cm (seam) or 35 cm (gap). Warn on band pieces and when depth_step agrees, look otherwise; repeats group per piece type.
35
- - open_fixture_end: open ends of run pieces (a mesh with two or more open rims of one size: pipe, duct or gutter sections, elbows, tees) that nothing joins within 2.5 cm (sleeve tolerance), seen from walkable space: a missing elbow, coupler, section or end piece (warn). A piece with one rim or rims of different sizes (a cap, a funnel, an outlet) is open by design.
36
- - depth_step (look): ray rows across each visible facade side at its band levels and every 1.25 m: band recesses and missing runs, seams, modules standing proud, holes with something behind them; a hole next to a through_hole confirms it (warn -> error); runs a door-like opening covers are skipped.
37
- - floor_gap: down rays over the floor tiles, along their seams, and from each tile edge to a wall within 1 m (bare strips at wall bases), classified by the FIRST surface hit: the void (error); an underlay over the floor's own lower surface such as a drain channel ("covers the floor", warn, not a hole); an underlay through a hole or strip. Areas are the missed rays' own footprints with the strip's size; a tile whose own mesh has holes is one issue for the piece.
38
- - floating / sunken: support under each prop's footprint; gap over 2 cm, embed over 3 cm, measured against the first surface from above (the tile it is buried in, not the underlay under it); structure and pieces touching a wall well off the ground excluded.
39
- - interpenetration: each prop's convex hulls against props, walls, structure and inserts; a deepest overlap over 3 cm, then every partner it cuts (up to 3).
40
- - orientation (look): long props within 1.2 m of a wall more than 15 deg off parallel. It never says which way a piece should face.
41
- - uv_stretch: per mesh resource, large triangles whose UV-to-world mapping is stretched over 8:1 or collapsed to a line, where an instance shows them (a reveal that inserts normally cover = warn).
42
- - duplicate: the same scene at the same transform.
43
- - z_fight: coplanar overlapping faces anywhere, from each mesh's planar face groups: between any two pieces (props, roofs, ledges, side walls, inserts against hosts, decals; opposite-facing only when both are double-sided) and between two surfaces of one mesh (once per mesh), plus the ray samples. Coplanar = a gap under twice the 24-bit depth step at the view distance (the nearest walkable eye point, camera or bookmark; 30 m without one) for the main camera's near/far; ev carries the overlap, gap, tolerance, surfaces, the plane's normal and the axis to nudge (nudge.world, nudge.local: a window can share its head or a jamb with its host, not its front). Warn over 0.05 m2 seen from a viewpoint; the material decides what is demoted to look, with the reason: render_priority, depth or normal offsets, a see-through (alpha) material, no depth test or depth writes.
44
- - lights: meshes paired with more than the per-object limit of omni or spot lights (Compatibility: 8 each; light cuts off at seams), spot lights with spot_angle_attenuation under 3; shadowed light counts.
45
- - transform: NaN, negative or non-uniform scale, a piece far out of bounds, and pieces left at the origin: an identity LOCAL transform under an identity parent, touching nothing and not one of a row of siblings (several sharing it warn, one alone is look; a module whose corner is the world origin is placed).
46
- - resource: missing dependency files, MeshInstance3D without a mesh, surfaces without a material.
32
+ Checks (pick with checks; the verifying-scenes skill explains each):
33
+ - through_hole: ray grids through each facade line that pass the wall AND reach the building's far side (an insert narrower than its frame, a missing module). Props do not close an opening.
34
+ - exposed_edge: edges of walls, bands, piers and corner blocks nothing covers within 4-7 mm, seen from walkable space, with a 2-60 cm reveal, a 4 cm seam or a 35 cm gap. Warn on bands or when depth_step agrees, else look.
35
+ - open_fixture_end (warn): open ends of pipe, duct or gutter runs (2+ open rims of one size) nothing joins within 2.5 cm; caps, funnels, outlets are open by design.
36
+ - depth_step (look): ray rows at each facade's band levels and every 1.25 m: recesses, missing runs, seams, proud modules, holes (a hole by a through_hole makes it an error).
37
+ - floor_gap: down rays over tiles, seams and the strip to a wall within 1 m, by FIRST surface hit: the void (error), underlay over the floor's own drain (warn, not a hole), underlay through a hole.
38
+ - floating / sunken: over 2 cm above or 3 cm into the first surface from above; structure and wall-mounted pieces excluded.
39
+ - interpenetration: prop hulls cutting props, walls, structure or inserts over 3 cm, with every partner (up to 3).
40
+ - orientation (look): long props within 1.2 m of a wall over 15 deg off parallel; never says which way to face.
41
+ - uv_stretch: shown triangles with UVs stretched over 8:1 or collapsed.
42
+ - duplicate: same scene, same transform.
43
+ - z_fight: coplanar overlapping faces of two pieces (opposite-facing only if both double-sided) or of one mesh: a gap under twice the 24-bit depth step at the view distance (else 30 m). Warn over 0.05 m2 seen; ev.nudge names the axis to move (world and local). render_priority, depth or normal offsets, alpha, no depth test or writes demote it to look, with the reason.
44
+ - lights: over the per-object omni/spot limit (Compatibility: 8 each), spot_angle_attenuation under 3; shadowed counts.
45
+ - transform: NaN, negative or non-uniform scale, far out of bounds, pieces left at the origin (several = warn, one = look).
46
+ - resource: missing dependencies, a MeshInstance3D without a mesh, surfaces without a material.
47
47
 
48
- budget_ms (default 3000) bounds the editor time: each check gets a weighted share of it, and a check past its share stops and is marked counts.<check>.partial (the share it covered), never clean. The three gap detectors (exposed_edge, open_fixture_end, depth_step) run last on the time the other checks leave (band pieces and band rows first); rerun them alone when partial.
48
+ budget_ms (default 3000) bounds editor time: each check gets a weighted share; one past it stops, marked counts.<check>.partial (the share covered), never clean. exposed_edge, open_fixture_end and depth_step run last on the time left: rerun them alone when partial.
49
49
 
50
- accept:[{key, reason}] (keys from issues[].key) records look and warn items you judged fine in res://.summer/audit-accept.json (the only file the audit writes); later audits count them (counts.<check>.accepted) but hide them until their evidence changes materially (severity rises, or the measured size moves by over 25%: shown again with accept_stale). Errors cannot be accepted; show_accepted lists them.
50
+ accept:[{key, reason}] (issues[].key) records look/warn items you judged fine in res://.summer/audit-accept.json, the only file the audit writes. Later audits count them (counts.<check>.accepted) but hide them until severity rises or the measured size moves over 25% (then accept_stale). Errors cannot be accepted; show_accepted lists them.
51
51
 
52
- Returns at most 5 KB of JSON: counts per check, time per check (editor ms), the scene size, and ONE page of issues {n, check, sev (error|warn|look), path, pos (world), why, ev (evidence numbers: sizes, distances, angles, the ray to reproduce), next (the tool to use next), key (for accept)}. Page with offset/limit (next_offset names the next page); filter with checks, root (a subtree) and min_severity. render:"sheet" adds ONE inline image of the page's first 6 issues framed up close from their open side (a camera never behind a wall), each tile labelled #n.
52
+ Returns at most 5 KB of JSON: counts and editor ms per check, scene size, ONE page of issues {n, check, sev (error|warn|look), path, pos (world), why, ev (evidence numbers, the ray to reproduce), next (the next tool), key}. Page with offset/limit (next_offset); filter with checks, root (subtree), min_severity. render:"sheet" adds ONE image of the page's first 6 issues framed close from their open side, tiles labelled #n.
53
53
 
54
- Every check works on any scene from geometry, the engine's node and resource data and materials alone: never node or file names, never kit metadata. Each piece's role comes from its shape: see-through cards (every material alpha) are dressing; thin upright sheets are walls (facing their side with more face area); flat slabs whose tops cover their footprint are floors (raised ones with walls under them are roofs, a large one below the rest is the underlay); a piece inside a wall's rectangle that reaches through the wall where it is open is an insert; bands, piers and corner blocks touching a facade wall are structure; the rest are props up to 3.5 m.
54
+ Every check works from geometry, node and resource data and materials alone: never node or file names, never kit metadata. Each piece's role (dressing, wall, floor, roof, underlay, insert, structure, a prop up to 3.5 m) comes from its shape.
55
55
 
56
- Read-only: it audits the SAVED file in a private offscreen copy (ScenePreview), so the open tab never becomes unsaved, undo is untouched and nothing is saved (accept writes only its own file). Save the scene first. Failures are structured (failure_reason), never a silent fallback.`, sceneAuditShape, async (args) => withEngine(async (client) => {
56
+ Read-only: audits the SAVED file (save first) in a private offscreen copy (ScenePreview): the open tab never becomes unsaved, undo is untouched, nothing is saved. Failures are structured (failure_reason), never a silent fallback.`, sceneAuditShape, async (args) => withEngine(async (client) => {
57
57
  const audit = await sceneAudit(client, args);
58
58
  return audit.ok ? { audit } : { audit, failure_reason: audit.failure_reason };
59
59
  }, { onResult: (wrapped) => auditContent(wrapped.audit) }));
@@ -192,17 +192,17 @@ Use this when summer_get_diagnostics shows a non-zero \`debugger.warnings\` coun
192
192
  const { result } = shapeEngineLogResponse(engineResult, { maxEntries: max_warnings });
193
193
  return result;
194
194
  }));
195
- server.tool("summer_play", `Start running the game in the engine. With no extra parameters the game runs inside Summer Engine's viewport (the 'main' instance) QUIETLY — see below.
195
+ server.tool("summer_play", `Start the game. With no parameters it runs QUIETLY inside Summer Engine's viewport (the 'main' instance); scene runs one level or UI screen instead of the main scene.
196
196
 
197
- QUIET BY DEFAULT (focus:false, PlayGame agent:true): the user is usually working on the same machine while you build, so a play must not take over their screen. Quiet play makes the EDITOR stay put: it does not switch the main screen to the Game tab, does not grab keyboard focus for the embedded game, ignores the game's later focus report, and skips the render-health self-check that would otherwise misread the untouched Game view as a GPU failure and flip the user's embed setting. Quiet play does NOT hide the game: it still runs embedded in the Game view (visible if the user already has that tab open), it is the running game for summer_is_running / summer_screenshot target:'game' / summer_get_diagnostics, and on engines without the background launch posture it does not change a user who has "Embed Game on Play" turned off — their game opens in its own OS window as always. Engines with the background posture (--summer-background, 0.5.66+) also launch the play child with that flag, so a separate-window game appears without activating or taking focus either. The result echoes agent_quiet:true when honoured; a launch result WITHOUT agent_quiet means the engine predates quiet play and most likely took focus — the tool adds posture_note saying so. focus:true launches like the toolbar Play button (Game tab + focus): use it ONLY when the user is watching and asked to see the game come up.
197
+ QUIET BY DEFAULT (focus:false, PlayGame agent:true): the user usually works on the same machine, so the EDITOR stays put. It does not switch to the Game tab or take keyboard focus (nor follow the game's later focus report), and skips the render-health self-check that would misread the untouched Game view as a GPU failure and flip the user's embed setting. Quiet play does NOT hide the game: it runs embedded in the Game view (visible if that tab is open) and is the running game for summer_is_running / summer_screenshot target:'game' / summer_get_diagnostics. With "Embed Game on Play" off the game gets its own OS window; engines with --summer-background (0.5.66+) open it without taking focus. The result echoes agent_quiet:true when honoured; without agent_quiet the engine predates quiet play and most likely took focus (posture_note says so). focus:true launches like the toolbar Play button (Game tab + focus): ONLY when the user is watching and asked to see the game come up.
198
198
 
199
- After starting, confirm boot with summer_is_running (boot time varies — never sleep a guessed delay), then summer_get_diagnostics for runtime errors. You can run a specific scene instead of the main scene — useful for testing individual levels or UI screens.
199
+ After starting, confirm boot with summer_is_running (boot time varies; never sleep a guessed delay), then summer_get_diagnostics for runtime errors.
200
200
 
201
- DETERMINISTIC RUNS (newer engines): seed / fixed_fps / time_scale pin THIS launch only (nothing is persisted). seed pins the game's GLOBAL RNG (randi/randf/randi_range/randf_range/randfn, Array.shuffle/pick_random) — it does NOT pin RandomNumberGenerator instances, scripts that call randomize(), rand_from_seed, wall-clock reads, or thread/IO/audio timing. fixed_fps decouples scene time from the wall clock so frame-count-derived state lands on the same frame run to run. The result's \`determinism\` block says whether the pins were applied (applied:false carries a reason: already_running, editor_run_args_override, launch_not_started) and restates seed_scope. If the result has NO determinism block although you sent a pin, the engine predates the params and the run is NOT reproducible — the tool says so; do not claim otherwise. Omitting every pin and instance parameter is exactly the v1 launch.
201
+ DETERMINISTIC RUNS (newer engines): seed / fixed_fps / time_scale pin THIS launch only, nothing persisted. seed pins the GLOBAL RNG only (not RandomNumberGenerator instances, randomize(), rand_from_seed, wall-clock, thread/IO/audio timing). The result's \`determinism\` block says whether the pins applied (applied:false carries a reason: already_running, editor_run_args_override, launch_not_started) and restates seed_scope. NO determinism block although you sent a pin = the engine predates the params and the run is NOT reproducible (the tool says so); never claim otherwise.
202
202
 
203
- PLAYTEST LAUNCH (engine runtime-control build): instance + mode:'offscreen' spawn a disposable hidden instance (at most 3) that summer_game_probe / summer_game_input / summer_game_control / summer_runtime_* address by name — run two variants side by side for an A/B. deterministic:true (offscreen only) launches with --fixed-fps 60 --summer-seed --audio-driver Dummy and is what lets summer_game_input action:'replay' accept a seed; speed sets the user time scale on session start. The instance result reports session_attached; poll summer_game_control action:'instances' until attached:true before addressing it. Then: probe -> act -> step/probe -> assert (the agent-playtesting skill). Failure reasons: too_many_instances, instance_exists, session_timeout (child never attached — check summer_get_console), unsupported_mode, main_scene_not_configured. A game already running answers playing:true with determinism.applied:false — summer_stop first to apply seed/fixed_fps.
203
+ PLAYTEST LAUNCH (engine runtime-control build): instance + mode:'offscreen' spawn a disposable hidden instance (at most 3) that summer_game_probe / summer_game_input / summer_game_control / summer_runtime_* address by name; two side by side make an A/B. deterministic:true (offscreen only) is what lets summer_game_input action:'replay' accept a seed. Poll summer_game_control action:'instances' until attached:true (the result reports session_attached) before addressing it. Then probe -> act -> step/probe -> assert (the agent-playtesting skill). Failure reasons: too_many_instances, instance_exists, session_timeout (child never attached; check summer_get_console), unsupported_mode, main_scene_not_configured. A game already running answers playing:true with determinism.applied:false: summer_stop first to apply seed/fixed_fps.
204
204
 
205
- MULTIPLAYER — LOCAL PLAY (Summer multiplayer games; engine with Local Play): players:N starts the game's authority headless plus N clients on this machine, each joining through the game's OWN Summer.client.join(SummerJoinTarget.queue(...)) — no account, login, Docker, CLI or local-only game code. The scenes and queue come from the project's summer.build.json and its WorldDefinition (client_entry_point + the headless_engine component entry_point); queue picks another declared queue — pass queue WITHOUT players to start that queue's minPlayers (a 4-player queue starts 4), or players to choose; spectators adds spectator clients. local_play.warnings flags a roster outside the queue's minPlayers..maxPlayers. The result's local_play block lists every process (label, role, persona) and the port; failure_reason local_play_unavailable says exactly what to declare. Every process attaches to the editor debugger: screenshots, input and summer_game_* go to the FIRST client, the authority's output is in summer_get_console, and summer_stop stops them all. A join for a different queue fails with a message naming both queues. It is not a proof of sign-in, matchmaking or hosted admission (staging). No local_play block although you sent players means the engine predates Local Play and ran ONE client — the tool says so.`, {
205
+ MULTIPLAYER — LOCAL PLAY (engine with Local Play; the multiplayer-testing skill): players:N starts the game's authority headless plus N clients on this machine, each joining through the game's OWN Summer.client.join(SummerJoinTarget.queue(...)): no account, login, Docker, CLI or local-only game code. Scenes and queue come from summer.build.json's WorldDefinition (client_entry_point, the headless_engine component entry_point). queue picks another declared queue; queue WITHOUT players starts its minPlayers; spectators adds spectator clients. local_play.warnings flags a roster outside minPlayers..maxPlayers. The local_play block lists every process (label, role, persona) and the port; failure_reason local_play_unavailable says what to declare. Every process attaches to the editor debugger: screenshots, input and summer_game_* go to the FIRST client, the authority's output is in summer_get_console, summer_stop stops them all. A join for a different queue fails naming both queues. Not a proof of sign-in, matchmaking or hosted admission (staging). No local_play block although you sent players = the engine predates Local Play and ran ONE client; the tool says so.`, {
206
206
  scene: z.string().optional().describe("Scene to run instead of main scene, e.g. 'res://levels/test_level.tscn'"),
207
207
  ...playGameExtensionSchema,
208
208
  }, async (args) => {
@@ -7,17 +7,17 @@ WHEN — the three asset classes neither generation nor the free library serve w
7
7
  - modular kits with exact dimensions and snapping (walls, pipes, fences, rails: array + boolean + bevel, one shared material) — generation cannot hold size and style across 30 pieces;
8
8
  - VFX meshes (shatter pieces, curve sweeps, trails, LOD chains) — one-liners in bpy, absent in the engine;
9
9
  - post-processing a generated model (decimate -> UV unwrap -> bake) before it goes into the scene.
10
- WHEN NOT: a generic prop (barrel, crate, chair) -> summer_search_assets / summer_import_asset first, then summer_generate_3d; a character or any organic shape -> summer_generate_3d (scripted organic modelling is the documented failure mode); a blockout or placeholder -> summer_run_script primitives/CSG, instant and in-scene. Route with the asset-strategy skill; the fabricating-assets skill carries the bpy rules and recipes.
10
+ WHEN NOT: a generic prop (barrel, crate, chair) -> summer_search_assets / summer_import_asset first, then summer_generate_3d; a character or any organic shape -> summer_generate_3d (scripted organic modelling is the documented failure mode); a blockout or placeholder -> summer_run_script primitives/CSG, instant and in-scene. Route with the asset-strategy skill; the fabricating-assets skill carries the bpy rules, recipes and the fix for each failure_reason.
11
11
 
12
- SCRIPT CONTRACT: 'source' is plain bpy code. Pre-bound names: bpy, bmesh, mathutils, math, Vector, Matrix, Euler. The script must CREATE mesh objects and leave them linked in the scene — do NOT export and do NOT quit (the engine's bootstrap exports for you: modifiers applied at export, Geometry Nodes realized, +Y-up conversion, materials carried as Principled BSDF only, a procedural Base Color baked to a 2K texture; procedural Metallic/Roughness/Normal/Emission are NOT baked and come back in 'warnings'). Objects hidden or render-disabled are treated as helpers (boolean cutters, guides) and are not exported — they are listed in 'skipped'. Model in metres. MESH/CURVE/SURFACE/META/FONT export as meshes, EMPTY/ARMATURE keep hierarchy, cameras and lights are dropped. Name your objects — they become node names.
12
+ SCRIPT CONTRACT: 'source' is plain bpy that must CREATE mesh objects and leave them linked in the scene — do NOT export and do NOT quit. The engine's bootstrap exports for you: modifiers applied, Geometry Nodes realized, +Y-up conversion, materials as Principled BSDF only, a procedural Base Color baked to a 2K texture; procedural Metallic/Roughness/Normal/Emission are NOT baked (see 'warnings'). Hidden or render-disabled objects are helpers (boolean cutters, guides), not exported, listed in 'skipped'. Model in metres. MESH/CURVE/SURFACE/META/FONT export as meshes, EMPTY/ARMATURE keep hierarchy, cameras and lights are dropped. Name your objects — they become node names.
13
13
 
14
- REQUIRES BLENDER on the user's machine (4.2 LTS or newer). Resolution order: 'blender_path' -> SUMMER_BLENDER_BIN in the editor's environment -> Editor Settings filesystem/import/blender/blender_path (shared with .blend import) -> PATH, well-known install dirs, ~/.summer/tools/blender-*. Not found -> failure_reason blender_not_found with the exact fix and every path that was checked; relay it to the user as a one-line decision, never guess a path and never install anything on their behalf.
14
+ REQUIRES BLENDER 4.2 LTS or newer. Resolution: 'blender_path' -> SUMMER_BLENDER_BIN in the editor's environment -> Editor Settings filesystem/import/blender/blender_path -> PATH, well-known install dirs, ~/.summer/tools/blender-*. Not found -> failure_reason blender_not_found with the exact fix and every path checked; relay it to the user as a one-line decision; never guess a path or install anything for them.
15
15
 
16
- ONE fabrication runs at a time per editor (failure_reason busy — wait for the result, never fire two in parallel). Budget max_seconds 15-600 (default 120) covers Blender boot + script + bakes + export; the client waits max_seconds + 60 s. Blind until import: there is no viewport feedback while the script runs, so keep scripts deterministic (fixed seeds) and verify afterwards.
16
+ ONE fabrication runs at a time per editor (failure_reason busy: wait for the result, never fire two in parallel). There is no viewport feedback while the script runs, so keep scripts deterministic (fixed seeds) and verify afterwards.
17
17
 
18
- Returns {ok, ran, blender_version, blender_path, out_path, objects[{name,type,vertices,faces,triangles,materials,modifiers}], object_count, dimensions{x,y,z} (+Y up, source scale), warnings[], baked[], skipped[], output[], errors[], exit_code, duration_ms, checkpoint} plus imported_node_path / scale_applied / instance_dimensions with import_to_scene, and no_rewind_point:true when no checkpoint exists. Failures carry failure_reason: blender_not_found | blender_launch_failed | script_error (traceback_tail + script_line — fix the bpy against the reported blender_version and re-run; bpy APIs change across majors) | timeout (raise max_seconds or split the job) | export_empty (no exportable object — check hide/render flags and collection links) | export_failed | export_missing | import_failed / instantiate_failed (the .glb IS at out_path — summer_instantiate_scene it yourself; the importer's message is in summer_get_console) | busy | cancelled.
18
+ Returns blender_version, blender_path, out_path, objects[{name, type, vertices, faces, triangles, materials, modifiers}], object_count, dimensions{x,y,z} (+Y up, source scale), warnings, baked, skipped, output, errors, exit_code, duration_ms, checkpoint; with import_to_scene also imported_node_path / scale_applied / instance_dimensions; no_rewind_point:true when no checkpoint exists. failure_reason: blender_not_found | blender_launch_failed | script_error (traceback_tail + script_line; fix the bpy for the reported blender_version) | timeout (raise max_seconds or split the job) | export_empty (check hide/render flags and collection links) | export_failed | export_missing | import_failed / instantiate_failed (the .glb IS at out_path: summer_instantiate_scene it yourself; importer message in summer_get_console) | busy | cancelled.
19
19
 
20
- THE LOOP: summer_world_snapshot BEFORE (keep snapshot_id) -> summer_fabricate_3d with import_to_scene (+ target_size for real-world scale) -> read dimensions/warnings/skipped -> summer_snapshot_diff + summer_screenshot -> iterate. Never claim a visual result without the screenshot. If this engine build predates FabricateMesh, the result is a structured engine_lacks_op failure (nothing is sent): use summer_generate_3d / summer_search_assets, or update Summer Engine.`, fabricateArgsSchema.shape, async (args) => withEngine(async (client) => {
20
+ THE LOOP: summer_world_snapshot BEFORE (keep snapshot_id) -> summer_fabricate_3d with import_to_scene (+ target_size for real-world scale) -> read dimensions/warnings/skipped -> summer_snapshot_diff + summer_screenshot -> iterate. Never claim a visual result without the screenshot. An engine build without FabricateMesh returns a structured engine_lacks_op failure (nothing is sent): use summer_generate_3d / summer_search_assets, or update Summer Engine.`, fabricateArgsSchema.shape, async (args) => withEngine(async (client) => {
21
21
  const missing = missingEngineOpResult(client, "FabricateMesh", FABRICATE_FALLBACK);
22
22
  if (missing)
23
23
  return missing;
@@ -8,7 +8,8 @@ import { getAuthToken } from "../../core/auth.js";
8
8
  import { resolveGatewayUrl } from "../../core/config.js";
9
9
  import { readJsonResponse } from "../../core/util/http.js";
10
10
  import { asRecord, stringFrom } from "../../core/util/json.js";
11
- import { TOOLKIT_VERSION as CLI_VERSION } from "../../core/version.js";
11
+ import { summerRequestHeaders } from "../../core/agent-host.js";
12
+ import { codedFailure, codeForStatus, describeNetworkError, networkDetails, NOT_SIGNED_IN, SIGN_IN_AGAIN_RECOVERY, } from "../../core/error-codes.js";
12
13
  const TOOL_BY_ENDPOINT = {
13
14
  "/api/mcp/generate/image": "summer_generate_image",
14
15
  "/api/mcp/generate/audio": "summer_generate_audio",
@@ -72,13 +73,18 @@ async function readLenientJson(res) {
72
73
  return json;
73
74
  return text ? { message: text.slice(0, 1000) } : {};
74
75
  }
76
+ /** The coded failure for a non-OK reply: 401 (token expired) and 402 (no
77
+ * credits) carry the shared codes. */
78
+ function statusFailure(status) {
79
+ const code = codeForStatus(status);
80
+ if (!code)
81
+ return {};
82
+ return code === "not_signed_in" ? { code, recovery: SIGN_IN_AGAIN_RECOVERY } : { code };
83
+ }
75
84
  async function mcpGenerate(endpoint, body, timeoutMs = 120_000) {
76
85
  const token = await getAuthToken();
77
86
  if (!token) {
78
- return {
79
- error: "Not signed in. Run in your terminal:\n npx -y summer-engine@latest login\nOr open: https://www.summerengine.com/login",
80
- status: 401,
81
- };
87
+ return { error: NOT_SIGNED_IN, status: 401, code: "not_signed_in" };
82
88
  }
83
89
  const gatewayUrl = await resolveGatewayUrl();
84
90
  let res;
@@ -86,36 +92,27 @@ async function mcpGenerate(endpoint, body, timeoutMs = 120_000) {
86
92
  res = await fetch(`${gatewayUrl}${endpoint}`, {
87
93
  method: "POST",
88
94
  headers: {
95
+ ...summerRequestHeaders({ tool: TOOL_BY_ENDPOINT[endpoint], surface: "mcp" }),
89
96
  Authorization: `Bearer ${token}`,
90
97
  "Content-Type": "application/json",
91
- "X-Summer-Client": "summer-cli",
92
- "X-Summer-Client-Version": CLI_VERSION,
93
- "X-Summer-Client-Surface": "mcp",
94
98
  "X-Summer-MCP-Endpoint": endpoint,
95
- "X-Summer-MCP-Tool": TOOL_BY_ENDPOINT[endpoint] ?? "unknown",
96
99
  },
97
100
  body: JSON.stringify(body),
98
101
  signal: AbortSignal.timeout(timeoutMs),
99
102
  });
100
103
  }
101
104
  catch (err) {
102
- const msg = err instanceof Error ? err.message : String(err);
103
- return { error: `Generation request failed: ${msg}`, status: 0 };
105
+ return { error: `Generation request failed: ${describeNetworkError(err)}`, status: 0, code: "unavailable", data: networkDetails(err) };
104
106
  }
105
107
  const data = await readLenientJson(res);
106
108
  if (!res.ok) {
107
109
  let message = formattedApiErrorMessage(res.status, data);
108
- if (res.status === 402) {
109
- message =
110
- (data.message || "Insufficient credits.") +
111
- "\nTop up at: https://www.summerengine.com/dashboard\nOr upgrade your plan at: https://www.summerengine.com/pricing";
112
- }
113
- if (res.status === 401) {
114
- message =
115
- (data.message || "Auth token expired.") +
116
- "\nRe-authenticate:\n npx -y summer-engine@latest login";
117
- }
118
- return { error: message, data: { ...data, status: res.status }, status: res.status };
110
+ // The next step (Add credits, sign in again) rides in `recovery`.
111
+ if (res.status === 402)
112
+ message = String(data.message || "Not enough credits.");
113
+ if (res.status === 401)
114
+ message = String(data.message || "Auth token expired.");
115
+ return { error: message, data: { ...data, status: res.status }, status: res.status, ...statusFailure(res.status) };
119
116
  }
120
117
  return { data, status: res.status };
121
118
  }
@@ -127,19 +124,15 @@ async function mcpGet(endpoint, searchParams, timeoutMs = 30_000) {
127
124
  try {
128
125
  res = await fetch(`${gatewayUrl}${endpoint}${suffix}`, {
129
126
  headers: {
127
+ ...summerRequestHeaders({ tool: TOOL_BY_ENDPOINT[endpoint], surface: "mcp" }),
130
128
  ...(token ? { Authorization: `Bearer ${token}` } : {}),
131
- "X-Summer-Client": "summer-cli",
132
- "X-Summer-Client-Version": CLI_VERSION,
133
- "X-Summer-Client-Surface": "mcp",
134
129
  "X-Summer-MCP-Endpoint": endpoint,
135
- "X-Summer-MCP-Tool": TOOL_BY_ENDPOINT[endpoint] ?? "unknown",
136
130
  },
137
131
  signal: AbortSignal.timeout(timeoutMs),
138
132
  });
139
133
  }
140
134
  catch (err) {
141
- const msg = err instanceof Error ? err.message : String(err);
142
- return { error: `Request failed: ${msg}`, status: 0 };
135
+ return { error: `Request failed: ${describeNetworkError(err)}`, status: 0, code: "unavailable", data: networkDetails(err) };
143
136
  }
144
137
  const data = await readLenientJson(res);
145
138
  if (!res.ok) {
@@ -147,6 +140,8 @@ async function mcpGet(endpoint, searchParams, timeoutMs = 30_000) {
147
140
  error: formattedApiErrorMessage(res.status, data),
148
141
  data: { ...data, status: res.status },
149
142
  status: res.status,
143
+ // Without a token a 401 means "sign in", not "sign in again".
144
+ ...(!token && res.status === 401 ? { code: "not_signed_in" } : statusFailure(res.status)),
150
145
  };
151
146
  }
152
147
  return { data, status: res.status };
@@ -158,18 +153,18 @@ async function mcpGet(endpoint, searchParams, timeoutMs = 30_000) {
158
153
  async function pollJob(jobId, maxWaitMs = 600_000, intervalMs = 5_000) {
159
154
  const token = await getAuthToken();
160
155
  if (!token)
161
- return { error: "Not signed in" };
156
+ return { error: NOT_SIGNED_IN, code: "not_signed_in" };
162
157
  const gatewayUrl = await resolveGatewayUrl();
163
158
  const deadline = Date.now() + maxWaitMs;
164
159
  while (Date.now() < deadline) {
165
160
  try {
166
161
  const res = await fetch(`${gatewayUrl}/api/mcp/jobs/${encodeURIComponent(jobId)}`, {
167
- headers: { Authorization: `Bearer ${token}` },
162
+ headers: { ...summerRequestHeaders({ surface: "mcp" }), Authorization: `Bearer ${token}` },
168
163
  signal: AbortSignal.timeout(15_000),
169
164
  });
170
- const data = await res.json();
165
+ const data = await readLenientJson(res);
171
166
  if (!res.ok)
172
- return { error: data.message || "Poll failed", data };
167
+ return { error: data.message || "Poll failed", data, ...statusFailure(res.status) };
173
168
  if (data.status === "completed")
174
169
  return { data };
175
170
  if (data.status === "failed")
@@ -182,23 +177,32 @@ async function pollJob(jobId, maxWaitMs = 600_000, intervalMs = 5_000) {
182
177
  }
183
178
  }
184
179
  catch (err) {
185
- const msg = err instanceof Error ? err.message : String(err);
186
- return { error: `Poll error: ${msg}` };
180
+ return { error: `Poll error: ${describeNetworkError(err)}`, code: "unavailable", data: networkDetails(err) };
187
181
  }
188
182
  }
189
183
  return { error: `Timed out after ${maxWaitMs / 1000}s. Use summer_check_job({ jobId: "${jobId}" }) to check later.` };
190
184
  }
191
- function errorResult(message, extra) {
185
+ /** A failed tool call. With a shared code (core/error-codes.ts) the body is
186
+ * `{ok:false, code, error, recovery, …, message}`; otherwise the older
187
+ * `{error:true, …, message}`. */
188
+ function errorResult(message, extra, coded) {
189
+ const body = coded?.code
190
+ ? codedFailure(coded.code, message, { ...extra, message }, coded.recovery)
191
+ : { error: true, ...extra, message };
192
192
  return {
193
193
  content: [
194
194
  {
195
195
  type: "text",
196
- text: JSON.stringify({ error: true, ...extra, message }, null, 2),
196
+ text: JSON.stringify(body, null, 2),
197
197
  },
198
198
  ],
199
199
  isError: true,
200
200
  };
201
201
  }
202
+ /** The step after a generation job starts (the hosted tools answer the same way). */
203
+ function checkJobNext(jobId) {
204
+ return `The job runs on Summer's servers. Poll summer_check_job({ jobId: "${jobId}" }) every 15-30 seconds until status is "completed".`;
205
+ }
202
206
  function successResult(data) {
203
207
  return {
204
208
  content: [
@@ -232,7 +236,7 @@ handoff that MCP cannot perform automatically; do not pretend that stage ran.`,
232
236
  params.set("id", workflowId);
233
237
  const result = await mcpGet("/api/mcp/workflows", params);
234
238
  if (result.error)
235
- return errorResult(result.error, result.data);
239
+ return errorResult(result.error, result.data, result);
236
240
  return successResult(result.data);
237
241
  });
238
242
  // ========================================================================
@@ -252,7 +256,7 @@ Cloud tool — runs on Summer's servers and works WITHOUT the Summer Engine app
252
256
  Requires authentication: run 'npx -y summer-engine@latest login' first.`, boardArgsSchema.shape, async (args) => {
253
257
  const result = await mcpGet(BOARD_ENDPOINT, boardQuery(args), 45_000);
254
258
  if (result.error)
255
- return errorResult(result.error, result.data);
259
+ return errorResult(result.error, result.data, result);
256
260
  return { content: boardContent(result.data ?? {}) };
257
261
  });
258
262
  // ========================================================================
@@ -307,7 +311,7 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, imageG
307
311
  options,
308
312
  }, IMAGE_GENERATION_TIMEOUT_MS);
309
313
  if (result.error) {
310
- return errorResult(result.error, result.data);
314
+ return errorResult(result.error, result.data, result);
311
315
  }
312
316
  // Download to temp so the AI can Read and show the image
313
317
  const imageUrl = result.data?.asset?.fileUrl || result.data?.asset?.thumbnailUrl;
@@ -343,7 +347,7 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
343
347
  }, async ({ assetId }) => {
344
348
  const result = await mcpGenerate("/api/mcp/generate/slice-asset-sheet", { assetId }, 300_000);
345
349
  if (result.error) {
346
- return errorResult(result.error, result.data);
350
+ return errorResult(result.error, result.data, result);
347
351
  }
348
352
  return successResult({
349
353
  ...result.data,
@@ -442,7 +446,7 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
442
446
  body.options = options;
443
447
  const result = await mcpGenerate("/api/mcp/generate/audio", body);
444
448
  if (result.error) {
445
- return errorResult(result.error, result.data);
449
+ return errorResult(result.error, result.data, result);
446
450
  }
447
451
  return successResult(result.data);
448
452
  });
@@ -533,8 +537,9 @@ For a complete animated humanoid package, pass rig=true plus animationNames or
533
537
  actionIds. This routes through the shared character pipeline instead of a
534
538
  one-off mesh job.
535
539
 
536
- By default, waits for completion (up to 10 min) and returns the result directly.
537
- Set wait=false to get the jobId immediately and poll manually with summer_check_job.
540
+ Returns a jobId within seconds. Poll summer_check_job with it until status is
541
+ "completed" (most models take 1-5 minutes; tell the user it is running and keep
542
+ working meanwhile). wait=true blocks up to 10 minutes instead.
538
543
 
539
544
  Cloud tool — runs on Summer's servers and works WITHOUT the Summer Engine app open.
540
545
  Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
@@ -589,8 +594,8 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
589
594
  .describe("Character height used by auto-rigging"),
590
595
  wait: z
591
596
  .boolean()
592
- .default(true)
593
- .describe("Wait for completion (default true, up to 10 min). Set false to get jobId immediately."),
597
+ .default(false)
598
+ .describe("Block until the job finishes (up to 10 min) and return the result. Default false returns the jobId at once; poll summer_check_job."),
594
599
  options: z
595
600
  .record(z.any())
596
601
  .optional()
@@ -616,17 +621,17 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
616
621
  options: mergedOptions,
617
622
  });
618
623
  if (result.error) {
619
- return errorResult(result.error, result.data);
624
+ return errorResult(result.error, result.data, result);
620
625
  }
621
626
  const jobId = result.data?.jobId;
622
- // If not waiting or no jobId, return immediately
627
+ // The job runs on Summer's servers; the agent polls summer_check_job.
623
628
  if (!wait || !jobId) {
624
- return successResult(result.data);
629
+ return successResult(jobId ? { ...result.data, next: checkJobNext(jobId) } : result.data);
625
630
  }
626
- // Auto-poll until done
631
+ // wait=true: block until done
627
632
  const pollResult = await pollJob(jobId);
628
633
  if (pollResult.error) {
629
- return errorResult(pollResult.error, { ...pollResult.data, jobId });
634
+ return errorResult(pollResult.error, { ...pollResult.data, jobId }, pollResult);
630
635
  }
631
636
  return successResult({
632
637
  ...pollResult.data,
@@ -688,7 +693,7 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
688
693
  options,
689
694
  });
690
695
  if (result.error) {
691
- return errorResult(result.error, result.data);
696
+ return errorResult(result.error, result.data, result);
692
697
  }
693
698
  return successResult(result.data);
694
699
  });
@@ -697,9 +702,10 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
697
702
  // ========================================================================
698
703
  server.tool("summer_check_job", `Check the status of an async generation job.
699
704
 
700
- Use this when you called summer_generate_3d with wait=false, or need to re-check
701
- a job that timed out. Most of the time you won't need this — summer_generate_3d
702
- waits automatically.
705
+ summer_generate_3d and summer_generate_motion return a jobId; call this with it
706
+ every 15-30 seconds until status is "completed" or "failed". A completed job
707
+ carries the result: assetId (3D), rigAssetId (rig=true), animationAssetId or
708
+ result.assets (motion), with file URLs. Import with summer_import_asset_by_id.
703
709
 
704
710
  Status values: waiting, active, completed, failed, delayed, unknown.
705
711
 
@@ -709,24 +715,24 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
709
715
  }, async ({ jobId }) => {
710
716
  const token = await getAuthToken();
711
717
  if (!token) {
712
- return errorResult("Not signed in. Run: npx -y summer-engine@latest login");
718
+ return errorResult(NOT_SIGNED_IN, undefined, { code: "not_signed_in" });
713
719
  }
720
+ let res;
714
721
  try {
715
722
  const gatewayUrl = await resolveGatewayUrl();
716
- const res = await fetch(`${gatewayUrl}/api/mcp/jobs/${encodeURIComponent(jobId)}`, {
717
- headers: { Authorization: `Bearer ${token}` },
723
+ res = await fetch(`${gatewayUrl}/api/mcp/jobs/${encodeURIComponent(jobId)}`, {
724
+ headers: { ...summerRequestHeaders({ surface: "mcp" }), Authorization: `Bearer ${token}` },
718
725
  signal: AbortSignal.timeout(15_000),
719
726
  });
720
- const data = await res.json();
721
- if (!res.ok) {
722
- return errorResult(data.message || data.error || "Failed to check job status", data);
723
- }
724
- return successResult(data);
725
727
  }
726
728
  catch (err) {
727
- const msg = err instanceof Error ? err.message : String(err);
728
- return errorResult(`Job status check failed: ${msg}`);
729
+ return errorResult(`Job status check failed: ${describeNetworkError(err)}`, networkDetails(err), { code: "unavailable" });
730
+ }
731
+ const data = await readLenientJson(res);
732
+ if (!res.ok) {
733
+ return errorResult(data.message || data.error || "Failed to check job status", data, statusFailure(res.status));
729
734
  }
735
+ return successResult(data);
730
736
  });
731
737
  // ========================================================================
732
738
  // summer_generate_motion
@@ -763,9 +769,9 @@ Each clip (meshy: each motion; text-to-motion: each prompt x take) is billed.
763
769
  State the clip list and estimated cost and confirm with the user before
764
770
  spending.
765
771
 
766
- By default, waits for completion (up to 10 min) and returns the result directly.
767
- Set wait=false to get the jobId immediately and poll with summer_check_job.
768
- Import finished clips with summer_import_asset_by_id.
772
+ Returns a jobId within seconds. Poll summer_check_job with it until status is
773
+ "completed" (wait=true blocks up to 10 minutes instead). Import finished clips
774
+ with summer_import_asset_by_id.
769
775
 
770
776
  Errors: backend_unavailable means text-to-motion is not enabled on this server
771
777
  yet — use meshy-library for humanoids and do not retry. Job failures starting
@@ -782,16 +788,16 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, motion
782
788
  const result = await mcpGenerate("/api/mcp/generate/motion", built.body);
783
789
  if (result.error) {
784
790
  const hint = motionErrorHint(result.data?.error);
785
- return errorResult(result.error, hint ? { ...result.data, hint } : result.data);
791
+ return errorResult(result.error, hint ? { ...result.data, hint } : result.data, result);
786
792
  }
787
793
  const jobId = result.data?.jobId;
788
794
  if (!args.wait || !jobId) {
789
- return successResult(result.data);
795
+ return successResult(jobId ? { ...result.data, next: checkJobNext(jobId) } : result.data);
790
796
  }
791
797
  const pollResult = await pollJob(jobId);
792
798
  if (pollResult.error) {
793
799
  const hint = motionJobFailureHint(pollResult.error);
794
- return errorResult(pollResult.error, { ...pollResult.data, jobId, ...(hint ? { hint } : {}) });
800
+ return errorResult(pollResult.error, { ...pollResult.data, jobId, ...(hint ? { hint } : {}) }, pollResult);
795
801
  }
796
802
  return successResult({
797
803
  ...pollResult.data,
@@ -5,12 +5,17 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
5
  * share ONE implementation. The MCP surface contributes the boot drift notice
6
6
  * it owns. Exported for tests.
7
7
  */
8
- export declare function buildAgentPlaybook(): Record<string, unknown>;
9
- export declare function renderAgentPlaybook(): string;
8
+ export declare function buildAgentPlaybook(options?: ProjectToolsOptions): Record<string, unknown>;
9
+ export declare function renderAgentPlaybook(options?: ProjectToolsOptions): string;
10
+ /** What the session's profile serves. `engine: false` (the assets profile)
11
+ * turns the playbook and the task plan into their no-engine versions. */
12
+ export interface ProjectToolsOptions {
13
+ engine?: boolean;
14
+ }
10
15
  /**
11
16
  * Register the playbook as an MCP PROMPT as well, so hosts that surface
12
17
  * prompts (prompt pickers, slash commands) get the operating guide natively
13
18
  * without knowing to call the tool. Same content, second doorway.
14
19
  */
15
- export declare function registerPlaybookPrompt(server: McpServer): void;
16
- export declare function registerProjectTools(server: McpServer): void;
20
+ export declare function registerPlaybookPrompt(server: McpServer, options?: ProjectToolsOptions): void;
21
+ export declare function registerProjectTools(server: McpServer, options?: ProjectToolsOptions): void;
@@ -38,37 +38,42 @@ function getScenePathFromSceneState(sceneState) {
38
38
  * share ONE implementation. The MCP surface contributes the boot drift notice
39
39
  * it owns. Exported for tests.
40
40
  */
41
- export function buildAgentPlaybook() {
41
+ export function buildAgentPlaybook(options = {}) {
42
42
  return buildCoreAgentPlaybook({
43
43
  summerUpdateNotice: getCachedBootDriftNotice()?.text ?? null,
44
+ engine: options.engine,
44
45
  });
45
46
  }
46
- export function renderAgentPlaybook() {
47
- return JSON.stringify(buildAgentPlaybook(), null, 2);
47
+ export function renderAgentPlaybook(options = {}) {
48
+ return JSON.stringify(buildAgentPlaybook(options), null, 2);
48
49
  }
49
50
  /**
50
51
  * Register the playbook as an MCP PROMPT as well, so hosts that surface
51
52
  * prompts (prompt pickers, slash commands) get the operating guide natively
52
53
  * without knowing to call the tool. Same content, second doorway.
53
54
  */
54
- export function registerPlaybookPrompt(server) {
55
+ export function registerPlaybookPrompt(server, options = {}) {
55
56
  server.registerPrompt("summer_agent_playbook", {
56
- title: "Summer Engine agent playbook",
57
- description: "AI-first operating guide for the Summer Engine MCP tools: observe-first loop, screenshot before/after every mutation, content routing (reuse -> import -> generate -> script last), physical invariants, cost rules, verification ritual, honesty rules, and recovery steps.",
57
+ title: options.engine === false ? "Summer assets playbook" : "Summer Engine agent playbook",
58
+ description: options.engine === false
59
+ ? "Operating guide for the Summer assets tools without Summer Engine: ask what the asset is for, reuse before generating, confirm spend, check the preview, hand over the file."
60
+ : "AI-first operating guide for the Summer Engine MCP tools: observe-first loop, screenshot before/after every mutation, content routing (reuse -> import -> generate -> script last), physical invariants, cost rules, verification ritual, honesty rules, and recovery steps.",
58
61
  }, async () => ({
59
62
  messages: [
60
63
  {
61
64
  role: "user",
62
65
  content: {
63
66
  type: "text",
64
- text: "Operate Summer Engine by this playbook for the rest of the session:\n\n" +
65
- renderAgentPlaybook(),
67
+ text: (options.engine === false
68
+ ? "Work with the Summer assets tools by this playbook for the rest of the session:\n\n"
69
+ : "Operate Summer Engine by this playbook for the rest of the session:\n\n") +
70
+ renderAgentPlaybook(options),
66
71
  },
67
72
  },
68
73
  ],
69
74
  }));
70
75
  }
71
- export function registerProjectTools(server) {
76
+ export function registerProjectTools(server, options = {}) {
72
77
  server.tool("summer_start_game_task", `Start here for any substantial AI game-building task.
73
78
 
74
79
  Takes the user's goal and returns the recommended Summer workflow: skill routes,
@@ -102,6 +107,7 @@ mutating the project.`, {
102
107
  target,
103
108
  assetPolicy,
104
109
  verification,
110
+ engine: options.engine,
105
111
  }), null, 2),
106
112
  },
107
113
  ],
@@ -115,7 +121,7 @@ ladder, honesty rules, anti-patterns, and recovery steps.`, {}, async () => ({
115
121
  content: [
116
122
  {
117
123
  type: "text",
118
- text: renderAgentPlaybook(),
124
+ text: renderAgentPlaybook(options),
119
125
  },
120
126
  ],
121
127
  }));