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
@@ -0,0 +1,443 @@
1
+ import { ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
2
+ import { z } from "zod";
3
+ import { localEntries, localInputSchema, localWireForm, missingInput } from "../core/ops/catalog.js";
4
+ import { answerOfHosted, hostedCallFailure, searchEverywhere } from "../core/ops/cloud.js";
5
+ import { errorAnswer, isLocalOp, legacyNames, localToolsFor, mcpNameOf, resolveOpName } from "../core/ops/contract.js";
6
+ import { ENGINE_SPLIT_OPS, engineOpDef, isSplitOp, renderOpRefs, splitToolArgs } from "../core/ops/engine.js";
7
+ import { answerOfEngineResult, engineFailure, textsOf } from "../core/ops/engine-answer.js";
8
+ import { TAKES_OUT, withOutField } from "../core/ops/save-files.js";
9
+ import { loadLibraryIndex } from "../core/library-search.js";
10
+ import { FOOTER_SUFFIX } from "../core/library-read.js";
11
+ /**
12
+ * The v4 surface of the local MCP (`summer mcp --surface v4`, SUMMER_SURFACE=v4):
13
+ * one catalog of Summer operations instead of one tool per feature.
14
+ *
15
+ * - Listed: the engine operations under their 3.x names (the core build loop
16
+ * keeps its tools) plus the operations split out of mixed 3.x tools,
17
+ * docs.search and docs.read, the hosted server's direct tools (mounted from
18
+ * its v4 surface), summer_search and summer_call.
19
+ * - An engine tool here is its operation: a short summary (the how-to is its
20
+ * guide, docs.read tool/<slug>), annotations from its effect, and the one
21
+ * answer shape, with engine_not_running and the other codes instead of
22
+ * plain text.
23
+ * - Every other local 3.x tool stays registered but unlisted: summer_call
24
+ * runs it by its operation name or its old name, through the same handler.
25
+ * The legacy toolset lists them again under their 3.x names.
26
+ * - Cloud operations run on the hosted server: summer_call forwards them to
27
+ * the hosted summer_call with the person's sign-in; summer_search merges
28
+ * the hosted hits with the local ones.
29
+ */
30
+ export const SUMMER_SEARCH = "summer_search";
31
+ export const SUMMER_CALL = "summer_call";
32
+ export const OPS_MCP_INSTRUCTIONS = "Summer Engine MCP, operation catalog. Call summer_get_project_context first when Summer Engine is open. " +
33
+ "Listed tools are the common jobs; for anything else, summer_search describes the job in words and returns the operation and its exact input, then summer_call runs it. " +
34
+ "More than 3 scene edits: one summer_run_script with scenePath. Each engine tool's full guide: summer_docs_read. Long work answers with a job: jobs.wait. " +
35
+ "Publishing, prices and other live changes answer needs_approval with a link: give it to the person; nothing changes until they approve.";
36
+ /** The assets profile's version: no engine tools, so it names none. */
37
+ export const OPS_MCP_ASSETS_INSTRUCTIONS = "Summer MCP, assets profile, operation catalog: generation and the Summer asset library, no engine tools. " +
38
+ "Read skill/summer-assets with summer_docs_read, then the asset's skill: stop at the file, skip its engine steps. " +
39
+ "For a job no listed tool does, summer_search returns the operation and its exact input, then summer_call runs it. " +
40
+ "Generation costs credits: confirm first (dryRun shows the estimate). Long work answers with a job: jobs.wait. " +
41
+ "Files save into the project's asset folder, or the folder in out; the answer gives localPath.";
42
+ const DOCS_ALIASES = [
43
+ ["summer_docs_search", "summer_search_library"],
44
+ ["summer_docs_read", "summer_read_library"],
45
+ ];
46
+ /** Listed with the engine tools although its operation is docs.engine_api: the offline engine class reference. */
47
+ const ENGINE_REFERENCE = "summer_api_docs";
48
+ /** Its v4 description, within the 300-character summary rule; the full text stays on the 3.x surface. */
49
+ export const ENGINE_REFERENCE_SUMMARY = "Look up an engine class offline before writing script code: inherits, properties, methods, signals and constants, or one member. Lists only members declared on that class (walk inherits). No engine needed. Next: summer_run_script.";
50
+ /** The read footer in this surface's words: feedback goes through summer_call (docs.feedback is not listed). */
51
+ export const V4_FOOTER_SUFFIX = 'If this entry is wrong, stale, or you deviate from it, report via summer_call {"op":"docs.feedback"}.';
52
+ /** A library read's result with the v4 footer (and the v4 names in its description of the footer). */
53
+ function withV4Footer(result) {
54
+ const record = result;
55
+ if (!record || !Array.isArray(record.content))
56
+ return result;
57
+ return {
58
+ ...record,
59
+ content: record.content.map((part) => part.type === "text" && typeof part.text === "string" ? { ...part, text: part.text.split(FOOTER_SUFFIX).join(V4_FOOTER_SUFFIX) } : part),
60
+ };
61
+ }
62
+ const LIBRARY_READS = new Set(["summer_read_library", "summer_get_agent_playbook"]);
63
+ /** The answer as tool content: compact JSON text (plus any image the tool returned) and structured content. */
64
+ function toolResult(answer, raw) {
65
+ const content = raw && typeof raw === "object" ? raw.content : undefined;
66
+ const images = Array.isArray(content) ? content.filter((part) => part?.type === "image") : [];
67
+ return {
68
+ content: [{ type: "text", text: JSON.stringify(answer) }, ...images],
69
+ // A client that reads structuredContent alone would drop the image.
70
+ ...(images.length ? {} : { structuredContent: answer }),
71
+ ...(answer.ok ? {} : { isError: true }),
72
+ };
73
+ }
74
+ /** A non-engine local 3.x tool's result as the one answer shape (a few, such as apps.dock, still need the engine). */
75
+ function answerOfLocal(result, op, effect) {
76
+ const record = (result && typeof result === "object" ? result : {});
77
+ const [first = ""] = textsOf(result);
78
+ if (record.isError) {
79
+ const engine = engineFailure(textsOf(result).join("\n\n"), op, { effect });
80
+ if (!engine.ok && ["engine_not_running", "engine_lacks_op", "conflict"].includes(engine.error.code))
81
+ return engine;
82
+ }
83
+ let payload = first;
84
+ try {
85
+ payload = JSON.parse(first);
86
+ }
87
+ catch {
88
+ payload = first ? { text: first } : {};
89
+ }
90
+ if (record.isError) {
91
+ const body = (payload && typeof payload === "object" ? payload : {});
92
+ const message = typeof body.message === "string" ? body.message : typeof body.error === "string" ? body.error : first.slice(0, 500) || "The tool failed.";
93
+ const details = { tool: payload };
94
+ if (/not found|does not exist|no such/i.test(message))
95
+ return errorAnswer("not_found", message, { details });
96
+ return errorAnswer("invalid_input", message, { details });
97
+ }
98
+ return { ok: true, status: "done", result: payload };
99
+ }
100
+ /** MCP annotations from an operation's effect (SPEC §4.1); engine operations never need a retry key. */
101
+ export function annotationsForEffect(effect, openWorld, title) {
102
+ return effect === "read"
103
+ ? { title, readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: openWorld }
104
+ : { title, readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: openWorld };
105
+ }
106
+ /** Library slug, summary and network authority of each local tool (registry/generated/index.json). */
107
+ function toolFacts() {
108
+ const out = new Map();
109
+ for (const entry of loadLibraryIndex()) {
110
+ if (entry.kind !== "tool" || !entry.mcp_tool_name)
111
+ continue;
112
+ out.set(entry.mcp_tool_name, { slug: entry.id.replace(/^tool\//, ""), summary: entry.summary ?? "", network: Boolean(entry.authority?.network) });
113
+ }
114
+ return out;
115
+ }
116
+ const PARAM_LIMIT = 200;
117
+ /** A sentence end: not the dot of "e.g.", "i.e." or "etc.", and followed by a new sentence. */
118
+ const SENTENCE_END = /(?<!\be\.g|\bi\.e|\betc)[.!?](?=\s+["'`(A-Z0-9])/g;
119
+ /** A parameter description cut to its whole sentences within PARAM_LIMIT characters; the guide has it whole. */
120
+ export function shortParamDescription(text) {
121
+ const clean = text.trim();
122
+ if (clean.length <= PARAM_LIMIT)
123
+ return clean;
124
+ let cut = -1;
125
+ for (const match of clean.matchAll(SENTENCE_END)) {
126
+ if (match.index + 1 > PARAM_LIMIT)
127
+ break;
128
+ cut = match.index + 1;
129
+ }
130
+ return cut >= 40 ? clean.slice(0, cut) : `${clean.slice(0, PARAM_LIMIT).replace(/\s+\S*$/, "")}…`;
131
+ }
132
+ /** 3.x tool names that shared descriptions mention, as this surface lists them. */
133
+ const V4_NAMES = [
134
+ [/summer_camera_bookmark(?: \(list them with action:"list"\))?/g, "summer_engine_save_camera_bookmark (list: summer_engine_list_camera_bookmarks)"],
135
+ [/summer_read_library/g, "summer_docs_read"],
136
+ [/summer_search_library/g, "summer_docs_search"],
137
+ [/summer_library_feedback/g, 'summer_call {"op":"docs.feedback"}'],
138
+ ];
139
+ export function v4Text(text) {
140
+ return V4_NAMES.reduce((out, [pattern, name]) => out.replace(pattern, name), text);
141
+ }
142
+ /** A schema's descriptions in this surface's words, cut to whole sentences when `short`. */
143
+ function v4Schema(schema, short) {
144
+ if (!schema || typeof schema !== "object" || Array.isArray(schema))
145
+ return schema;
146
+ const record = schema;
147
+ const out = { ...record };
148
+ if (typeof record.description === "string")
149
+ out.description = v4Text(short ? shortParamDescription(record.description) : record.description);
150
+ if (record.properties && typeof record.properties === "object") {
151
+ out.properties = Object.fromEntries(Object.entries(record.properties).map(([key, value]) => [key, v4Schema(value, short)]));
152
+ }
153
+ if (record.items)
154
+ out.items = v4Schema(record.items, short);
155
+ for (const key of ["anyOf", "oneOf", "allOf"])
156
+ if (Array.isArray(record[key]))
157
+ out[key] = record[key].map((branch) => v4Schema(branch, short));
158
+ return out;
159
+ }
160
+ export function applyOpsSurface(server, options) {
161
+ const tools = server._registeredTools;
162
+ const names = legacyNames();
163
+ const facts = toolFacts();
164
+ const entries = new Map(localEntries().map((entry) => [entry.name, entry]));
165
+ /** The 3.x handler of each engine tool, before the v4 answer wraps it (summer_call runs these). */
166
+ const rawHandlers = new Map();
167
+ /** Tools listed with the v4 engine shape; their parameter descriptions are cut in tools/list. */
168
+ const engineTools = new Set();
169
+ // docs.search and docs.read under their 4.0 names, same handlers.
170
+ for (const [alias, original] of DOCS_ALIASES) {
171
+ const tool = tools[original];
172
+ if (!tool || tools[alias])
173
+ continue;
174
+ const shape = tool.inputSchema?.shape ?? {};
175
+ server.tool(alias, v4Text(tool.description ?? ""), shape, tool.annotations ?? {}, (async (args, extra) => {
176
+ const result = await tool.handler(args, extra);
177
+ return LIBRARY_READS.has(original) ? withV4Footer(result) : result;
178
+ }));
179
+ }
180
+ // Engine tools (and the operations split out of the two mixed ones) are listed with the v4 shape.
181
+ const mixed = new Set(Object.values(ENGINE_SPLIT_OPS).map((def) => def.tool));
182
+ const splitByTool = new Map(Object.keys(ENGINE_SPLIT_OPS).map((op) => [mcpNameOf(op), op]));
183
+ const listed = new Set(DOCS_ALIASES.map(([alias]) => alias));
184
+ if (options.engine) {
185
+ for (const name of Object.keys(tools)) {
186
+ if (!names[name]?.op.startsWith("engine.") || mixed.has(name))
187
+ continue;
188
+ engineTools.add(name);
189
+ listed.add(name);
190
+ }
191
+ for (const [op, def] of Object.entries(ENGINE_SPLIT_OPS)) {
192
+ if (!tools[def.tool])
193
+ continue;
194
+ engineTools.add(mcpNameOf(op));
195
+ listed.add(mcpNameOf(op));
196
+ }
197
+ if (tools[ENGINE_REFERENCE]) {
198
+ listed.add(ENGINE_REFERENCE);
199
+ tools[ENGINE_REFERENCE].update({ title: "Look up an engine class", description: ENGINE_REFERENCE_SUMMARY });
200
+ }
201
+ }
202
+ /** The tool that runs an operation in this session, for summaries that name it. */
203
+ const toolOf = (op) => {
204
+ if (op === "docs.search")
205
+ return "summer_docs_search";
206
+ if (op === "docs.read")
207
+ return "summer_docs_read";
208
+ const tool = isSplitOp(op) ? mcpNameOf(op) : entries.get(op)?.mcpTool;
209
+ return tool && listed.has(tool) ? tool : undefined;
210
+ };
211
+ const guideOf = (toolName) => {
212
+ const slug = facts.get(toolName)?.slug;
213
+ return slug ? `tool/${slug}` : undefined;
214
+ };
215
+ const describe = (op, toolName) => {
216
+ const def = engineOpDef(op);
217
+ const guide = guideOf(toolName);
218
+ return `${renderOpRefs(def.summary, toolOf)}${guide ? `\nGuide: summer_docs_read {"id":"${guide}"}` : ""}`;
219
+ };
220
+ for (const name of engineTools) {
221
+ const tool = tools[name];
222
+ const op = names[name]?.op;
223
+ const def = op ? engineOpDef(op) : null;
224
+ if (!tool || !op || !def)
225
+ continue; // split tools are registered below
226
+ const handler = tool.handler;
227
+ rawHandlers.set(name, handler);
228
+ const answerOptions = { effect: def.effect, guide: guideOf(name) };
229
+ tool.update({
230
+ title: def.title,
231
+ description: describe(op, name),
232
+ annotations: annotationsForEffect(def.effect, Boolean(facts.get(name)?.network), def.title),
233
+ callback: (async (...args) => {
234
+ const raw = await handler(...args);
235
+ return toolResult(answerOfEngineResult(raw, op, answerOptions), raw);
236
+ }),
237
+ });
238
+ }
239
+ // Operations split out of a mixed 3.x tool: their own tool, the 3.x handler with the action fixed.
240
+ for (const [op, def] of Object.entries(ENGINE_SPLIT_OPS)) {
241
+ const base = tools[def.tool];
242
+ if (!options.engine || !base)
243
+ continue;
244
+ const shape = splitShape(def, base.inputSchema?.shape ?? {});
245
+ const answerOptions = { effect: def.effect, guide: guideOf(def.tool) };
246
+ server.tool(mcpNameOf(op), describe(op, def.tool), shape, annotationsForEffect(def.effect, Boolean(facts.get(def.tool)?.network), def.title), (async (args, extra) => {
247
+ const raw = await base.handler(splitToolArgs(def, args ?? {}), extra);
248
+ return toolResult(answerOfEngineResult(raw, op, answerOptions), raw);
249
+ }));
250
+ tools[mcpNameOf(op)].update({ title: def.title });
251
+ }
252
+ // The rest stay callable; the legacy toolset lists them under their 3.x names.
253
+ for (const [name, tool] of Object.entries(tools)) {
254
+ if (listed.has(name))
255
+ continue;
256
+ const op = names[name]?.op;
257
+ if (!options.legacy || !op) {
258
+ tool.disable();
259
+ continue;
260
+ }
261
+ const use = mixed.has(name)
262
+ ? Object.entries(ENGINE_SPLIT_OPS).filter(([, def]) => def.tool === name).map(([splitOp]) => toolOf(splitOp) ?? splitOp).join(", ")
263
+ : op;
264
+ tool.update({ description: `3.x name; use ${use}. ${renderOpRefs(entries.get(op)?.summary ?? facts.get(name)?.summary ?? "", toolOf)}`.trim() });
265
+ }
266
+ // tools/list: local tools name tools as this surface lists them, and an engine tool's
267
+ // parameter descriptions are cut to whole sentences (the guide has them whole).
268
+ const handlers = server.server._requestHandlers;
269
+ const listTools = handlers.get("tools/list");
270
+ if (listTools) {
271
+ server.server.setRequestHandler(ListToolsRequestSchema, async (request, extra) => {
272
+ const result = await listTools(request, extra);
273
+ return {
274
+ ...result,
275
+ tools: result.tools.map((tool) => (listed.has(tool.name) ? { ...tool, inputSchema: v4Schema(tool.inputSchema, engineTools.has(tool.name)) } : tool)),
276
+ };
277
+ });
278
+ }
279
+ /** The tool and arguments that run a local operation here, or null. */
280
+ function localCall(name, resolved, input) {
281
+ const split = ENGINE_SPLIT_OPS[resolved];
282
+ // A split operation runs its 3.x tool with the action fixed; called by that 3.x name, it runs as called.
283
+ if (split && name !== split.tool)
284
+ return tools[split.tool] ? { tool: split.tool, args: splitToolArgs(split, input), split: true } : null;
285
+ if (tools[name])
286
+ return { tool: name, args: input };
287
+ const own = entries.get(resolved)?.mcpTool;
288
+ const tool = own && tools[own] ? own : localToolsFor(resolved).find((candidate) => tools[candidate]);
289
+ return tool ? { tool, args: input } : null;
290
+ }
291
+ async function validate(toolName, args, op) {
292
+ const schema = tools[toolName].inputSchema;
293
+ if (!schema?.safeParseAsync)
294
+ return { data: undefined };
295
+ const parsed = await schema.safeParseAsync(args);
296
+ if (parsed.success)
297
+ return { data: parsed.data };
298
+ const issue = parsed.error?.issues[0];
299
+ const path = issue?.path.join(".") || "(input)";
300
+ const guide = guideOf(toolName);
301
+ return {
302
+ error: errorAnswer("invalid_input", `${path}: ${issue?.message ?? "invalid value"}.`, {
303
+ details: { path },
304
+ next: guide && op.startsWith("engine.") ? { op: "docs.read", input: { id: guide } } : { op: "ops.describe", input: { name: op } },
305
+ }),
306
+ };
307
+ }
308
+ async function runLocal(op, call, extra, dryRun, input) {
309
+ const { tool: toolName, args } = call;
310
+ // A split operation's own fields first: its 3.x tool took them as optional (its fixed action may come along; it is replaced).
311
+ const split = call.split ? ENGINE_SPLIT_OPS[op] : undefined;
312
+ const missing = split ? missingInput(localInputSchema(op), Object.fromEntries(Object.entries(input).filter(([key]) => !(key in split.fixed)))) : null;
313
+ if (missing) {
314
+ const guide = guideOf(toolName);
315
+ return errorAnswer("invalid_input", missing, { next: guide ? { op: "docs.read", input: { id: guide } } : { op: "ops.describe", input: { name: op } } });
316
+ }
317
+ const checked = await validate(toolName, args, op);
318
+ if ("error" in checked)
319
+ return checked.error;
320
+ const entry = entries.get(op);
321
+ if (dryRun) {
322
+ // The default dry run (SPEC §5.3): the input is checked and the call described; nothing reaches the engine.
323
+ const target = typeof args.scenePath === "string" ? ` on ${args.scenePath}` : typeof args.path === "string" ? ` on ${args.path}` : "";
324
+ return {
325
+ ok: true,
326
+ status: "dry_run",
327
+ preview: { summary: `${entry?.title ?? op}${target}: the input is valid. Nothing was done.`, changes: [], approval: entry?.approval ?? "none", estimate: null, valid: true },
328
+ };
329
+ }
330
+ const handler = rawHandlers.get(toolName) ?? tools[toolName].handler;
331
+ const result = checked.data === undefined ? await handler(extra) : await handler(checked.data, extra);
332
+ const raw = LIBRARY_READS.has(toolName) ? withV4Footer(result) : result;
333
+ const def = engineOpDef(op);
334
+ return def ? answerOfEngineResult(raw, op, { effect: def.effect, guide: guideOf(toolName) }) : answerOfLocal(raw, op, entry?.effect === "read" ? "read" : "write");
335
+ }
336
+ async function search(query, area, limit) {
337
+ const { items, warning } = await searchEverywhere(query, { area, limit }, (name, args) => options.cloud.call(name, args), (toolName) => tools[toolName]?.enabled === true);
338
+ return { ok: true, status: "done", result: { items }, ...(warning ? { warnings: [warning] } : {}) };
339
+ }
340
+ server.tool(SUMMER_SEARCH, "Find any Summer operation by describing the job in plain words: engine, assets, store, pricing, analytics and the rest. Returns the best matches with their exact input schema, effect and approval. Next: summer_call with the name.", {
341
+ query: z.string().min(1).max(300).describe('The job in plain words: "lower my game\'s price", "add a light to the scene".'),
342
+ area: z.string().regex(/^[a-z]+$/).optional().describe("Only this area: engine, assets, store, pricing, analytics..."),
343
+ limit: z.number().int().min(1).max(20).optional().describe("Most results (default 5)."),
344
+ }, { title: "Find a Summer operation", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, (async ({ query, area, limit }) => toolResult(await search(query, area, limit ?? 5))));
345
+ server.tool(SUMMER_CALL, "Run any Summer operation by name (from summer_search) with its input. Engine operations run here; cloud ones run on Summer's server with the same approvals: money, publishing and live changes answer needs_approval with a link. 3.x tool names work too.", {
346
+ op: z.string().min(1).max(80).describe("The operation name, e.g. engine.add_node or pricing.set_base (or a 3.x tool name)."),
347
+ input: z.record(z.unknown()).optional().describe("The operation's input, matching the schema summer_search returned."),
348
+ dryRun: z.boolean().optional().describe("Check and describe the call without doing it."),
349
+ idempotencyKey: z.string().min(1).max(128).optional().describe("Retry key for writes; reuse it only to retry the identical call."),
350
+ }, { title: "Run a Summer operation", readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true }, (async ({ op, input, dryRun, idempotencyKey }, extra) => {
351
+ const name = op.trim();
352
+ const args = input ?? {};
353
+ // A split operation's own tool name, or a mixed 3.x tool whose action picks the operation.
354
+ const action = typeof args.action === "string" ? args.action : typeof args.mode === "string" ? args.mode : undefined;
355
+ const resolved = splitByTool.get(name) ?? (action ? names[`${name}#${action}`]?.op : undefined) ?? resolveOpName(name);
356
+ // The catalog itself: local operations are searched and described here as well.
357
+ if (resolved === "ops.search" && typeof args.query === "string") {
358
+ return toolResult(await search(args.query, typeof args.area === "string" ? args.area : undefined, typeof args.limit === "number" ? args.limit : 5));
359
+ }
360
+ if (resolved === "ops.describe" && typeof args.name === "string" && isLocalOp(resolveOpName(args.name))) {
361
+ const wire = localWireForm(resolveOpName(args.name));
362
+ return toolResult(wire
363
+ ? { ok: true, status: "done", result: { operation: wire } }
364
+ : errorAnswer("not_found", `No operation is named "${args.name}".`, { next: { op: "ops.search", input: { query: args.name } } }));
365
+ }
366
+ // A 3.x name this server registers runs its 3.x tool unchanged (local
367
+ // options such as summer_app_publish's dir keep working), wherever its
368
+ // 4.0 operation runs.
369
+ if (names[name] && tools[name] && name !== SUMMER_CALL && name !== SUMMER_SEARCH && !isLocalOp(resolved)) {
370
+ return toolResult(await runLocal(resolved, { tool: name, args }, extra, dryRun === true, args));
371
+ }
372
+ if (isLocalOp(resolved)) {
373
+ const call = localCall(name, resolved, args);
374
+ if (!call)
375
+ return toolResult(errorAnswer("not_in_profile", `${resolved} is not served by this profile.`, { next: { say: "Run the MCP with --profile engine." } }));
376
+ return toolResult(await runLocal(resolved, call, extra, dryRun === true, args));
377
+ }
378
+ // `out` stays here: this package saves the files (core/ops/save-files.ts).
379
+ const { input: sent, out } = options.files.take(resolved, args);
380
+ let raw;
381
+ try {
382
+ raw = await options.cloud.call(SUMMER_CALL, { op: name, ...(input ? { input: sent } : {}), ...(dryRun ? { dryRun } : {}), ...(idempotencyKey ? { idempotencyKey } : {}) });
383
+ }
384
+ catch (error) {
385
+ return toolResult(hostedCallFailure(error, { op: resolved, dryRun: dryRun === true, idempotencyKey }));
386
+ }
387
+ return toolResult(await options.files.finish(resolved, answerOfHosted(raw), out));
388
+ }));
389
+ }
390
+ /** A split operation's input shape: its fields from the 3.x tool's shape, the required ones required. */
391
+ function splitShape(def, base) {
392
+ const shape = {};
393
+ for (const field of def.fields) {
394
+ const type = base[field];
395
+ if (!type)
396
+ continue;
397
+ shape[field] = def.required?.includes(field) && type instanceof z.ZodOptional ? type.unwrap().describe(type.description ?? "") : type;
398
+ }
399
+ return shape;
400
+ }
401
+ /**
402
+ * The hosted direct tools on the v4 surface. Those that take `out`
403
+ * (summer_assets_generate_image, summer_assets_get, summer_jobs_wait, ...)
404
+ * show it in their listed input, and a call keeps it here and saves the files
405
+ * the answer names. A call that throws answers in the one shape too
406
+ * (hostedCallFailure), never with a plain "retry".
407
+ */
408
+ export function hostedFileTools(files) {
409
+ const ops = new Map([...TAKES_OUT].map((op) => [mcpNameOf(op), op]));
410
+ const sent = async (tool, args, forward) => {
411
+ try {
412
+ return await forward(args);
413
+ }
414
+ catch (error) {
415
+ const failure = hostedCallFailure(error, {
416
+ op: ops.get(tool.name) ?? tool.name,
417
+ dryRun: args.dryRun === true,
418
+ idempotencyKey: typeof args.idempotencyKey === "string" ? args.idempotencyKey : undefined,
419
+ read: tool.annotations?.readOnlyHint === true,
420
+ });
421
+ return toolResult(failure);
422
+ }
423
+ };
424
+ return {
425
+ inputSchema: (tool) => {
426
+ const op = ops.get(tool.name);
427
+ return op ? withOutField(op, tool.inputSchema) : tool.inputSchema;
428
+ },
429
+ call: async (name, args, forward, tool) => {
430
+ const op = ops.get(name);
431
+ if (!op)
432
+ return sent(tool, args, forward);
433
+ const { input, out } = files.take(op, args);
434
+ const raw = await sent(tool, input, forward);
435
+ const answer = answerOfHosted(raw);
436
+ const saved = await files.finish(op, answer, out);
437
+ if (saved === answer)
438
+ return raw;
439
+ const content = Array.isArray(raw.content) ? raw.content : [];
440
+ return { ...raw, content: [{ type: "text", text: JSON.stringify(saved) }, ...content.filter((part) => part.type !== "text")], ...(raw.structuredContent ? { structuredContent: saved } : {}) };
441
+ },
442
+ };
443
+ }
@@ -2,34 +2,58 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { EngineApiClient } from "../core/api-client.js";
3
3
  import type { EngineSelection } from "../core/engine.js";
4
4
  import { getCachedBootDriftNotice as getCachedNotice } from "./boot-notice.js";
5
+ import { type CloudCaller } from "./ops-surface.js";
6
+ import { FileSaver } from "../core/ops/save-files.js";
7
+ import { type ToolSelection } from "./tool-surface.js";
8
+ import { resolveSurface, type SurfaceVersion } from "../core/tool-profiles.js";
5
9
  export declare const getCachedBootDriftNotice: typeof getCachedNotice;
6
10
  /**
7
11
  * Server `instructions` in the MCP initialize response (SDK ServerOptions,
8
12
  * @modelcontextprotocol/sdk >= 1.x). Hosts hand this to the model once per
9
- * session, before any tool call — the place for the five habits an end-to-end run
10
- * showed an agent needs on the first
11
- * turn and would otherwise learn the hard way. Kept under 600 characters so
12
- * it costs a few hundred tokens once; the full operating guide stays in the
13
- * summer_agent_playbook prompt / summer_get_agent_playbook tool. The last
14
- * sentence names the publishing path, the owner-approval rule and where
15
- * review feedback is read.
13
+ * session, before any tool call — the place for the habits end-to-end runs
14
+ * showed an agent needs on the first turn and would otherwise learn the hard
15
+ * way, including scripting a run of scene edits instead of hundreds of single
16
+ * calls. Kept under 600 characters so it costs a few hundred tokens once; the
17
+ * full operating guide stays in the summer_agent_playbook prompt /
18
+ * summer_get_agent_playbook tool. The last sentence names the publishing path,
19
+ * the owner-approval rule and where review feedback is read.
16
20
  */
17
21
  export declare const SUMMER_MCP_INSTRUCTIONS: string;
22
+ /** The same first-turn habits for a profile without engine tools (`--profile assets`). */
23
+ export declare const SUMMER_MCP_ASSETS_INSTRUCTIONS: string;
18
24
  export declare function configureMcpEngineSelection(selection?: EngineSelection): void;
19
25
  export declare function getClient(): Promise<EngineApiClient>;
20
26
  export declare function resetClient(): void;
21
27
  /**
22
- * Build the MCP server with every Summer tool registered, without connecting
23
- * a transport. startMcpServer() uses this; tests use it to count the live
24
- * tool surface against registry/generated/counts.json.
28
+ * Build the MCP server with every Summer tool of the selected profile
29
+ * registered, without connecting a transport. startMcpServer() uses this;
30
+ * tests use it to count the live tool surface against
31
+ * registry/generated/counts.json. Without a selection: the full profile.
25
32
  */
26
- export declare function createMcpServer(): {
33
+ export { resolveSurface, type SurfaceVersion };
34
+ export interface CreateMcpServerOptions {
35
+ /** v4: the operation catalog surface (ops-surface.ts). Default v3 here; startMcpServer resolves v4 by default. */
36
+ surface?: SurfaceVersion;
37
+ /** Where v4 runs cloud operations (the hosted mount's client). */
38
+ cloud?: CloudCaller;
39
+ /** v4 only: list every local 3.x name too (the legacy toolset, legacy-toolset.ts). */
40
+ legacy?: boolean;
41
+ }
42
+ export declare function createMcpServer(selection?: ToolSelection, options?: CreateMcpServerOptions): {
27
43
  server: McpServer;
28
44
  getRegisteredToolCount: () => number;
45
+ /** v4: saves generated files on this machine (the mounted hosted tools share it). */
46
+ files: FileSaver;
29
47
  };
30
48
  export interface StartMcpServerOptions {
31
49
  projectPath?: string;
32
50
  instanceId?: string;
33
51
  cwd?: string;
52
+ /** --profile / SUMMER_PROFILE (full, engine, assets). */
53
+ profile?: string;
54
+ /** --toolsets / SUMMER_TOOLSETS (comma list; added to the profile). */
55
+ toolsets?: string;
56
+ /** --surface / SUMMER_SURFACE: v4 (default) serves the operation catalog; v3 the 3.x tools. */
57
+ surface?: string;
34
58
  }
35
59
  export declare function startMcpServer(options?: StartMcpServerOptions): Promise<void>;