summer-engine 3.8.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 (485) hide show
  1. package/.claude-plugin/marketplace.json +2 -13
  2. package/.claude-plugin/plugin.json +23 -22
  3. package/.codex-plugin/plugin.json +4 -12
  4. package/.cursor-plugin/plugin.json +4 -12
  5. package/.factory-plugin/plugin.json +4 -12
  6. package/AGENTS.md +19 -12
  7. package/CHANGELOG.md +96 -0
  8. package/GEMINI.md +3 -3
  9. package/README.md +103 -33
  10. package/assets/icon.png +0 -0
  11. package/commands/start.md +71 -0
  12. package/commands/summer.md +3 -2
  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 +25 -2
  27. package/dist/core/capabilities/apps.js +25 -12
  28. package/dist/core/capabilities/doctor.d.ts +3 -0
  29. package/dist/core/capabilities/doctor.js +20 -15
  30. package/dist/core/capabilities/fabricate-mesh.d.ts +2 -2
  31. package/dist/core/capabilities/game-task-plan.d.ts +12 -6
  32. package/dist/core/capabilities/game-task-plan.js +80 -5
  33. package/dist/core/capabilities/motion-generation.js +2 -2
  34. package/dist/core/capabilities/navigation/open.d.ts +6 -2
  35. package/dist/core/capabilities/navigation/open.js +3 -0
  36. package/dist/core/capabilities/publish-build.js +2 -0
  37. package/dist/core/capabilities/runtime-control.d.ts +4 -4
  38. package/dist/core/capabilities/scene-script-target.d.ts +17 -0
  39. package/dist/core/capabilities/scene-script-target.js +70 -0
  40. package/dist/core/capabilities/sfx-choices.d.ts +4 -0
  41. package/dist/core/capabilities/sfx-choices.js +13 -6
  42. package/dist/core/capabilities/tool-dispatch.d.ts +12 -3
  43. package/dist/core/capabilities/tool-dispatch.js +81 -46
  44. package/dist/core/embeddings.d.ts +2 -0
  45. package/dist/core/embeddings.js +1 -1
  46. package/dist/core/error-codes.d.ts +62 -0
  47. package/dist/core/error-codes.js +97 -0
  48. package/dist/core/format.d.ts +2 -0
  49. package/dist/core/format.js +2 -1
  50. package/dist/core/hosted-mcp.d.ts +22 -0
  51. package/dist/core/hosted-mcp.js +56 -1
  52. package/dist/core/library-read.js +5 -0
  53. package/dist/core/library-search.js +2 -1
  54. package/dist/core/oauth.js +4 -0
  55. package/dist/core/ops/catalog.d.ts +41 -0
  56. package/dist/core/ops/catalog.js +145 -0
  57. package/dist/core/ops/cloud.d.ts +56 -0
  58. package/dist/core/ops/cloud.js +175 -0
  59. package/dist/core/ops/contract.d.ts +119 -0
  60. package/dist/core/ops/contract.js +142 -0
  61. package/dist/core/ops/engine-answer.d.ts +25 -0
  62. package/dist/core/ops/engine-answer.js +117 -0
  63. package/dist/core/ops/engine.d.ts +55 -0
  64. package/dist/core/ops/engine.js +649 -0
  65. package/dist/core/ops/save-files.d.ts +78 -0
  66. package/dist/core/ops/save-files.js +419 -0
  67. package/dist/core/ops/search.d.ts +9 -0
  68. package/dist/core/ops/search.js +55 -0
  69. package/dist/core/skills-registry.d.ts +16 -1
  70. package/dist/core/skills-registry.js +35 -2
  71. package/dist/core/telemetry.d.ts +32 -0
  72. package/dist/core/telemetry.js +38 -10
  73. package/dist/core/tool-profiles.d.ts +25 -0
  74. package/dist/core/tool-profiles.js +41 -0
  75. package/dist/installer/agent-config.d.ts +17 -4
  76. package/dist/installer/agent-config.js +22 -6
  77. package/dist/installer/agent-table.d.ts +3 -0
  78. package/dist/installer/agent-table.js +10 -7
  79. package/dist/installer/setup.d.ts +2 -0
  80. package/dist/installer/setup.js +9 -4
  81. package/dist/installer/version-check.d.ts +29 -9
  82. package/dist/installer/version-check.js +81 -28
  83. package/dist/mcp/command.js +7 -0
  84. package/dist/mcp/hosted-mount.d.ts +27 -2
  85. package/dist/mcp/hosted-mount.js +53 -23
  86. package/dist/mcp/legacy-toolset.d.ts +27 -0
  87. package/dist/mcp/legacy-toolset.js +43 -0
  88. package/dist/mcp/ops-surface.d.ts +59 -0
  89. package/dist/mcp/ops-surface.js +443 -0
  90. package/dist/mcp/server.d.ts +35 -11
  91. package/dist/mcp/server.js +234 -89
  92. package/dist/mcp/tool-results.d.ts +26 -0
  93. package/dist/mcp/tool-results.js +81 -0
  94. package/dist/mcp/tool-surface.d.ts +65 -0
  95. package/dist/mcp/tool-surface.js +317 -0
  96. package/dist/mcp/tools/app-tools.js +9 -2
  97. package/dist/mcp/tools/asset-tools.js +55 -53
  98. package/dist/mcp/tools/audit-tools.js +21 -21
  99. package/dist/mcp/tools/debug-tools.js +6 -6
  100. package/dist/mcp/tools/fabricate-tools.js +6 -6
  101. package/dist/mcp/tools/generate-tools.js +76 -70
  102. package/dist/mcp/tools/project-tools.d.ts +9 -4
  103. package/dist/mcp/tools/project-tools.js +16 -10
  104. package/dist/mcp/tools/scene-tools.js +12 -23
  105. package/dist/mcp/tools/script-tools.js +9 -5
  106. package/dist/mcp/tools/with-engine.d.ts +6 -0
  107. package/dist/mcp/tools/with-engine.js +19 -0
  108. package/gemini-extension.json +4 -12
  109. package/hooks/pre-commit-doctor.sh +5 -4
  110. package/hooks/session-start.sh +24 -28
  111. package/integrations/claude-desktop/README.md +1 -1
  112. package/integrations/copilot-jetbrains/README.md +1 -1
  113. package/integrations/junie/README.md +1 -1
  114. package/integrations/lm-studio/README.md +1 -1
  115. package/integrations/trae/README.md +1 -1
  116. package/integrations/visual-studio/README.md +1 -1
  117. package/library/references/mcp-tools-reference/mcp-tools-reference.md +79 -51
  118. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  119. package/library/references/product-map/resource.yaml +2 -2
  120. package/library/skills/3d-lighting/SKILL.md +53 -28
  121. package/library/skills/3d-lighting/resource.yaml +1 -1
  122. package/library/skills/README.md +119 -117
  123. package/library/skills/adaptive-music/SKILL.md +19 -23
  124. package/library/skills/adaptive-music/resource.yaml +1 -1
  125. package/library/skills/agent-playtesting/SKILL.md +1 -1
  126. package/library/skills/agent-playtesting/resource.yaml +1 -1
  127. package/library/skills/ai-characters-in-games/SKILL.md +1 -1
  128. package/library/skills/ai-characters-in-games/resource.yaml +1 -1
  129. package/library/skills/ambient-bed/SKILL.md +22 -13
  130. package/library/skills/ambient-bed/resource.yaml +1 -1
  131. package/library/skills/animated-loop/SKILL.md +41 -32
  132. package/library/skills/animated-loop/resource.yaml +1 -1
  133. package/library/skills/animation-tree/SKILL.md +1 -1
  134. package/library/skills/animation-tree/resource.yaml +1 -1
  135. package/library/skills/art-direction/SKILL.md +3 -3
  136. package/library/skills/art-direction/resource.yaml +1 -1
  137. package/library/skills/asset-strategy/SKILL.md +21 -4
  138. package/library/skills/asset-strategy/resource.yaml +2 -1
  139. package/library/skills/audio-direction/SKILL.md +10 -10
  140. package/library/skills/audio-direction/resource.yaml +1 -1
  141. package/library/skills/auto-fire-targeting/SKILL.md +1 -1
  142. package/library/skills/auto-fire-targeting/resource.yaml +1 -1
  143. package/library/skills/bounded-engine-runs/SKILL.md +1 -1
  144. package/library/skills/bounded-engine-runs/resource.yaml +1 -1
  145. package/library/skills/brainstorm-game/SKILL.md +1 -1
  146. package/library/skills/brainstorm-game/resource.yaml +1 -1
  147. package/library/skills/brainstorming/SKILL.md +1 -1
  148. package/library/skills/brainstorming/resource.yaml +1 -1
  149. package/library/skills/browse-templates/SKILL.md +1 -1
  150. package/library/skills/browse-templates/resource.yaml +1 -1
  151. package/library/skills/camera-rigs/SKILL.md +2 -2
  152. package/library/skills/camera-rigs/resource.yaml +1 -1
  153. package/library/skills/celeste-momentum-platforming/resource.yaml +1 -0
  154. package/library/skills/character-animation-wiring/SKILL.md +4 -4
  155. package/library/skills/character-animation-wiring/resource.yaml +1 -1
  156. package/library/skills/character-model/SKILL.md +55 -47
  157. package/library/skills/character-model/resource.yaml +1 -1
  158. package/library/skills/character-movement/SKILL.md +3 -3
  159. package/library/skills/character-movement/resource.yaml +1 -1
  160. package/library/skills/character-portrait/SKILL.md +24 -19
  161. package/library/skills/character-portrait/resource.yaml +1 -1
  162. package/library/skills/cinematic-cutscene/SKILL.md +58 -46
  163. package/library/skills/cinematic-cutscene/resource.yaml +1 -1
  164. package/library/skills/combat-basics/SKILL.md +1 -1
  165. package/library/skills/combat-basics/resource.yaml +1 -1
  166. package/library/skills/compatibility-renderer-traps/SKILL.md +1 -1
  167. package/library/skills/compatibility-renderer-traps/resource.yaml +1 -1
  168. package/library/skills/concept-art/SKILL.md +16 -12
  169. package/library/skills/concept-art/resource.yaml +1 -1
  170. package/library/skills/concept-to-level/SKILL.md +239 -0
  171. package/library/skills/concept-to-level/references/technical-rules.md +150 -0
  172. package/library/skills/concept-to-level/resource.yaml +44 -0
  173. package/library/skills/create-asset-sheet/SKILL.md +19 -13
  174. package/library/skills/create-asset-sheet/resource.yaml +1 -1
  175. package/library/skills/debug/SKILL.md +2 -2
  176. package/library/skills/debug/resource.yaml +1 -1
  177. package/library/skills/debugging-game-feel/SKILL.md +1 -1
  178. package/library/skills/debugging-game-feel/resource.yaml +1 -1
  179. package/library/skills/design-level/SKILL.md +23 -35
  180. package/library/skills/design-level/resource.yaml +1 -1
  181. package/library/skills/design-mechanic/SKILL.md +1 -1
  182. package/library/skills/design-mechanic/resource.yaml +1 -1
  183. package/library/skills/design-npc/SKILL.md +22 -24
  184. package/library/skills/design-npc/resource.yaml +1 -1
  185. package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
  186. package/library/skills/diagnosing-perf-regressions/resource.yaml +1 -1
  187. package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
  188. package/library/skills/driving-the-editor-ui/resource.yaml +1 -1
  189. package/library/skills/environment-kit/SKILL.md +20 -16
  190. package/library/skills/environment-kit/resource.yaml +1 -1
  191. package/library/skills/export-and-ship/SKILL.md +6 -6
  192. package/library/skills/export-and-ship/resource.yaml +1 -1
  193. package/library/skills/fabricating-assets/SKILL.md +7 -7
  194. package/library/skills/fabricating-assets/resource.yaml +3 -3
  195. package/library/skills/facial-and-lipsync/SKILL.md +14 -15
  196. package/library/skills/facial-and-lipsync/resource.yaml +1 -1
  197. package/library/skills/fps-controller/SKILL.md +33 -41
  198. package/library/skills/fps-controller/resource.yaml +1 -1
  199. package/library/skills/game-feel/SKILL.md +8 -8
  200. package/library/skills/game-feel/resource.yaml +1 -1
  201. package/library/skills/gameskill/SKILL.md +4 -4
  202. package/library/skills/gameskill/resource.yaml +1 -1
  203. package/library/skills/gdscript-patterns/SKILL.md +1 -1
  204. package/library/skills/gdscript-patterns/resource.yaml +1 -1
  205. package/library/skills/generate-motion/SKILL.md +30 -21
  206. package/library/skills/generate-motion/resource.yaml +1 -1
  207. package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
  208. package/library/skills/godogen-visual-proof-game-generation/resource.yaml +1 -0
  209. package/library/skills/grow-analytics/SKILL.md +3 -3
  210. package/library/skills/grow-analytics/resource.yaml +1 -1
  211. package/library/skills/headless-scripting/SKILL.md +1 -1
  212. package/library/skills/headless-scripting/resource.yaml +1 -1
  213. package/library/skills/in-game-purchases/SKILL.md +1 -1
  214. package/library/skills/in-game-purchases/resource.yaml +1 -1
  215. package/library/skills/instantiate-asset-pack/SKILL.md +2 -2
  216. package/library/skills/instantiate-asset-pack/resource.yaml +1 -1
  217. package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +1 -0
  218. package/library/skills/make-game/SKILL.md +4 -4
  219. package/library/skills/make-game/references/2d-platformer.md +1 -1
  220. package/library/skills/make-game/references/3d-fps.md +1 -1
  221. package/library/skills/make-game/references/3d-horror.md +1 -1
  222. package/library/skills/make-game/references/3d-third-person.md +2 -2
  223. package/library/skills/make-game/resource.yaml +1 -1
  224. package/library/skills/multiplayer/SKILL.md +1 -1
  225. package/library/skills/multiplayer/resource.yaml +1 -1
  226. package/library/skills/multiplayer-movement/SKILL.md +1 -1
  227. package/library/skills/multiplayer-movement/resource.yaml +1 -1
  228. package/library/skills/multiplayer-project/SKILL.md +1 -1
  229. package/library/skills/multiplayer-project/resource.yaml +1 -1
  230. package/library/skills/multiplayer-publish/SKILL.md +8 -7
  231. package/library/skills/multiplayer-publish/resource.yaml +3 -3
  232. package/library/skills/multiplayer-state/SKILL.md +1 -1
  233. package/library/skills/multiplayer-state/resource.yaml +1 -1
  234. package/library/skills/multiplayer-testing/SKILL.md +1 -1
  235. package/library/skills/multiplayer-testing/resource.yaml +1 -1
  236. package/library/skills/music-track/SKILL.md +22 -13
  237. package/library/skills/music-track/resource.yaml +1 -1
  238. package/library/skills/navigate-summer/SKILL.md +11 -9
  239. package/library/skills/navigate-summer/resource.yaml +1 -1
  240. package/library/skills/new-project/SKILL.md +1 -1
  241. package/library/skills/new-project/resource.yaml +1 -1
  242. package/library/skills/organic-model/SKILL.md +24 -18
  243. package/library/skills/organic-model/resource.yaml +1 -1
  244. package/library/skills/pixel-art/SKILL.md +27 -23
  245. package/library/skills/pixel-art/resource.yaml +1 -1
  246. package/library/skills/play/SKILL.md +1 -1
  247. package/library/skills/play/resource.yaml +1 -1
  248. package/library/skills/playtesting-a-feature/SKILL.md +1 -1
  249. package/library/skills/playtesting-a-feature/resource.yaml +1 -1
  250. package/library/skills/procedural-animation/SKILL.md +20 -16
  251. package/library/skills/procedural-animation/resource.yaml +1 -1
  252. package/library/skills/prop-model/SKILL.md +25 -19
  253. package/library/skills/prop-model/resource.yaml +1 -1
  254. package/library/skills/psx-retro-rendering/resource.yaml +1 -0
  255. package/library/skills/publish-your-game/SKILL.md +16 -6
  256. package/library/skills/publish-your-game/resource.yaml +3 -3
  257. package/library/skills/realtime-wet-surfaces/resource.yaml +1 -0
  258. package/library/skills/release-readiness/SKILL.md +1 -1
  259. package/library/skills/release-readiness/resource.yaml +1 -1
  260. package/library/skills/remote-deploy/SKILL.md +1 -1
  261. package/library/skills/remote-deploy/resource.yaml +1 -1
  262. package/library/skills/retarget/SKILL.md +23 -20
  263. package/library/skills/retarget/resource.yaml +1 -1
  264. package/library/skills/running-in-the-cloud/SKILL.md +1 -1
  265. package/library/skills/running-in-the-cloud/resource.yaml +1 -1
  266. package/library/skills/save-load/SKILL.md +1 -1
  267. package/library/skills/save-load/resource.yaml +1 -1
  268. package/library/skills/scene-composition/SKILL.md +1 -1
  269. package/library/skills/scene-composition/resource.yaml +1 -1
  270. package/library/skills/scene-hierarchy-design/SKILL.md +2 -2
  271. package/library/skills/scene-hierarchy-design/resource.yaml +1 -1
  272. package/library/skills/scene-scripting/SKILL.md +66 -636
  273. package/library/skills/scene-scripting/references/ctx-api.md +184 -0
  274. package/library/skills/scene-scripting/references/recipes-2d-ui.md +193 -0
  275. package/library/skills/scene-scripting/references/recipes-3d.md +280 -0
  276. package/library/skills/scene-scripting/resource.yaml +4 -4
  277. package/library/skills/scene-to-level/SKILL.md +2 -2
  278. package/library/skills/scene-to-level/resource.yaml +1 -1
  279. package/library/skills/skill-create/resource.yaml +1 -0
  280. package/library/skills/skill-improve/resource.yaml +1 -0
  281. package/library/skills/skill-test/SKILL.md +2 -2
  282. package/library/skills/skill-test/resource.yaml +1 -0
  283. package/library/skills/skintokens-auto-rigging/resource.yaml +1 -0
  284. package/library/skills/skybox-panorama/SKILL.md +27 -21
  285. package/library/skills/skybox-panorama/resource.yaml +1 -1
  286. package/library/skills/sound-effect/SKILL.md +29 -20
  287. package/library/skills/sound-effect/resource.yaml +1 -1
  288. package/library/skills/spatial-placement/SKILL.md +14 -9
  289. package/library/skills/spatial-placement/resource.yaml +1 -1
  290. package/library/skills/sprite-sheet/SKILL.md +32 -27
  291. package/library/skills/sprite-sheet/resource.yaml +1 -1
  292. package/library/skills/store-art/SKILL.md +3 -3
  293. package/library/skills/store-art/resource.yaml +2 -2
  294. package/library/skills/store-listing/SKILL.md +3 -3
  295. package/library/skills/store-listing/resource.yaml +2 -2
  296. package/library/skills/summer-analytics/SKILL.md +7 -5
  297. package/library/skills/summer-analytics/resource.yaml +2 -2
  298. package/library/skills/summer-apps/SKILL.md +48 -32
  299. package/library/skills/summer-apps/manifest.md +1 -1
  300. package/library/skills/summer-apps/minimal-app.md +7 -7
  301. package/library/skills/summer-apps/resource.yaml +1 -1
  302. package/library/skills/summer-apps/sdk-reference.md +5 -5
  303. package/library/skills/summer-apps-design/SKILL.md +1 -1
  304. package/library/skills/summer-apps-design/resource.yaml +1 -1
  305. package/library/skills/summer-assets/SKILL.md +56 -0
  306. package/library/skills/summer-assets/resource.yaml +34 -0
  307. package/library/skills/summer-store/SKILL.md +1 -1
  308. package/library/skills/text-to-motion/SKILL.md +30 -23
  309. package/library/skills/text-to-motion/prompts-and-controls.md +5 -5
  310. package/library/skills/text-to-motion/resource.yaml +1 -1
  311. package/library/skills/text-to-motion/rigging-for-text-motion.md +2 -2
  312. package/library/skills/tileable-texture/SKILL.md +19 -15
  313. package/library/skills/tileable-texture/resource.yaml +1 -1
  314. package/library/skills/trailer-shot/SKILL.md +28 -24
  315. package/library/skills/trailer-shot/resource.yaml +1 -1
  316. package/library/skills/tune-performance/SKILL.md +6 -6
  317. package/library/skills/tune-performance/resource.yaml +1 -1
  318. package/library/skills/ui-basics/SKILL.md +41 -36
  319. package/library/skills/ui-basics/resource.yaml +1 -1
  320. package/library/skills/ui-graphics/SKILL.md +47 -38
  321. package/library/skills/ui-graphics/resource.yaml +1 -1
  322. package/library/skills/use-widget-asset/SKILL.md +1 -1
  323. package/library/skills/use-widget-asset/resource.yaml +1 -1
  324. package/library/skills/using-summer/SKILL.md +6 -5
  325. package/library/skills/using-summer/resource.yaml +1 -1
  326. package/library/skills/vehicle-model/SKILL.md +65 -57
  327. package/library/skills/vehicle-model/resource.yaml +1 -1
  328. package/library/skills/verification-before-completion/SKILL.md +1 -1
  329. package/library/skills/verification-before-completion/resource.yaml +1 -1
  330. package/library/skills/verifying-scenes/SKILL.md +2 -2
  331. package/library/skills/verifying-scenes/resource.yaml +1 -1
  332. package/library/skills/vfx-dissolve/SKILL.md +2 -2
  333. package/library/skills/vfx-dissolve/resource.yaml +1 -1
  334. package/library/skills/vfx-fire/SKILL.md +15 -41
  335. package/library/skills/vfx-fire/resource.yaml +1 -1
  336. package/library/skills/vfx-hit-spark/SKILL.md +1 -1
  337. package/library/skills/vfx-hit-spark/resource.yaml +1 -1
  338. package/library/skills/vfx-lightning/SKILL.md +7 -16
  339. package/library/skills/vfx-lightning/resource.yaml +1 -1
  340. package/library/skills/vfx-magic-glow/SKILL.md +23 -32
  341. package/library/skills/vfx-magic-glow/resource.yaml +1 -1
  342. package/library/skills/vfx-muzzle-flash/SKILL.md +20 -35
  343. package/library/skills/vfx-muzzle-flash/resource.yaml +1 -1
  344. package/library/skills/vfx-smoke/SKILL.md +13 -31
  345. package/library/skills/vfx-smoke/resource.yaml +1 -1
  346. package/library/skills/vfx-water-ripple/SKILL.md +12 -31
  347. package/library/skills/vfx-water-ripple/resource.yaml +1 -1
  348. package/library/skills/voice-line/SKILL.md +71 -40
  349. package/library/skills/voice-line/resource.yaml +1 -1
  350. package/library/skills/web-and-touch-input/SKILL.md +1 -1
  351. package/library/skills/web-and-touch-input/resource.yaml +1 -1
  352. package/library/skills/web-compatibility-look/SKILL.md +1 -1
  353. package/library/skills/web-compatibility-look/resource.yaml +1 -1
  354. package/library/skills/world-building-3d/SKILL.md +1 -1
  355. package/library/skills/world-building-3d/resource.yaml +1 -1
  356. package/library/skills/writing-skills/resource.yaml +1 -0
  357. package/library/tools/add-node/GUIDE.md +14 -0
  358. package/library/tools/align-distribute-3d/GUIDE.md +7 -0
  359. package/library/tools/app-call/resource.yaml +1 -1
  360. package/library/tools/app-guide/resource.yaml +2 -2
  361. package/library/tools/app-page/resource.yaml +1 -1
  362. package/library/tools/app-screenshot/resource.yaml +19 -1
  363. package/library/tools/app-tools/resource.yaml +1 -1
  364. package/library/tools/attach-to-surface/GUIDE.md +15 -0
  365. package/library/tools/batch/GUIDE.md +27 -0
  366. package/library/tools/camera-bookmark/GUIDE.md +12 -0
  367. package/library/tools/capture-gameplay/GUIDE.md +3 -0
  368. package/library/tools/capture-gameplay/resource.yaml +3 -3
  369. package/library/tools/check-job/resource.yaml +1 -1
  370. package/library/tools/clear-console/GUIDE.md +3 -0
  371. package/library/tools/connect-ports/GUIDE.md +9 -0
  372. package/library/tools/connect-signal/GUIDE.md +14 -0
  373. package/library/tools/create-debug-report/GUIDE.md +10 -0
  374. package/library/tools/create-scene/GUIDE.md +10 -0
  375. package/library/tools/debug-views/GUIDE.md +7 -0
  376. package/library/tools/enable-plugin/GUIDE.md +3 -0
  377. package/library/tools/export-game/GUIDE.md +3 -0
  378. package/library/tools/export-game/resource.yaml +3 -3
  379. package/library/tools/export-templates/GUIDE.md +3 -0
  380. package/library/tools/fabricate-3d/GUIDE.md +19 -0
  381. package/library/tools/frame-nodes/GUIDE.md +9 -0
  382. package/library/tools/frame-shot/GUIDE.md +9 -0
  383. package/library/tools/game-control/GUIDE.md +9 -0
  384. package/library/tools/game-input/GUIDE.md +9 -0
  385. package/library/tools/game-probe/GUIDE.md +9 -0
  386. package/library/tools/generate-3d/resource.yaml +3 -3
  387. package/library/tools/generate-motion/resource.yaml +2 -2
  388. package/library/tools/get-console/GUIDE.md +9 -0
  389. package/library/tools/get-console/resource.yaml +5 -0
  390. package/library/tools/get-debugger-errors/GUIDE.md +7 -0
  391. package/library/tools/get-debugger-errors/resource.yaml +5 -0
  392. package/library/tools/get-debugger-warnings/GUIDE.md +7 -0
  393. package/library/tools/get-debugger-warnings/resource.yaml +5 -0
  394. package/library/tools/get-diagnostics/GUIDE.md +13 -0
  395. package/library/tools/get-project-context/GUIDE.md +25 -0
  396. package/library/tools/get-runtime-tree/GUIDE.md +7 -0
  397. package/library/tools/get-runtime-tree/resource.yaml +5 -0
  398. package/library/tools/get-scene-tree/GUIDE.md +11 -0
  399. package/library/tools/get-scene-tree/resource.yaml +5 -0
  400. package/library/tools/get-script-errors/GUIDE.md +5 -0
  401. package/library/tools/grep/GUIDE.md +11 -0
  402. package/library/tools/import-asset/GUIDE.md +8 -0
  403. package/library/tools/import-asset-by-id/GUIDE.md +12 -0
  404. package/library/tools/import-from-url/GUIDE.md +10 -0
  405. package/library/tools/import-from-url-batch/GUIDE.md +3 -0
  406. package/library/tools/import-hdri/GUIDE.md +16 -0
  407. package/library/tools/input-map-bind/GUIDE.md +11 -0
  408. package/library/tools/inspect-asset/GUIDE.md +14 -0
  409. package/library/tools/inspect-asset/resource.yaml +5 -0
  410. package/library/tools/inspect-node/GUIDE.md +11 -0
  411. package/library/tools/inspect-node/resource.yaml +5 -0
  412. package/library/tools/inspect-resource/GUIDE.md +7 -0
  413. package/library/tools/inspect-resource/resource.yaml +5 -0
  414. package/library/tools/inspect-runtime-node/GUIDE.md +7 -0
  415. package/library/tools/inspect-runtime-node/resource.yaml +5 -0
  416. package/library/tools/instantiate-scene/GUIDE.md +12 -0
  417. package/library/tools/is-running/GUIDE.md +3 -0
  418. package/library/tools/measure/GUIDE.md +8 -0
  419. package/library/tools/navigation-probe/GUIDE.md +9 -0
  420. package/library/tools/open/resource.yaml +2 -2
  421. package/library/tools/open-main-scene/GUIDE.md +6 -0
  422. package/library/tools/open-scene/GUIDE.md +8 -0
  423. package/library/tools/place-adjacent/GUIDE.md +7 -0
  424. package/library/tools/play/GUIDE.md +13 -0
  425. package/library/tools/project-setting/GUIDE.md +9 -0
  426. package/library/tools/publish-build/resource.yaml +6 -6
  427. package/library/tools/raycast/GUIDE.md +7 -0
  428. package/library/tools/read-file/GUIDE.md +10 -0
  429. package/library/tools/read-library/resource.yaml +5 -0
  430. package/library/tools/recent-events/GUIDE.md +7 -0
  431. package/library/tools/remove-node/GUIDE.md +3 -0
  432. package/library/tools/repeat-along/GUIDE.md +5 -0
  433. package/library/tools/replace-node/GUIDE.md +9 -0
  434. package/library/tools/replace-text/GUIDE.md +5 -0
  435. package/library/tools/run-editor-script/GUIDE.md +16 -0
  436. package/library/tools/run-script/GUIDE.md +30 -0
  437. package/library/tools/run-script/resource.yaml +6 -3
  438. package/library/tools/runtime-animate/GUIDE.md +7 -0
  439. package/library/tools/runtime-call/GUIDE.md +7 -0
  440. package/library/tools/runtime-set/GUIDE.md +9 -0
  441. package/library/tools/runtime-spawn/GUIDE.md +9 -0
  442. package/library/tools/save-scene/GUIDE.md +3 -0
  443. package/library/tools/scene-audit/GUIDE.md +29 -0
  444. package/library/tools/screenshot/GUIDE.md +17 -0
  445. package/library/tools/select-node/GUIDE.md +3 -0
  446. package/library/tools/set-prop/GUIDE.md +23 -0
  447. package/library/tools/set-resource-property/GUIDE.md +8 -0
  448. package/library/tools/shot-sheet/GUIDE.md +7 -0
  449. package/library/tools/snap-to-surface/GUIDE.md +17 -0
  450. package/library/tools/snapshot-diff/GUIDE.md +7 -0
  451. package/library/tools/starcast/GUIDE.md +12 -0
  452. package/library/tools/stop/GUIDE.md +3 -0
  453. package/library/tools/test-placement/GUIDE.md +7 -0
  454. package/library/tools/ui-actions/GUIDE.md +12 -0
  455. package/library/tools/ui-activate/GUIDE.md +11 -0
  456. package/library/tools/ui-screenshot/GUIDE.md +9 -0
  457. package/library/tools/ui-tree/GUIDE.md +10 -0
  458. package/library/tools/wait-for-event/GUIDE.md +11 -0
  459. package/library/tools/world-snapshot/GUIDE.md +9 -0
  460. package/library/tools/write-file/GUIDE.md +5 -0
  461. package/library/tools/zoom/GUIDE.md +5 -0
  462. package/package.json +6 -4
  463. package/registry/generated/counts.json +2 -2
  464. package/registry/generated/gemini-extension.json +4 -12
  465. package/registry/generated/index.json +433 -339
  466. package/registry/generated/marketplace.claude.json +2 -13
  467. package/registry/generated/plugin.claude.json +23 -22
  468. package/registry/generated/plugin.codex.json +4 -12
  469. package/registry/generated/plugin.cursor.json +4 -12
  470. package/registry/generated/plugin.factory.json +4 -12
  471. package/registry/generated/server.json +34 -0
  472. package/registry/generated/skills-index.md +119 -117
  473. package/registry/generated/skills-registry.json +153 -115
  474. package/registry/operations/fixtures/invalid-deprecated-without-replacement.json +60 -0
  475. package/registry/operations/fixtures/invalid-name.json +60 -0
  476. package/registry/operations/fixtures/invalid-publish-without-owner.json +82 -0
  477. package/registry/operations/fixtures/invalid-spend-without-estimate.json +42 -0
  478. package/registry/operations/fixtures/invalid-unknown-field.json +61 -0
  479. package/registry/operations/fixtures/valid-player-facing.json +82 -0
  480. package/registry/operations/fixtures/valid-read.json +60 -0
  481. package/registry/operations/fixtures/valid-spend.json +43 -0
  482. package/registry/operations/legacy-names.json +1206 -0
  483. package/registry/schemas/operation.schema.json +318 -0
  484. package/registry/schemas/skill.schema.json +4 -0
  485. package/CLAUDE.md +0 -7
@@ -18,6 +18,8 @@ import { join, sep } from "node:path";
18
18
  import { PACKAGE_ROOT } from "../core/package-root.js";
19
19
  import { configureAgentMcp, parseAgent, SUMMER_MCP_SERVER_NAME, topLevelKey, } from "./agent-config.js";
20
20
  const NPM_REGISTRY_LATEST_URL = "https://registry.npmjs.org/summer-engine/latest";
21
+ const NPM_REGISTRY_DIST_TAGS_URL = "https://registry.npmjs.org/-/package/summer-engine/dist-tags";
22
+ const NPM_REGISTRY_PACKAGE_URL = "https://registry.npmjs.org/summer-engine";
21
23
  const REGISTRY_FETCH_TIMEOUT_MS = 3000;
22
24
  export function parseSemver(version) {
23
25
  if (!version)
@@ -69,8 +71,8 @@ export function classifyDrift(installed, target) {
69
71
  }
70
72
  return { severity: "warning", reason: "minor-drift" };
71
73
  }
72
- export async function fetchLatestRegistryVersion(options = {}) {
73
- const url = options.url ?? NPM_REGISTRY_LATEST_URL;
74
+ async function fetchRegistryJson(defaultUrl, options) {
75
+ const url = options.url ?? defaultUrl;
74
76
  const timeoutMs = options.timeoutMs ?? REGISTRY_FETCH_TIMEOUT_MS;
75
77
  const fetchImpl = options.fetchImpl ?? globalThis.fetch;
76
78
  if (!fetchImpl) {
@@ -88,15 +90,7 @@ export async function fetchLatestRegistryVersion(options = {}) {
88
90
  message: `registry responded ${response.status}`,
89
91
  };
90
92
  }
91
- const body = (await response.json());
92
- if (typeof body.version !== "string") {
93
- return {
94
- ok: false,
95
- reason: "registry-unreachable",
96
- message: "registry payload missing version",
97
- };
98
- }
99
- return { ok: true, version: body.version };
93
+ return { ok: true, body: await response.json() };
100
94
  }
101
95
  catch (error) {
102
96
  return {
@@ -106,6 +100,43 @@ export async function fetchLatestRegistryVersion(options = {}) {
106
100
  };
107
101
  }
108
102
  }
103
+ export async function fetchLatestRegistryVersion(options = {}) {
104
+ const result = await fetchRegistryJson(NPM_REGISTRY_LATEST_URL, options);
105
+ if (!result.ok)
106
+ return result;
107
+ const body = result.body;
108
+ if (typeof body?.version !== "string") {
109
+ return {
110
+ ok: false,
111
+ reason: "registry-unreachable",
112
+ message: "registry payload missing version",
113
+ };
114
+ }
115
+ return { ok: true, version: body.version };
116
+ }
117
+ export async function fetchRegistryDistTags(options = {}) {
118
+ const result = await fetchRegistryJson(NPM_REGISTRY_DIST_TAGS_URL, options);
119
+ if (!result.ok)
120
+ return result;
121
+ const body = result.body;
122
+ const tags = {};
123
+ for (const [tag, value] of Object.entries(body ?? {})) {
124
+ if (typeof value === "string")
125
+ tags[tag] = value;
126
+ }
127
+ if (!tags.latest) {
128
+ return { ok: false, reason: "registry-unreachable", message: "registry payload missing latest" };
129
+ }
130
+ return { ok: true, tags };
131
+ }
132
+ /** Whether npm has this exact version: true, false (registry says 404), or
133
+ * null when the registry could not be asked. */
134
+ export async function isRegistryVersionPublished(version, options = {}) {
135
+ const result = await fetchRegistryJson(`${NPM_REGISTRY_PACKAGE_URL}/${encodeURIComponent(version)}`, options);
136
+ if (result.ok)
137
+ return true;
138
+ return result.message === "registry responded 404" ? false : null;
139
+ }
109
140
  const RECOMMENDED_REFRESH_COMMAND = "npx clear-npx-cache && npx -y summer-engine@latest setup <agent> --yes --force";
110
141
  export function buildCliVersionCheck(input) {
111
142
  if (!input.registry.ok) {
@@ -212,28 +243,51 @@ export function defaultSkillMarkerCandidates() {
212
243
  }
213
244
  return candidates;
214
245
  }
215
- /** The npm dist-tag a refresh command should name. A CLI that is AHEAD of
216
- * npm `latest` was installed from `next` (a soaking release); telling that
217
- * user to run `summer-engine@latest` would silently downgrade the MCP server
218
- * while leaving the newer skills in place (release review P1-3). */
219
- export function refreshChannel(installedVersion, latestVersion) {
246
+ /** The npm spec a refresh command or a new MCP entry should name, so the agent
247
+ * never runs an older release than this CLI (release review P1-3). `latest`
248
+ * unless this CLI is AHEAD of npm latest; then `next` only when the next
249
+ * dist-tag is this exact version, else this exact version. A CLI that is ahead
250
+ * is not always on `next`: `next` stayed on 3.1.0 while latest moved to 3.8.0,
251
+ * and pinning it dropped every option newer than 3.1.0 (SUMMER_PROFILE). */
252
+ export function refreshChannel(installedVersion, latestVersion, nextVersion) {
220
253
  const installed = parseSemver(installedVersion);
221
254
  const latest = latestVersion ? parseSemver(latestVersion) : null;
222
255
  if (!installed || !latest)
223
256
  return "latest";
224
- return classifyDrift(installed, latest).reason === "ahead" ? "next" : "latest";
257
+ if (classifyDrift(installed, latest).reason !== "ahead")
258
+ return "latest";
259
+ return nextVersion?.trim() === installedVersion.trim() ? "next" : installedVersion.trim();
225
260
  }
226
261
  /** Default `summer setup` channel when neither --channel nor SUMMER_CHANNEL is
227
- * given: `next` while this CLI is ahead of npm latest, else `latest`. Network
228
- * failure means `latest` (never blocks setup). */
229
- export async function resolveDefaultChannel(installedVersion) {
230
- const registry = await fetchLatestRegistryVersion();
262
+ * given: `latest`, unless this CLI is ahead of npm latest. Then `next` when
263
+ * next is this exact version, this exact version when npm has it, and
264
+ * otherwise (a checkout that was never published) `latest` with a note that
265
+ * points at --local-dev. Network failure means `latest` (never blocks setup). */
266
+ export async function resolveDefaultChannel(installedVersion, deps = {}) {
267
+ const registry = await (deps.fetchDistTags ?? fetchRegistryDistTags)();
231
268
  if (!registry.ok)
232
269
  return { channel: "latest" };
233
- const channel = refreshChannel(installedVersion, registry.version);
234
- return channel === "next"
235
- ? { channel, note: `This CLI (${installedVersion}) is ahead of npm latest (${registry.version}); the MCP entry is pinned to summer-engine@next so the agent keeps running this release. Pass --channel latest to override.` }
236
- : { channel };
270
+ const latest = registry.tags.latest;
271
+ const channel = refreshChannel(installedVersion, latest, registry.tags.next);
272
+ if (channel === "latest")
273
+ return { channel };
274
+ if (channel === "next") {
275
+ return {
276
+ channel,
277
+ note: `This CLI (${installedVersion}) is the npm next release, ahead of latest (${latest}); the MCP entry runs summer-engine@next. Pass --channel latest to override.`,
278
+ };
279
+ }
280
+ const published = await (deps.isPublished ?? isRegistryVersionPublished)(installedVersion);
281
+ if (published) {
282
+ return {
283
+ channel,
284
+ note: `This CLI (${installedVersion}) is ahead of npm latest (${latest}); the MCP entry is pinned to summer-engine@${installedVersion} so the agent runs this release. Pass --channel latest to override.`,
285
+ };
286
+ }
287
+ return {
288
+ channel: "latest",
289
+ note: `This CLI (${installedVersion}) is not on npm, so the MCP entry runs summer-engine@latest (${latest}), which can lack options this CLI has. To run this build, pass --local-dev.`,
290
+ };
237
291
  }
238
292
  export async function buildSkillsVersionCheck(input) {
239
293
  const cliParsed = parseSemver(input.installedCliVersion);
@@ -306,7 +360,7 @@ export async function buildSkillsVersionCheck(input) {
306
360
  ...baseDetails,
307
361
  drift: worst.drift.reason,
308
362
  ...(install ? { install } : {}),
309
- recommendedAction: skillsRefreshCommand(worst.agent, install, refreshChannel(input.installedCliVersion, input.latestRegistryVersion)),
363
+ recommendedAction: skillsRefreshCommand(worst.agent, install, refreshChannel(input.installedCliVersion, input.latestRegistryVersion, input.nextRegistryVersion)),
310
364
  },
311
365
  };
312
366
  }
@@ -330,8 +384,7 @@ export function skillsRefreshCommand(agent, install, channel = "latest") {
330
384
  if (install?.localDev && install.cliPath) {
331
385
  return `node ${install.cliPath} setup ${agent} --local-dev --yes --force`;
332
386
  }
333
- const tag = channel === "next" ? "next" : "latest";
334
- return `npx clear-npx-cache && npx -y summer-engine@${tag} setup ${agent} --yes --force${channel === "next" ? " --channel next" : ""}`;
387
+ return `npx clear-npx-cache && npx -y summer-engine@${channel} setup ${agent} --yes --force${channel === "latest" ? "" : ` --channel ${channel}`}`;
335
388
  }
336
389
  /** The shape `summer setup --local-dev` writes: `node <…>/dist/bin/summer.js mcp`
337
390
  * (createSummerMcpServerConfig(true)). */
@@ -1,14 +1,21 @@
1
1
  import { Command, Option } from "commander";
2
2
  import { configureAgentMcp, parseAgent, parseScope, supportedAgents, } from "../installer/agent-config.js";
3
3
  import { startMcpServer } from "./server.js";
4
+ import { TOOLSETS } from "./tool-surface.js";
4
5
  export const mcpCommand = new Command("mcp")
5
6
  .description("Start the MCP server for AI tool integration (Cursor, Claude Code, etc.)")
6
7
  .option("--project <path>", "Bind local engine tools to the editor running this project")
7
8
  .option("--instance <id>", "Bind local engine tools to one exact Summer editor instance")
9
+ .option("--profile <profile>", "Tool profile: full (every tool, the default), engine (engine, generation and the store; under 128 tools), assets (generation and the asset library, no engine). Env: SUMMER_PROFILE")
10
+ .option("--toolsets <list>", `Comma-separated toolsets to add (alone: core plus these): ${TOOLSETS.join(", ")}, or all. Env: SUMMER_TOOLSETS`)
11
+ .option("--surface <surface>", "Tool surface: v4 (the default: engine tools, summer_search and summer_call for the operation catalog) or v3 (the 3.x tools). Env: SUMMER_SURFACE")
8
12
  .action(async (opts) => {
9
13
  await startMcpServer({
10
14
  projectPath: opts.project,
11
15
  instanceId: opts.instance,
16
+ profile: opts.profile,
17
+ toolsets: opts.toolsets,
18
+ surface: opts.surface,
12
19
  });
13
20
  });
14
21
  // Deprecated alias. `summer setup <agent>` (src/cli/commands/setup.ts) is the
@@ -1,4 +1,5 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type Tool } from "@modelcontextprotocol/sdk/types.js";
2
3
  import { type HostedClient, type HostedConnectDependencies } from "../core/hosted-mcp.js";
3
4
  export type { HostedClient };
4
5
  /**
@@ -30,6 +31,8 @@ export interface HostedMountState {
30
31
  resources: string[];
31
32
  /** Hosted names the local MCP already defines (kept local). */
32
33
  collisions: string[];
34
+ /** Hosted tools left out because the server's tool limit was reached. */
35
+ overLimit: string[];
33
36
  error?: {
34
37
  code: string;
35
38
  message: string;
@@ -42,9 +45,31 @@ export interface HostedMountState {
42
45
  * reports each mounted tool's own JSON Schema rather than the passthrough one.
43
46
  * Returns mount(), which callers run after connect without awaiting it.
44
47
  */
45
- export declare function prepareHostedMount(server: McpServer, deps?: HostedMountDependencies, options?: {
48
+ /** Fields and handling this package adds around a hosted tool (the v4 surface saves generated files here). */
49
+ export interface HostedLocalHook {
50
+ /** The input schema a client lists for the tool. */
51
+ inputSchema(tool: Tool): Tool["inputSchema"];
52
+ /** Runs the call; `forward` sends arguments on to the hosted tool, `tool` is its listing (annotations included). */
53
+ call(name: string, args: Record<string, unknown>, forward: (args: Record<string, unknown>) => Promise<Record<string, unknown>>, tool: Tool): Promise<Record<string, unknown>>;
54
+ }
55
+ export interface HostedMountOptions {
46
56
  firstListWaitMs?: number;
47
- }): {
57
+ /** The profile's filter: false leaves a hosted tool out. Default: every tool. */
58
+ includeTool?: (name: string) => boolean;
59
+ /** Mount no tool once the server has this many. Default: no limit. */
60
+ maxTools?: number;
61
+ /** The description a mounted tool gets here. Default: the hosted one. */
62
+ describe?: (tool: Tool) => string;
63
+ /** Runs after each successful mount (another mount can follow it). */
64
+ onMounted?: () => void;
65
+ /** What summer_store_tools calls the hosted tools this profile mounts.
66
+ * Default: the full profile's store, publishing, board and Grow tools. */
67
+ hostedToolsLabel?: string;
68
+ /** Local fields and handling around each mounted tool. Default: none. */
69
+ local?: HostedLocalHook;
70
+ }
71
+ export declare function prepareHostedMount(server: McpServer, deps?: HostedMountDependencies, options?: HostedMountOptions): {
48
72
  mount: () => Promise<HostedMountState>;
49
73
  state: HostedMountState;
74
+ call: (name: string, args: Record<string, unknown>) => Promise<Record<string, unknown>>;
50
75
  };
@@ -1,6 +1,6 @@
1
1
  import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
2
2
  import { z } from "zod";
3
- import { connectHostedMcp } from "../core/hosted-mcp.js";
3
+ import { connectHostedMcp, hostedConnectFailure, HostedUnreachableError, withV3Surface } from "../core/hosted-mcp.js";
4
4
  import { getStoreAccessToken, OAuthError, resolveMcpResourceUrl } from "../core/oauth.js";
5
5
  import { appendMcpLogEvent } from "../core/mcp-log.js";
6
6
  import { providerSafeSchema } from "./provider-safe-schema.js";
@@ -26,7 +26,7 @@ export const STORE_TOOLS_STATUS = "summer_store_tools";
26
26
  export const FIRST_LIST_WAIT_MS = 5_000;
27
27
  const passthroughArgs = z.object({}).passthrough();
28
28
  export const defaultHostedMountDependencies = {
29
- url: () => resolveMcpResourceUrl(),
29
+ url: () => withV3Surface(resolveMcpResourceUrl()),
30
30
  token: () => getStoreAccessToken(),
31
31
  connect: connectHostedMcp,
32
32
  };
@@ -45,16 +45,10 @@ async function listAll(page, key) {
45
45
  function errorText(error) {
46
46
  return { content: [{ type: "text", text: JSON.stringify({ ok: false, ...error }) }], isError: true };
47
47
  }
48
- /**
49
- * Get the server ready for hosted tools before the transport connects (the
50
- * SDK fixes capabilities at connect): resource handlers exist, and tools/list
51
- * reports each mounted tool's own JSON Schema rather than the passthrough one.
52
- * Returns mount(), which callers run after connect without awaiting it.
53
- */
54
48
  export function prepareHostedMount(server, deps = defaultHostedMountDependencies, options = {}) {
55
49
  const firstListWaitMs = options.firstListWaitMs ?? FIRST_LIST_WAIT_MS;
56
50
  let listed = false;
57
- const state = { status: "idle", tools: [], prompts: [], resources: [], collisions: [] };
51
+ const state = { status: "idle", tools: [], prompts: [], resources: [], collisions: [], overLimit: [] };
58
52
  const schemas = new Map();
59
53
  const registries = server;
60
54
  // Declare the resources capability now: registering one and removing it
@@ -74,7 +68,7 @@ export function prepareHostedMount(server, deps = defaultHostedMountDependencies
74
68
  ...result,
75
69
  tools: result.tools.map((tool) => {
76
70
  const hosted = schemas.get(tool.name);
77
- return hosted ? { ...tool, inputSchema: providerSafeSchema(hosted.inputSchema), ...(hosted.annotations ? { annotations: hosted.annotations } : {}), ...(hosted.title ? { title: hosted.title } : {}) } : tool;
71
+ return hosted ? { ...tool, inputSchema: providerSafeSchema(options.local ? options.local.inputSchema(hosted) : hosted.inputSchema), ...(hosted.annotations ? { annotations: hosted.annotations } : {}), ...(hosted.title ? { title: hosted.title } : {}) } : tool;
78
72
  }),
79
73
  };
80
74
  });
@@ -93,6 +87,8 @@ export function prepareHostedMount(server, deps = defaultHostedMountDependencies
93
87
  }
94
88
  let statusTool = null;
95
89
  let running = null;
90
+ let connected = null;
91
+ const listedToolCount = () => Object.values(registries._registeredTools).filter((tool) => tool.enabled !== false).length;
96
92
  /** Wait for a mount in progress, at most ms; returns at once when none runs. */
97
93
  async function waitForMount(ms) {
98
94
  if (!running || ms <= 0)
@@ -105,8 +101,12 @@ export function prepareHostedMount(server, deps = defaultHostedMountDependencies
105
101
  if (statusTool || STORE_TOOLS_STATUS in registries._registeredTools)
106
102
  return;
107
103
  statusTool = server.registerTool(STORE_TOOLS_STATUS, {
108
- description: "The Summer store, publishing, board and Grow tools come from the hosted Summer Engine MCP and are not loaded. Call this to see why and how to fix it (usually: run \"summer login --store\" in a terminal); it loads them when the sign-in works.",
104
+ title: "Load the hosted Summer tools",
105
+ description: `The ${options.hostedToolsLabel ?? "Summer store, publishing, board and Grow tools"} come from the hosted Summer Engine MCP and are not loaded. Call this to see why and how to fix it (usually: run "summer login --store" in a terminal); it loads them when the sign-in works.`,
109
106
  inputSchema: passthroughArgs,
107
+ // Registered after the server's annotation pass, so it carries its own:
108
+ // it asks Summer's servers which tools this sign-in may use and changes nothing.
109
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
110
110
  }, async () => {
111
111
  const after = await mount();
112
112
  if (after.status === "mounted") {
@@ -124,14 +124,12 @@ export function prepareHostedMount(server, deps = defaultHostedMountDependencies
124
124
  }
125
125
  catch (error) {
126
126
  state.status = "unavailable";
127
- state.error =
128
- error instanceof OAuthError
129
- ? { code: error.code, message: error.message.replace(` ${error.recovery}`, ""), recovery: error.recovery }
130
- : {
131
- code: "store_tools_unreachable",
132
- message: `The hosted Summer Engine MCP did not answer: ${error instanceof Error ? error.message : String(error)}.`,
133
- recovery: 'Recovery: check the network; if it says unauthorized, run "summer login --store --force". Then call summer_store_tools.',
134
- };
127
+ const failure = hostedConnectFailure(error, 'Recovery: check the network; if it says unauthorized, run "summer login --store --force". Then call summer_store_tools.');
128
+ state.error = {
129
+ code: failure instanceof OAuthError ? failure.code : "store_tools_unreachable",
130
+ message: failure.message.replace(` ${failure.recovery}`, ""),
131
+ recovery: failure.recovery,
132
+ };
135
133
  appendMcpLogEvent("mcp:hosted_mount_failed", { code: state.error.code });
136
134
  showStatusTool();
137
135
  return state;
@@ -149,10 +147,19 @@ export function prepareHostedMount(server, deps = defaultHostedMountDependencies
149
147
  }
150
148
  if (schemas.has(tool.name))
151
149
  continue;
150
+ if (options.includeTool && !options.includeTool(tool.name))
151
+ continue;
152
+ // The limit is on what a client lists: tools a surface keeps unlisted (v4) do not count.
153
+ if (options.maxTools !== undefined && listedToolCount() >= options.maxTools) {
154
+ if (!state.overLimit.includes(tool.name))
155
+ state.overLimit.push(tool.name);
156
+ continue;
157
+ }
152
158
  schemas.set(tool.name, tool);
153
- server.registerTool(tool.name, { description: tool.description ?? "", inputSchema: passthroughArgs, ...(tool.annotations ? { annotations: tool.annotations } : {}) }, async (args) => {
159
+ server.registerTool(tool.name, { description: options.describe ? options.describe(tool) : (tool.description ?? ""), inputSchema: passthroughArgs, ...(tool.annotations ? { annotations: tool.annotations } : {}) }, async (args) => {
154
160
  try {
155
- return (await client.callTool({ name: tool.name, arguments: args }));
161
+ const forward = (sent) => client.callTool({ name: tool.name, arguments: sent });
162
+ return (options.local ? await options.local.call(tool.name, args, forward, tool) : await forward(args));
156
163
  }
157
164
  catch (error) {
158
165
  return errorText({
@@ -185,9 +192,17 @@ export function prepareHostedMount(server, deps = defaultHostedMountDependencies
185
192
  }
186
193
  statusTool?.remove();
187
194
  statusTool = null;
195
+ connected = client;
188
196
  state.status = "mounted";
189
197
  delete state.error;
190
- appendMcpLogEvent("mcp:hosted_mounted", { tools: state.tools.length, prompts: state.prompts.length, resources: state.resources.length, collisions: state.collisions.length });
198
+ options.onMounted?.();
199
+ appendMcpLogEvent("mcp:hosted_mounted", {
200
+ tools: state.tools.length,
201
+ prompts: state.prompts.length,
202
+ resources: state.resources.length,
203
+ collisions: state.collisions.length,
204
+ ...(state.overLimit.length ? { overLimit: state.overLimit } : {}),
205
+ });
191
206
  return state;
192
207
  }
193
208
  /** Mount once; a failed mount runs again on the next call. */
@@ -209,5 +224,20 @@ export function prepareHostedMount(server, deps = defaultHostedMountDependencies
209
224
  }
210
225
  return running;
211
226
  }
212
- return { mount, state };
227
+ /**
228
+ * Call a hosted tool whether or not it is listed here (the v4 surface's
229
+ * summer_search and summer_call stay local and forward through this).
230
+ */
231
+ async function call(name, args) {
232
+ const after = await mount();
233
+ if (!connected) {
234
+ const error = after.error ?? { code: "store_tools_unavailable", message: "The hosted Summer server is not connected.", recovery: 'Recovery: run "summer login".' };
235
+ // Nothing was sent. A sign-in failure keeps its OAuth code; anything else is the server not answering.
236
+ if (error.code === "store_tools_unreachable" || error.code === "store_tools_unavailable")
237
+ throw new HostedUnreachableError(error.message, error.recovery);
238
+ throw new OAuthError(error.code, error.message, error.recovery);
239
+ }
240
+ return connected.callTool({ name, arguments: args });
241
+ }
242
+ return { mount, state, call };
213
243
  }
@@ -0,0 +1,27 @@
1
+ import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
+ import { type SkillMarkerCandidate } from "../installer/version-check.js";
3
+ /**
4
+ * The legacy toolset of the v4 surface (SPEC §8.1, §12.3): every 3.x tool
5
+ * name listed again, each running as it did in 3.x, each description
6
+ * starting "3.x name; use <op>." It keeps skills written for 3.x working.
7
+ *
8
+ * On when the toolsets name `legacy` (`--toolsets legacy`,
9
+ * SUMMER_TOOLSETS=legacy), or SUMMER_LEGACY_TOOLS=on, or, unless
10
+ * SUMMER_LEGACY_TOOLS=off, while the Summer skills installed on this
11
+ * computer are older than 4.0 (their .summer-version marker).
12
+ */
13
+ export declare const LEGACY_TOOLSET = "legacy";
14
+ /** `--toolsets` without `legacy`, and whether it was there. */
15
+ export declare function takeLegacyToolset(list: string | undefined): {
16
+ toolsets: string | undefined;
17
+ requested: boolean;
18
+ };
19
+ /** True when any installed Summer skills carry a marker older than 4.0. */
20
+ export declare function installedSkillsBefore4(candidates?: SkillMarkerCandidate[]): boolean;
21
+ export type LegacyReason = "toolsets" | "env" | "skills" | "off";
22
+ export declare function resolveLegacy(requested: boolean, env?: NodeJS.ProcessEnv, skillsBefore4?: () => boolean): {
23
+ on: boolean;
24
+ reason: LegacyReason;
25
+ };
26
+ /** A hosted 3.x tool's description in the legacy toolset: its operation, then its first sentence. */
27
+ export declare function legacyHostedDescription(tool: Pick<Tool, "name" | "description">): string;
@@ -0,0 +1,43 @@
1
+ import { resolveOpName } from "../core/ops/contract.js";
2
+ import { defaultSkillMarkerCandidates, readSkillMarker } from "../installer/version-check.js";
3
+ /**
4
+ * The legacy toolset of the v4 surface (SPEC §8.1, §12.3): every 3.x tool
5
+ * name listed again, each running as it did in 3.x, each description
6
+ * starting "3.x name; use <op>." It keeps skills written for 3.x working.
7
+ *
8
+ * On when the toolsets name `legacy` (`--toolsets legacy`,
9
+ * SUMMER_TOOLSETS=legacy), or SUMMER_LEGACY_TOOLS=on, or, unless
10
+ * SUMMER_LEGACY_TOOLS=off, while the Summer skills installed on this
11
+ * computer are older than 4.0 (their .summer-version marker).
12
+ */
13
+ export const LEGACY_TOOLSET = "legacy";
14
+ /** `--toolsets` without `legacy`, and whether it was there. */
15
+ export function takeLegacyToolset(list) {
16
+ if (list === undefined)
17
+ return { toolsets: undefined, requested: false };
18
+ const parts = list.split(",").map((part) => part.trim());
19
+ const rest = parts.filter((part) => part.toLowerCase() !== LEGACY_TOOLSET);
20
+ return { toolsets: rest.filter(Boolean).join(","), requested: rest.length !== parts.length };
21
+ }
22
+ /** True when any installed Summer skills carry a marker older than 4.0. */
23
+ export function installedSkillsBefore4(candidates = defaultSkillMarkerCandidates()) {
24
+ return candidates.some((candidate) => {
25
+ const major = Number.parseInt(readSkillMarker(candidate.dir)?.version.split(".")[0] ?? "", 10);
26
+ return Number.isFinite(major) && major < 4;
27
+ });
28
+ }
29
+ export function resolveLegacy(requested, env = process.env, skillsBefore4 = installedSkillsBefore4) {
30
+ if (requested)
31
+ return { on: true, reason: "toolsets" };
32
+ const forced = (env.SUMMER_LEGACY_TOOLS ?? "").trim().toLowerCase();
33
+ if (forced === "on")
34
+ return { on: true, reason: "env" };
35
+ if (forced === "off")
36
+ return { on: false, reason: "off" };
37
+ return skillsBefore4() ? { on: true, reason: "skills" } : { on: false, reason: "off" };
38
+ }
39
+ /** A hosted 3.x tool's description in the legacy toolset: its operation, then its first sentence. */
40
+ export function legacyHostedDescription(tool) {
41
+ const first = (tool.description ?? "").split(/(?<=\.)\s/)[0]?.slice(0, 200) ?? "";
42
+ return `3.x name; use ${resolveOpName(tool.name)}. ${first}`.trim();
43
+ }
@@ -0,0 +1,59 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
3
+ import { type FileSaver } from "../core/ops/save-files.js";
4
+ import type { HostedLocalHook } from "./hosted-mount.js";
5
+ /**
6
+ * The v4 surface of the local MCP (`summer mcp --surface v4`, SUMMER_SURFACE=v4):
7
+ * one catalog of Summer operations instead of one tool per feature.
8
+ *
9
+ * - Listed: the engine operations under their 3.x names (the core build loop
10
+ * keeps its tools) plus the operations split out of mixed 3.x tools,
11
+ * docs.search and docs.read, the hosted server's direct tools (mounted from
12
+ * its v4 surface), summer_search and summer_call.
13
+ * - An engine tool here is its operation: a short summary (the how-to is its
14
+ * guide, docs.read tool/<slug>), annotations from its effect, and the one
15
+ * answer shape, with engine_not_running and the other codes instead of
16
+ * plain text.
17
+ * - Every other local 3.x tool stays registered but unlisted: summer_call
18
+ * runs it by its operation name or its old name, through the same handler.
19
+ * The legacy toolset lists them again under their 3.x names.
20
+ * - Cloud operations run on the hosted server: summer_call forwards them to
21
+ * the hosted summer_call with the person's sign-in; summer_search merges
22
+ * the hosted hits with the local ones.
23
+ */
24
+ export declare const SUMMER_SEARCH = "summer_search";
25
+ export declare const SUMMER_CALL = "summer_call";
26
+ export declare const OPS_MCP_INSTRUCTIONS: string;
27
+ /** The assets profile's version: no engine tools, so it names none. */
28
+ export declare const OPS_MCP_ASSETS_INSTRUCTIONS: string;
29
+ /** Runs a tool on the hosted server's v4 surface (hosted-mount.ts). */
30
+ export interface CloudCaller {
31
+ call(name: string, args: Record<string, unknown>): Promise<Record<string, unknown>>;
32
+ }
33
+ export interface OpsSurfaceOptions {
34
+ /** Keep the engine operations listed (profiles with engine tools). */
35
+ engine: boolean;
36
+ cloud: CloudCaller;
37
+ /** The legacy toolset: list every local 3.x name too, each running as it did in 3.x. */
38
+ legacy?: boolean;
39
+ /** Saves generated files on this machine (`out`, localPath); shared with the mounted hosted tools. */
40
+ files: FileSaver;
41
+ }
42
+ /** Its v4 description, within the 300-character summary rule; the full text stays on the 3.x surface. */
43
+ export declare 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.";
44
+ /** The read footer in this surface's words: feedback goes through summer_call (docs.feedback is not listed). */
45
+ export declare const V4_FOOTER_SUFFIX = "If this entry is wrong, stale, or you deviate from it, report via summer_call {\"op\":\"docs.feedback\"}.";
46
+ /** MCP annotations from an operation's effect (SPEC §4.1); engine operations never need a retry key. */
47
+ export declare function annotationsForEffect(effect: "read" | "write", openWorld: boolean, title: string): ToolAnnotations;
48
+ /** A parameter description cut to its whole sentences within PARAM_LIMIT characters; the guide has it whole. */
49
+ export declare function shortParamDescription(text: string): string;
50
+ export declare function v4Text(text: string): string;
51
+ export declare function applyOpsSurface(server: McpServer, options: OpsSurfaceOptions): void;
52
+ /**
53
+ * The hosted direct tools on the v4 surface. Those that take `out`
54
+ * (summer_assets_generate_image, summer_assets_get, summer_jobs_wait, ...)
55
+ * show it in their listed input, and a call keeps it here and saves the files
56
+ * the answer names. A call that throws answers in the one shape too
57
+ * (hostedCallFailure), never with a plain "retry".
58
+ */
59
+ export declare function hostedFileTools(files: FileSaver): HostedLocalHook;