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
@@ -16,6 +16,7 @@ import { registerEventTools } from "./tools/event-tools.js";
16
16
  import { registerFabricateTools } from "./tools/fabricate-tools.js";
17
17
  import { registerUiTools } from "./tools/ui-tools.js";
18
18
  import { registerRuntimeTools } from "./tools/runtime-tools.js";
19
+ import { registerAppTools } from "./tools/app-tools.js";
19
20
  import { recordToolCall, registrationHasInputSchema, trajectoryArgsFor, } from "../core/trajectory.js";
20
21
  import { registerFileTools } from "./tools/file-tools.js";
21
22
  import { registerAssetTools } from "./tools/asset-tools.js";
@@ -26,29 +27,49 @@ import { registerNavigationTools } from "./tools/navigation-tools.js";
26
27
  import { registerLibraryTools } from "./tools/library-tools.js";
27
28
  import { getCachedBootDriftNotice as getCachedNotice, setCachedBootDriftNotice, } from "./boot-notice.js";
28
29
  import { appendMcpLogEvent } from "../core/mcp-log.js";
29
- import { prepareHostedMount } from "./hosted-mount.js";
30
+ import { defaultHostedMountDependencies, prepareHostedMount } from "./hosted-mount.js";
31
+ import { applyOpsSurface, hostedFileTools, OPS_MCP_ASSETS_INSTRUCTIONS, OPS_MCP_INSTRUCTIONS, SUMMER_CALL, SUMMER_SEARCH } from "./ops-surface.js";
32
+ import { FileSaver } from "../core/ops/save-files.js";
33
+ import { opForToolCall } from "../core/ops/contract.js";
34
+ import { v4HostedUrl } from "../core/ops/cloud.js";
30
35
  import { serveProviderSafeToolSchemas } from "./provider-safe-schema.js";
36
+ import { legacyHostedDescription, resolveLegacy, takeLegacyToolset } from "./legacy-toolset.js";
37
+ import { OUTPUT_CAPS, PROFILE_TOOL_LIMIT, PROFILES, TOOLSETS, annotationsFor, registryAuthorities, resolveToolSelection, selectionIncludes, withMaxCharactersArg, } from "./tool-surface.js";
38
+ import { shapeToolResult, singleEditCounter } from "./tool-results.js";
39
+ import { recordLocalToolCall, recordMcpSession } from "../core/telemetry.js";
40
+ import { currentToolContext, registerMcpClientSource, runWithToolContext } from "../core/agent-host.js";
31
41
  import { buildBootDriftNotice, fetchLatestRegistryVersion, } from "../installer/version-check.js";
32
42
  import { TOOLKIT_VERSION as version } from "../core/version.js";
43
+ import { ENGINE_FREE_NOTE, engineNotRunningFromConnectError } from "../core/error-codes.js";
44
+ import { resolveSurface } from "../core/tool-profiles.js";
45
+ import { OAuthError } from "../core/oauth.js";
33
46
  let processDiagnosticsInstalled = false;
47
+ const FULL_SELECTION = { profile: "full", toolsets: null, ignored: [] };
34
48
  export const getCachedBootDriftNotice = getCachedNotice;
35
49
  /**
36
50
  * Server `instructions` in the MCP initialize response (SDK ServerOptions,
37
51
  * @modelcontextprotocol/sdk >= 1.x). Hosts hand this to the model once per
38
- * session, before any tool call — the place for the five habits an end-to-end run
39
- * showed an agent needs on the first
40
- * turn and would otherwise learn the hard way. Kept under 600 characters so
41
- * it costs a few hundred tokens once; the full operating guide stays in the
42
- * summer_agent_playbook prompt / summer_get_agent_playbook tool. The last
43
- * sentence names the publishing path, the owner-approval rule and where
44
- * review feedback is read.
52
+ * session, before any tool call — the place for the habits end-to-end runs
53
+ * showed an agent needs on the first turn and would otherwise learn the hard
54
+ * way, including scripting a run of scene edits instead of hundreds of single
55
+ * calls. Kept under 600 characters so it costs a few hundred tokens once; the
56
+ * full operating guide stays in the summer_agent_playbook prompt /
57
+ * summer_get_agent_playbook tool. The last sentence names the publishing path,
58
+ * the owner-approval rule and where review feedback is read.
45
59
  */
46
- export const SUMMER_MCP_INSTRUCTIONS = "Summer Engine MCP. Call summer_get_project_context first: it binds the open project, returns mainScene, projectMemory, any capabilitySkewWarning. " +
47
- "Before building or fixing, summer_search_library then summer_read_library the hit. " +
48
- "After play, read summer_get_diagnostics, not summer_get_console alone. " +
49
- "An all-black screenshot means no redraw yet: recapture. " +
60
+ export const SUMMER_MCP_INSTRUCTIONS = "Summer Engine MCP. Call summer_get_project_context first: it binds the open project. " +
61
+ "Before building or fixing: summer_search_library, then summer_read_library the hit. " +
62
+ "More than 3 scene edits: one summer_run_script (snapshot, script, diff, screenshot). " +
63
+ "After play: summer_get_diagnostics, not only summer_get_console. " +
64
+ "All-black screenshot: no redraw yet, recapture. " +
50
65
  "Report verified entries via summer_library_feedback. " +
51
- "Publishing: summer_export_game, summer_publish_build, summer_store_*; agents never publish alone: summer_store_submit returns the owner's approval link; summer_store_review, feedback to fix.";
66
+ "Publish: summer_export_game, summer_publish_build, summer_store_*; never alone: summer_store_submit returns the owner's approval link, summer_store_review the feedback.";
67
+ /** The same first-turn habits for a profile without engine tools (`--profile assets`). */
68
+ export const SUMMER_MCP_ASSETS_INSTRUCTIONS = "Summer MCP, assets profile: generation and the Summer asset library, no engine tools. " +
69
+ "Read skill/summer-assets, then the asset's skill (sound-effect, prop-model, ...): stop at the file, skip its engine steps. " +
70
+ "Generation costs credits: confirm first. A job returns a jobId: summer_check_job. " +
71
+ "Hand over files with summer_get_asset_download_url. " +
72
+ "Report verified entries via summer_library_feedback.";
52
73
  /**
53
74
  * Fire-and-forget probe of the npm registry on MCP boot. Caches the result for
54
75
  * the session. We never await this in startup so a slow / offline registry
@@ -102,26 +123,20 @@ export async function getClient() {
102
123
  const reason = error instanceof Error
103
124
  ? error.message
104
125
  : "Summer Engine is not running.";
126
+ // Nothing reachable: a coded error withEngine renders as JSON
127
+ // (engine_not_running). Anything else (several editors open, …) already
128
+ // says how to pick one.
129
+ const notRunning = engineNotRunningFromConnectError(reason);
130
+ if (notRunning)
131
+ throw notRunning;
105
132
  throw new Error(reason + "\n" +
106
- "Open the intended project in Summer Engine, or run: npx -y summer-engine@latest run\n" +
107
- "Note: only tools that touch the local project need the engine. Cloud tools " +
108
- "(summer_generate_*, summer_search_assets, summer_list_my_assets, summer_get_asset, " +
109
- "summer_check_job) work right now without it — they only need 'npx -y summer-engine@latest login'.");
133
+ "Open the intended project in Summer Engine, or run: npx -y summer-engine@latest run <project-path>\n" +
134
+ "Note: " + ENGINE_FREE_NOTE);
110
135
  }
111
136
  }
112
137
  export function resetClient() {
113
138
  cachedClient = null;
114
139
  }
115
- /**
116
- * Passive result-size observability. Monkey-patches server.tool() so every
117
- * registered handler's serialized text payload is measured and logged to
118
- * stderr in the existing `[summer-mcp]` JSON shape. The result itself is
119
- * never modified — external coding agents (Claude Code, Cursor, Codex)
120
- * manage their own context budgets, and silently truncating their tool
121
- * results is the wrong shape (see #102 revert). If a specific tool turns
122
- * out to produce pathological payloads in practice, the right fix is
123
- * adding range/depth/filter parameters to that tool — not a blanket cap.
124
- */
125
140
  function errorDetails(error) {
126
141
  if (error instanceof Error) {
127
142
  return {
@@ -169,74 +184,115 @@ function installMcpProcessDiagnostics() {
169
184
  appendMcpLogEvent("mcp:exit", { pid: process.pid, code });
170
185
  });
171
186
  }
172
- function installResultSizeLogger(server) {
173
- const original = server.tool.bind(server);
187
+ /** Index of the zod raw shape among server.tool()'s middle arguments, or -1. */
188
+ function rawShapeIndex(args) {
189
+ for (let index = 1; index < args.length - 1; index++) {
190
+ const candidate = args[index];
191
+ if (!candidate || typeof candidate !== "object" || "_def" in candidate)
192
+ continue;
193
+ const values = Object.values(candidate);
194
+ if (values.length > 0 && values.every((value) => !!value && typeof value === "object" && "_def" in value))
195
+ return index;
196
+ }
197
+ return -1;
198
+ }
199
+ function installToolCallWrapper(server, surfaceMeta) {
200
+ const target = server;
201
+ const original = target.tool.bind(server);
202
+ const singleEdits = singleEditCounter();
203
+ const hostApp = () => server.server.getClientVersion()?.name;
174
204
  let registeredToolCount = 0;
175
- server.tool = function patchedTool(...args) {
176
- if (args.length < 2)
177
- return original(...args);
178
- const name = args[0];
205
+ target.tool = function patchedTool(...registration) {
206
+ if (registration.length < 2)
207
+ return original(...registration);
208
+ const name = registration[0];
179
209
  if (typeof name !== "string")
180
- return original(...args);
181
- const lastIdx = args.length - 1;
182
- const handler = args[lastIdx];
210
+ return original(...registration);
211
+ const lastIdx = registration.length - 1;
212
+ const handler = registration[lastIdx];
183
213
  if (typeof handler !== "function")
184
- return original(...args);
214
+ return original(...registration);
185
215
  registeredToolCount += 1;
216
+ const args = [...registration];
217
+ const cap = OUTPUT_CAPS.get(name);
218
+ const shapeAt = cap === undefined ? -1 : rawShapeIndex(args);
219
+ if (shapeAt > 0)
220
+ args[shapeAt] = withMaxCharactersArg(name, args[shapeAt]);
186
221
  // Schema-less tools receive only the SDK's `extra` — never record that as
187
222
  // the tool's arguments (see registrationHasInputSchema).
188
223
  const hasInputSchema = registrationHasInputSchema(args);
189
- const wrapped = async (...handlerArgs) => {
224
+ args[lastIdx] = async (...handlerArgs) => {
225
+ let maxCharacters = cap;
226
+ if (shapeAt > 0 && handlerArgs[0] && typeof handlerArgs[0] === "object") {
227
+ const { maxCharacters: requested, ...rest } = handlerArgs[0];
228
+ if (typeof requested === "number")
229
+ maxCharacters = requested;
230
+ handlerArgs = [rest, ...handlerArgs.slice(1)];
231
+ }
190
232
  const startedAt = Date.now();
233
+ // A tool another tool runs (summer_call, a v4 operation over its 3.x
234
+ // tool) is part of that call: only the outer call sends a usage line.
235
+ const nested = currentToolContext() !== undefined;
236
+ const recordUsage = (ok, durationMs) => {
237
+ if (!nested)
238
+ recordLocalToolCall({ tool: name, op: opForToolCall(name, handlerArgs[0]), ...surfaceMeta, ok, durationMs, mcpClient: hostApp() });
239
+ };
191
240
  let result;
192
241
  try {
193
- result = await handler(...handlerArgs);
242
+ // Every Summer request the tool makes names it (core/agent-host.ts).
243
+ result = await runWithToolContext(name, "mcp", () => handler(...handlerArgs));
194
244
  }
195
245
  catch (error) {
196
246
  // A handler THROW never produced a result to classify; record it as
197
247
  // ok:false / exception so the stream does not silently skip failures,
198
248
  // then let the SDK turn it into the protocol error it always did.
249
+ const durationMs = Date.now() - startedAt;
199
250
  recordToolCall({
200
251
  tool: name,
201
252
  args: trajectoryArgsFor(hasInputSchema, handlerArgs),
202
253
  exception: error instanceof Error ? error.message : String(error),
203
- durationMs: Date.now() - startedAt,
254
+ durationMs,
204
255
  });
256
+ recordUsage(false, durationMs);
205
257
  throw error;
206
258
  }
207
259
  const durationMs = Date.now() - startedAt;
260
+ const record = result && typeof result === "object" ? result : null;
261
+ const isError = record?.isError === true;
262
+ // withEngine stamps failure classifiers + retried + bound hash on a
263
+ // non-enumerable symbol so we can log them here without every tool
264
+ // threading its own name through withEngine.
265
+ const meta = record ? record[WITH_ENGINE_META] : undefined;
208
266
  try {
267
+ const hint = singleEdits(name, isError);
268
+ result = shapeToolResult(result, { maxCharacters, hint });
269
+ }
270
+ catch {
271
+ // Shaping must never break the tool call; the raw result goes out.
272
+ }
273
+ try {
274
+ recordMcpSession();
275
+ recordUsage(!isError, durationMs);
209
276
  // Opt-in local trajectory capture: one JSONL line per tool call when
210
277
  // SUMMER_TRAJECTORY_DIR is set. recordToolCall never throws and is a
211
278
  // no-op when the env var is unset.
212
- {
213
- const record = result;
214
- const callMeta = record && typeof record === "object"
215
- ? record[WITH_ENGINE_META]
216
- : undefined;
217
- recordToolCall({
218
- tool: name,
219
- args: trajectoryArgsFor(hasInputSchema, handlerArgs),
220
- isError: record?.isError === true,
221
- terminalState: callMeta?.terminalState,
222
- errorClass: callMeta?.errorClass,
223
- failureReason: callMeta?.failureReason,
224
- durationMs,
225
- // Read only under SUMMER_TRAJECTORY_EVAL=1 (bounded summary); the
226
- // default redacted stream ignores it.
227
- result,
228
- });
229
- }
279
+ recordToolCall({
280
+ tool: name,
281
+ args: trajectoryArgsFor(hasInputSchema, handlerArgs),
282
+ isError,
283
+ terminalState: meta?.terminalState,
284
+ errorClass: meta?.errorClass,
285
+ failureReason: meta?.failureReason,
286
+ durationMs,
287
+ // Read only under SUMMER_TRAJECTORY_EVAL=1 (bounded summary); the
288
+ // default redacted stream ignores it.
289
+ result,
290
+ });
230
291
  if (result &&
231
292
  typeof result === "object" &&
232
293
  "content" in result &&
233
294
  Array.isArray(result.content)) {
234
295
  const debug = process.env.SUMMER_MCP_DEBUG === "1";
235
- const isError = result.isError === true;
236
- // withEngine stamps failure classifiers + retried + bound hash on a
237
- // non-enumerable symbol so we can log them here without every tool
238
- // threading its own name through withEngine.
239
- const meta = result[WITH_ENGINE_META];
240
296
  // Structured per-call line. Verbose behind SUMMER_MCP_DEBUG=1; when the
241
297
  // flag is off, log ONLY failures — the success path stays quiet.
242
298
  if (debug || isError) {
@@ -257,17 +313,11 @@ function installResultSizeLogger(server) {
257
313
  process.stderr.write(`[summer-mcp] ${callLine}\n`);
258
314
  }
259
315
  if (debug) {
260
- let chars = 0;
261
- for (const entry of result
262
- .content) {
263
- if (entry && entry.type === "text" && typeof entry.text === "string") {
264
- chars += entry.text.length;
265
- }
266
- }
267
- const bytes = Buffer.byteLength(result.content
316
+ const texts = result.content
268
317
  .filter((e) => e && e.type === "text" && typeof e.text === "string")
269
- .map((e) => e.text)
270
- .join(""), "utf8");
318
+ .map((e) => e.text);
319
+ const chars = texts.reduce((sum, text) => sum + text.length, 0);
320
+ const bytes = Buffer.byteLength(texts.join(""), "utf8");
271
321
  const line = JSON.stringify({
272
322
  event: "mcp:result_size",
273
323
  tool_name: name,
@@ -288,31 +338,44 @@ function installResultSizeLogger(server) {
288
338
  }
289
339
  return result;
290
340
  };
291
- const newArgs = [...args];
292
- newArgs[lastIdx] = wrapped;
293
- return original(...newArgs);
341
+ return original(...args);
294
342
  };
295
343
  return () => registeredToolCount;
296
344
  }
297
345
  /**
298
- * Build the MCP server with every Summer tool registered, without connecting
299
- * a transport. startMcpServer() uses this; tests use it to count the live
300
- * tool surface against registry/generated/counts.json.
346
+ * Build the MCP server with every Summer tool of the selected profile
347
+ * registered, without connecting a transport. startMcpServer() uses this;
348
+ * tests use it to count the live tool surface against
349
+ * registry/generated/counts.json. Without a selection: the full profile.
301
350
  */
302
- export function createMcpServer() {
351
+ export { resolveSurface };
352
+ const NO_CLOUD = {
353
+ call: async () => {
354
+ throw new OAuthError("store_login_required", "The hosted Summer server is not connected.", 'Recovery: run "summer login".');
355
+ },
356
+ };
357
+ export function createMcpServer(selection = FULL_SELECTION, options = {}) {
358
+ const surface = options.surface ?? "v3";
359
+ // A profile without engine tools (assets) gets the no-engine instructions,
360
+ // playbook and task plan, so nothing points the agent at a tool it lacks.
361
+ const engine = !selection.toolsets || selection.toolsets.has("engine");
303
362
  const server = new McpServer({
304
363
  name: "summer-engine",
305
364
  version,
306
- }, { instructions: SUMMER_MCP_INSTRUCTIONS });
307
- // Passive observability: log result-size to stderr but do not modify
308
- // results. See installResultSizeLogger above.
309
- const getRegisteredToolCount = installResultSizeLogger(server);
365
+ }, {
366
+ instructions: surface === "v4"
367
+ ? engine ? OPS_MCP_INSTRUCTIONS : OPS_MCP_ASSETS_INSTRUCTIONS
368
+ : engine ? SUMMER_MCP_INSTRUCTIONS : SUMMER_MCP_ASSETS_INSTRUCTIONS,
369
+ });
370
+ const getWrappedToolCount = installToolCallWrapper(server, { surfaceVersion: surface, profile: selection.profile });
371
+ // Requests to Summer's servers name the agent app from the initialize handshake.
372
+ registerMcpClientSource(() => server.server.getClientVersion());
310
373
  registerSceneTools(server);
311
374
  registerDebugTools(server);
312
375
  registerVisualTools(server);
313
376
  registerSeeingTools(server);
314
377
  registerAuditTools(server);
315
- registerProjectTools(server);
378
+ registerProjectTools(server, { engine });
316
379
  registerFileTools(server);
317
380
  registerAssetTools(server);
318
381
  registerGenerateTools(server);
@@ -328,12 +391,40 @@ export function createMcpServer() {
328
391
  registerFabricateTools(server);
329
392
  registerUiTools(server);
330
393
  registerRuntimeTools(server);
394
+ registerAppTools(server);
331
395
  // The playbook is also an MCP prompt so prompt-surfacing hosts get it
332
396
  // natively (same content as the summer_get_agent_playbook tool).
333
- registerPlaybookPrompt(server);
397
+ registerPlaybookPrompt(server, { engine });
334
398
  // Strict providers (Kimi, OpenAI strict) reject tuple and $ref schemas.
335
399
  serveProviderSafeToolSchemas(server);
336
- return { server, getRegisteredToolCount };
400
+ // Effect hints from each tool's registry authority, then the profile:
401
+ // tools outside it are removed before any client lists them.
402
+ const registered = server._registeredTools;
403
+ const authorities = registryAuthorities();
404
+ let removed = 0;
405
+ for (const [name, tool] of Object.entries(registered)) {
406
+ if (!selectionIncludes(selection, name, true)) {
407
+ tool.remove();
408
+ removed += 1;
409
+ continue;
410
+ }
411
+ const authority = authorities.get(name);
412
+ if (authority)
413
+ tool.update({ annotations: annotationsFor(name, authority) });
414
+ }
415
+ // Without engine tools nothing imports a file into a project, so files save into it by default.
416
+ const files = new FileSaver({ saveByDefault: !engine });
417
+ if (surface === "v4")
418
+ applyOpsSurface(server, { engine, cloud: options.cloud ?? NO_CLOUD, legacy: options.legacy === true, files });
419
+ return { server, getRegisteredToolCount: () => getWrappedToolCount() - removed, files };
420
+ }
421
+ /** What the hosted tools a profile mounts are, for summer_store_tools. */
422
+ function hostedToolsLabel(toolsets) {
423
+ if (toolsets.has("ship"))
424
+ return "Summer store and publishing tools";
425
+ if (toolsets.has("tools"))
426
+ return "Tool Factory tools (summer_tool_*) and asset editing tools";
427
+ return undefined;
337
428
  }
338
429
  export async function startMcpServer(options = {}) {
339
430
  configureMcpEngineSelection({
@@ -353,7 +444,22 @@ export async function startMcpServer(options = {}) {
353
444
  cwd: options.cwd ?? process.cwd(),
354
445
  },
355
446
  });
356
- const { server, getRegisteredToolCount } = createMcpServer();
447
+ const surface = resolveSurface(options.surface);
448
+ // `legacy` is not a toolset of its own: it lists the 3.x names on the v4 surface.
449
+ const toolsetList = takeLegacyToolset(options.toolsets ?? process.env.SUMMER_TOOLSETS);
450
+ const legacy = surface === "v4" ? resolveLegacy(toolsetList.requested) : { on: false, reason: "off" };
451
+ const selection = resolveToolSelection({ profile: options.profile, toolsets: toolsetList.toolsets });
452
+ if (selection.ignored.length > 0) {
453
+ writeMcpStderr("mcp:unknown_toolsets", {
454
+ ignored: selection.ignored,
455
+ profiles: Object.keys(PROFILES),
456
+ toolsets: TOOLSETS,
457
+ });
458
+ }
459
+ // v4 runs cloud operations through the hosted mount below, once it exists.
460
+ let hostedCall = null;
461
+ const cloud = { call: (name, args) => (hostedCall ? hostedCall(name, args) : NO_CLOUD.call(name, args)) };
462
+ const { server, getRegisteredToolCount, files } = createMcpServer(selection, { surface, cloud, legacy: legacy.on });
357
463
  // Fire-and-forget — never block tool registration on the npm registry.
358
464
  void probeBootDrift().catch((error) => {
359
465
  setCachedBootDriftNotice(null);
@@ -362,13 +468,54 @@ export async function startMcpServer(options = {}) {
362
468
  // Hosted Summer Engine MCP tools (store, publishing, board, Grow): ready
363
469
  // before connect, mounted after it. The first tools/list waits a few
364
470
  // seconds for the mount (not under summer doctor, which times the list).
365
- const hosted = prepareHostedMount(server, undefined, process.env.SUMMER_MCP_DOCTOR === "1" ? { firstListWaitMs: 0 } : {});
471
+ // A profile mounts only its hosted toolsets, and never more tools in total
472
+ // than PROFILE_TOOL_LIMIT.
473
+ // v4 mounts the hosted v4 surface (its direct tools for this profile;
474
+ // summer_search and summer_call stay local and forward to it).
475
+ // The legacy toolset (below) mounts after this mount, and again after a retry of it.
476
+ let legacyHosted = null;
477
+ const hosted = prepareHostedMount(server, surface === "v4" ? { ...defaultHostedMountDependencies, url: v4HostedUrl(selection.profile) } : undefined, {
478
+ ...(process.env.SUMMER_MCP_DOCTOR === "1" ? { firstListWaitMs: 0 } : {}),
479
+ onMounted: () => void legacyHosted?.mount(),
480
+ ...(surface === "v4"
481
+ ? { includeTool: (name) => name !== SUMMER_SEARCH && name !== SUMMER_CALL, maxTools: PROFILE_TOOL_LIMIT, local: hostedFileTools(files) }
482
+ : selection.toolsets === null
483
+ ? {}
484
+ : {
485
+ includeTool: (name) => selectionIncludes(selection, name, false),
486
+ maxTools: PROFILE_TOOL_LIMIT,
487
+ hostedToolsLabel: hostedToolsLabel(selection.toolsets),
488
+ }),
489
+ });
490
+ hostedCall = hosted.call;
491
+ // The legacy toolset also lists the hosted 3.x names this profile listed in
492
+ // 3.x, from the hosted 3.x surface, each running its 3.x tool, under the
493
+ // same limit as in 3.x. Its sign-in waits for the v4 mount's (a token
494
+ // refresh is not shared), so it starts at boot and the first tools/list
495
+ // still waits for it.
496
+ legacyHosted = legacy.on
497
+ ? prepareHostedMount(server, {
498
+ ...defaultHostedMountDependencies,
499
+ token: async () => {
500
+ await hosted.mount();
501
+ return defaultHostedMountDependencies.token();
502
+ },
503
+ }, {
504
+ ...(process.env.SUMMER_MCP_DOCTOR === "1" ? { firstListWaitMs: 0 } : {}),
505
+ ...(selection.toolsets === null ? {} : { includeTool: (name) => selectionIncludes(selection, name, false), maxTools: PROFILE_TOOL_LIMIT }),
506
+ describe: legacyHostedDescription,
507
+ })
508
+ : null;
366
509
  const transport = new StdioServerTransport();
367
510
  await server.connect(transport);
368
511
  void hosted.mount();
512
+ void legacyHosted?.mount();
369
513
  appendMcpLogEvent("mcp:ready", {
370
514
  version,
371
515
  pid: process.pid,
516
+ profile: selection.profile,
517
+ surface,
518
+ ...(surface === "v4" ? { legacy: legacy.reason } : {}),
372
519
  toolCount: getRegisteredToolCount(),
373
520
  });
374
521
  process.stderr.write(`[summer-mcp] MCP server running v${version}.\n`);
@@ -0,0 +1,26 @@
1
+ type Content = {
2
+ type?: string;
3
+ text?: unknown;
4
+ };
5
+ /** Pretty-printed JSON text as compact JSON; anything else unchanged. */
6
+ export declare function compactJsonText(text: string): string;
7
+ /** Cut text blocks to maxCharacters in total, with one note saying how to get the rest. */
8
+ export declare function capText(content: Content[], maxCharacters: number): Content[];
9
+ /**
10
+ * The text an agent gets: compact JSON, cut at maxCharacters when the tool
11
+ * is capped, plus an optional hint line. Images and error flags are kept.
12
+ */
13
+ export declare function shapeToolResult(result: unknown, options: {
14
+ maxCharacters?: number;
15
+ hint?: string | null;
16
+ }): unknown;
17
+ /** The first single edit in a row that gets the hint, and how often it repeats after that. */
18
+ export declare const SINGLE_EDIT_HINT_AT = 4;
19
+ /**
20
+ * Counts successful single scene edits since the last batched edit
21
+ * (summer_run_script, summer_batch, summer_run_editor_script). Reads in
22
+ * between do not break the run. Returns the hint on the 4th edit in a row,
23
+ * then every 6th.
24
+ */
25
+ export declare function singleEditCounter(): (tool: string, isError: boolean) => string | null;
26
+ export {};
@@ -0,0 +1,81 @@
1
+ import { BATCH_EDIT_TOOLS, SINGLE_EDIT_TOOLS } from "./tool-surface.js";
2
+ /** Pretty-printed JSON text as compact JSON; anything else unchanged. */
3
+ export function compactJsonText(text) {
4
+ const first = text[0];
5
+ if ((first !== "{" && first !== "[") || !text.includes("\n"))
6
+ return text;
7
+ try {
8
+ return JSON.stringify(JSON.parse(text));
9
+ }
10
+ catch {
11
+ return text;
12
+ }
13
+ }
14
+ /** The library read's last line (the feedback footer) survives a cut. */
15
+ const KEEP_LAST_LINE = /\n(— entry_id: [^\n]*)\s*$/;
16
+ /** Cut text blocks to maxCharacters in total, with one note saying how to get the rest. */
17
+ export function capText(content, maxCharacters) {
18
+ const total = content.reduce((sum, part) => sum + (part.type === "text" && typeof part.text === "string" ? part.text.length : 0), 0);
19
+ if (total <= maxCharacters)
20
+ return content;
21
+ const note = `\n\n[Truncated: ${maxCharacters} of ${total} characters shown. Call again with maxCharacters: ${total} for all of it, or narrow the request.]`;
22
+ let budget = maxCharacters;
23
+ let cut = false;
24
+ const out = [];
25
+ for (const part of content) {
26
+ if (part.type !== "text" || typeof part.text !== "string") {
27
+ out.push(part);
28
+ continue;
29
+ }
30
+ if (cut)
31
+ continue;
32
+ if (part.text.length <= budget) {
33
+ budget -= part.text.length;
34
+ out.push(part);
35
+ continue;
36
+ }
37
+ const footer = part.text.match(KEEP_LAST_LINE)?.[1];
38
+ out.push({ ...part, text: part.text.slice(0, budget) + note + (footer ? `\n\n${footer}` : "") });
39
+ cut = true;
40
+ }
41
+ return out;
42
+ }
43
+ /**
44
+ * The text an agent gets: compact JSON, cut at maxCharacters when the tool
45
+ * is capped, plus an optional hint line. Images and error flags are kept.
46
+ */
47
+ export function shapeToolResult(result, options) {
48
+ if (!result || typeof result !== "object" || !Array.isArray(result.content))
49
+ return result;
50
+ const original = result;
51
+ let content = original.content.map((part) => part && part.type === "text" && typeof part.text === "string" ? { ...part, text: compactJsonText(part.text) } : part);
52
+ if (options.maxCharacters !== undefined)
53
+ content = capText(content, options.maxCharacters);
54
+ if (options.hint)
55
+ content = [...content, { type: "text", text: options.hint }];
56
+ return { ...original, content };
57
+ }
58
+ /** The first single edit in a row that gets the hint, and how often it repeats after that. */
59
+ export const SINGLE_EDIT_HINT_AT = 4;
60
+ const SINGLE_EDIT_HINT_EVERY = 6;
61
+ /**
62
+ * Counts successful single scene edits since the last batched edit
63
+ * (summer_run_script, summer_batch, summer_run_editor_script). Reads in
64
+ * between do not break the run. Returns the hint on the 4th edit in a row,
65
+ * then every 6th.
66
+ */
67
+ export function singleEditCounter() {
68
+ let run = 0;
69
+ return (tool, isError) => {
70
+ if (BATCH_EDIT_TOOLS.has(tool)) {
71
+ run = 0;
72
+ return null;
73
+ }
74
+ if (isError || !SINGLE_EDIT_TOOLS.has(tool))
75
+ return null;
76
+ run += 1;
77
+ if (run < SINGLE_EDIT_HINT_AT || (run - SINGLE_EDIT_HINT_AT) % SINGLE_EDIT_HINT_EVERY !== 0)
78
+ return null;
79
+ return `Tip: ${run} single scene edits in a row. More than 3 edits: write one summer_run_script instead (snapshot, script, diff, screenshot).`;
80
+ };
81
+ }
@@ -0,0 +1,65 @@
1
+ import type { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
2
+ import { type ZodTypeAny } from "zod";
3
+ import { type Profile, type Toolset } from "../core/tool-profiles.js";
4
+ /**
5
+ * The shape of the MCP tool surface: which toolset each tool belongs to, each
6
+ * local tool's annotations, which results are capped, and which calls count
7
+ * as single scene edits. Read by server.ts (registration, results) and, with
8
+ * the profiles in core/tool-profiles.ts, by hosted-mount.ts (which hosted
9
+ * tools a profile mounts).
10
+ *
11
+ * Tool names never change here: a profile only leaves tools out.
12
+ */
13
+ export { TOOLSETS, PROFILES, PROFILE_TOOL_LIMIT, type Toolset, type Profile } from "../core/tool-profiles.js";
14
+ /** The toolset a tool belongs to: local tools by the table above, hosted ones by name. */
15
+ export declare function toolsetOf(name: string, local: boolean): Toolset;
16
+ export interface ToolSelection {
17
+ /** "custom" = toolsets given without a profile. */
18
+ profile: Profile | "custom";
19
+ /** null = every toolset (the full profile). */
20
+ toolsets: ReadonlySet<Toolset> | null;
21
+ /** Unknown names given in flags or env, for one warning line. */
22
+ ignored: string[];
23
+ }
24
+ /**
25
+ * `summer mcp --profile <p> --toolsets <a,b>` (env SUMMER_PROFILE,
26
+ * SUMMER_TOOLSETS). Without either: the full profile. `--toolsets` alone
27
+ * selects those toolsets plus core; with a profile it adds to it. `all` is
28
+ * every toolset. Unknown names are ignored and reported, never fatal: a
29
+ * typo must not stop an agent's MCP server from starting.
30
+ */
31
+ export declare function resolveToolSelection(options?: {
32
+ profile?: string;
33
+ toolsets?: string;
34
+ }, env?: NodeJS.ProcessEnv): ToolSelection;
35
+ /** True when the selection keeps this tool. */
36
+ export declare function selectionIncludes(selection: ToolSelection, name: string, local: boolean): boolean;
37
+ /** Every name the refinement sets mention (a test checks each is a real tool). */
38
+ export declare const ANNOTATION_REFINEMENTS: ReadonlySet<string>;
39
+ export type Authority = Partial<Record<"filesystem" | "editor_mutation" | "network" | "credentials" | "publish", boolean>>;
40
+ /** MCP annotations for one local tool from its registry authority. */
41
+ export declare function annotationsFor(name: string, authority: Authority): ToolAnnotations;
42
+ /** Registry authority per MCP tool name (registry/generated/index.json). */
43
+ export declare function registryAuthorities(): Map<string, Authority>;
44
+ /** Default text cap for tools whose results can be large. */
45
+ export declare const DEFAULT_MAX_CHARACTERS = 4000;
46
+ /**
47
+ * Tools whose text results are capped by default, with their default cap.
48
+ * Scene and runtime trees, console and debugger reads, inspect reads and
49
+ * library reads. The scene tree and library reads get more room: a median
50
+ * skill is about 12K characters, and cutting every skill read would double
51
+ * the core search-then-read loop. Writes, job ids and file reads are never
52
+ * capped.
53
+ */
54
+ export declare const OUTPUT_CAPS: ReadonlyMap<string, number>;
55
+ /**
56
+ * A capped tool's input shape plus `maxCharacters`. server.ts adds it at
57
+ * registration and strips it before the handler runs; the descriptor parity
58
+ * test applies the same function, so library/tools/<slug>/resource.yaml
59
+ * lists the argument too.
60
+ */
61
+ export declare function withMaxCharactersArg<T extends Record<string, ZodTypeAny>>(name: string, shape: T): T;
62
+ /** One-change scene tools; a run of them is one summer_run_script. */
63
+ export declare const SINGLE_EDIT_TOOLS: ReadonlySet<string>;
64
+ /** Calls that already batch edits; they end a run of single edits. */
65
+ export declare const BATCH_EDIT_TOOLS: ReadonlySet<string>;