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
@@ -20,6 +20,7 @@ import { tmpdir } from "node:os";
20
20
  import { join } from "node:path";
21
21
  import { mkdir, mkdtemp, writeFile } from "node:fs/promises";
22
22
  import { EngineApiClient } from "../api-client.js";
23
+ import { CLI_RECOVERY, codedFailure, codeForStatus, describeNetworkError, engineNotRunningFromConnectError, networkDetails, NOT_SIGNED_IN, } from "../error-codes.js";
23
24
  import { missingEngineEventsResult, missingEngineOpResult, } from "../capability-skew.js";
24
25
  import { buildAgentPlaybook } from "./agent-playbook.js";
25
26
  import { recentEvents, recentEventsArgsSchema, waitForEvent, waitForEventArgsSchema, } from "./events.js";
@@ -35,7 +36,8 @@ import { ImportHdriError, importHdriArgsSchema, importPolyHavenHdri } from "./hd
35
36
  import { FABRICATE_FALLBACK, buildFabricateMeshOp, fabricateArgsSchema } from "./fabricate-mesh.js";
36
37
  import { buildUiActionsOp, buildUiActivateOp, buildUiScreenshotOp, buildUiTreeOp, executeUiOp, uiActionsArgsSchema, uiActivateArgsSchema, uiScreenshotArgsSchema, uiScreenshotCaption, uiScreenshotImage, uiTreeArgsSchema, withUiFailureDetails, } from "./ui-control.js";
37
38
  import { PLAY_INSTANCE_FALLBACK, RUNTIME_FALLBACKS, buildGameControlOp, buildGameInputOp, buildGameProbeOp, buildRuntimeAnimateOp, buildRuntimeCallOp, buildRuntimeSetOp, buildRuntimeSpawnOp, buildStopGameOp, findProbePayload, gameControlArgsSchema, gameInputArgsSchema, gameProbeArgsSchema, playGame, probeFrameStamp, runtimeAnimateArgsSchema, runtimeCallArgsSchema, runtimeSetArgsSchema, runtimeSpawnArgsSchema, stripProbeImage, withRuntimeFailureHints, } from "./runtime-control.js";
38
- import { RUN_EDITOR_SCRIPT_FALLBACK, RUN_SCRIPT_FALLBACK, buildRunEditorScriptOp, buildRunSceneScriptOp, } from "./scene-script.js";
39
+ import { RUN_EDITOR_SCRIPT_FALLBACK, RUN_SCRIPT_FALLBACK, buildRunEditorScriptOp, } from "./scene-script.js";
40
+ import { runSceneScriptOn } from "./scene-script-target.js";
39
41
  import { CAMERA_BOOKMARK_ACTIONS, CAMERA_BOOKMARK_FALLBACK, SCREENSHOT_FRAMINGS, buildCameraBookmarkOp, buildScenePreviewInput, } from "./camera-view.js";
40
42
  import { PLAY_DETERMINISM_NOT_SUPPORTED, pickPlayDeterminism, readPlayDeterminism } from "./play-determinism.js";
41
43
  import { debugViews, frameNodes, frameShot, rememberBookmarkRender, shotSheet, slotPolicy, zoom, } from "./seeing/seeing.js";
@@ -75,13 +77,12 @@ import { PLACEMENT_FIELDS, SCENE_MUTATION_OPS, SCENE_QUERY_OPS, instantiateScene
75
77
  import { attachToSurface, attachToSurfaceArgsSchema, connectPorts, connectPortsArgsSchema, inspectAsset, inspectAssetArgsSchema, measure, measureArgsSchema, placeAdjacent, placeAdjacentArgsSchema, raycast, raycastArgsSchema, repeatAlong, repeatAlongArgsSchema, } from "./placement.js";
76
78
  import { readLibraryEntry, readLibraryInputSchema } from "../library-read.js";
77
79
  import { runSearchLibrary, searchLibraryInputSchema } from "../library-search.js";
78
- import { TOOLKIT_VERSION as CLI_VERSION } from "../version.js";
80
+ import { runWithToolContext, summerRequestHeaders } from "../agent-host.js";
81
+ import { APP_DOCK_FALLBACK, appCall, appCallArgsSchema, appCreate, appCreateArgsSchema, appData, appDataArgsSchema, appDockArgsSchema, appDockOp, appEvents, appEventsArgsSchema, appGet, appGetArgsSchema, appGuide, appGuideArgsSchema, appList, appListArgsSchema, appPage, appPageArgsSchema, appScreenshot, appScreenshotArgsSchema, appUpdate, appUpdateArgsSchema, appPublish, appPublishArgsSchema, appReportGap, appReportGapArgsSchema, appsGateway, appTools, appToolsArgsSchema, } from "./apps.js";
82
+ import { enablePluginArgsSchema, enablePluginOp, interpretEnablePluginResult } from "./enable-plugin.js";
79
83
  /** Dispatch-level failure with a user-facing message (no stack needed). */
80
84
  export class ToolDispatchError extends Error {
81
85
  }
82
- /** The local engine is not reachable — a clean state, not a crash. */
83
- export class EngineUnavailableError extends ToolDispatchError {
84
- }
85
86
  /** A tool failed with a structured receipt that `summer tool` prints whole
86
87
  * (JSON on stdout, exit 1) instead of flattening to `message`: every engine
87
88
  * envelope extractOpError reads as a failure (the same gate the MCP face
@@ -96,6 +97,23 @@ export class ToolResultError extends ToolDispatchError {
96
97
  this.result = result;
97
98
  }
98
99
  }
100
+ /** A shared failure (core/error-codes.ts) — not signed in, no credits,
101
+ * network — printed as `{ok:false, code, error, recovery}` with the shell
102
+ * wording of the next step. */
103
+ export class CodedToolError extends ToolResultError {
104
+ constructor(code, message, extra = {}, recovery = CLI_RECOVERY[code]) {
105
+ super(codedFailure(code, message, extra, recovery), message);
106
+ }
107
+ }
108
+ /** The local engine is not reachable — a clean state, not a crash. Prints
109
+ * `{ok:false, code:"engine_not_running", error, recovery, hint}`. */
110
+ export class EngineUnavailableError extends CodedToolError {
111
+ constructor(message) {
112
+ super("engine_not_running", message, {
113
+ hint: "Engine-free tools (generate-*, asset search/list/get, library search/read, plan) work without it.",
114
+ });
115
+ }
116
+ }
99
117
  export function createDefaultDispatchContext() {
100
118
  let cached = null;
101
119
  return {
@@ -108,10 +126,12 @@ export function createDefaultDispatchContext() {
108
126
  }
109
127
  catch (error) {
110
128
  const reason = error instanceof Error ? error.message : String(error);
111
- throw new EngineUnavailableError("Summer Engine is not running (or no project is open).\n" +
112
- `${reason}\n` +
113
- "Start it with 'summer run' or open the project in the Summer desktop app, then retry.\n" +
114
- "Engine-free tools (generate-*, asset search/list/get, creator, plan) work without it.");
129
+ // Several editors open (or another selection problem) already says
130
+ // how to pick one; only "nothing reachable" is engine_not_running.
131
+ const notRunning = engineNotRunningFromConnectError(reason);
132
+ if (!notRunning)
133
+ throw new ToolDispatchError(reason);
134
+ throw new EngineUnavailableError(notRunning.message);
115
135
  }
116
136
  },
117
137
  };
@@ -263,17 +283,24 @@ async function dispatchUiOp(ctx, built) {
263
283
  // ---------------------------------------------------------------------------
264
284
  async function requireToken() {
265
285
  const token = await getAuthToken();
266
- if (!token) {
267
- throw new ToolDispatchError("Not signed in. Run 'summer login' first — these tools require a Summer Engine account.");
268
- }
286
+ if (!token)
287
+ throw new CodedToolError("not_signed_in", NOT_SIGNED_IN);
269
288
  return token;
270
289
  }
290
+ /** A non-OK Summer web reply: 401 and 402 carry the shared codes. */
291
+ function gatewayFailure(status, data) {
292
+ const message = String(data.message || data.error || `Request failed (${status})`);
293
+ const code = codeForStatus(status);
294
+ if (code === "not_signed_in")
295
+ return new CodedToolError(code, message, { status }, "Run: summer login --force");
296
+ if (code)
297
+ return new CodedToolError(code, message, { status });
298
+ return new ToolDispatchError(message);
299
+ }
271
300
  function gatewayHeaders(token, endpoint) {
272
301
  return {
302
+ ...summerRequestHeaders({ surface: "cli" }),
273
303
  Authorization: `Bearer ${token}`,
274
- "X-Summer-Client": "summer-cli",
275
- "X-Summer-Client-Version": CLI_VERSION,
276
- "X-Summer-Client-Surface": "cli",
277
304
  "X-Summer-MCP-Endpoint": endpoint,
278
305
  };
279
306
  }
@@ -303,12 +330,11 @@ async function gatewayGet(endpoint, params, timeoutMs = 30_000) {
303
330
  });
304
331
  }
305
332
  catch (err) {
306
- throw new ToolDispatchError(`Request failed: ${err instanceof Error ? err.message : String(err)}`);
333
+ throw new CodedToolError("unavailable", `Request failed: ${describeNetworkError(err)}`, networkDetails(err));
307
334
  }
308
335
  const data = await readJsonBody(res);
309
- if (!res.ok) {
310
- throw new ToolDispatchError(String(data.message || data.error || `Request failed (${res.status})`));
311
- }
336
+ if (!res.ok)
337
+ throw gatewayFailure(res.status, data);
312
338
  return data;
313
339
  }
314
340
  async function gatewayPost(endpoint, body, timeoutMs = 120_000) {
@@ -327,19 +353,11 @@ async function gatewayPost(endpoint, body, timeoutMs = 120_000) {
327
353
  });
328
354
  }
329
355
  catch (err) {
330
- throw new ToolDispatchError(`Generation request failed: ${err instanceof Error ? err.message : String(err)}`);
356
+ throw new CodedToolError("unavailable", `Generation request failed: ${describeNetworkError(err)}`, networkDetails(err));
331
357
  }
332
358
  const data = await readJsonBody(res);
333
- if (!res.ok) {
334
- let message = String(data.message || data.error || `Request failed (${res.status})`);
335
- if (res.status === 402) {
336
- message = `${message} — insufficient credits; top up or upgrade on the Summer dashboard.`;
337
- }
338
- if (res.status === 401) {
339
- message = `${message} — auth token expired; run 'summer login' again.`;
340
- }
341
- throw new ToolDispatchError(message);
342
- }
359
+ if (!res.ok)
360
+ throw gatewayFailure(res.status, data);
343
361
  return data;
344
362
  }
345
363
  async function pollGenerationJob(jobId, maxWaitMs = 600_000, intervalMs = 5_000) {
@@ -348,14 +366,19 @@ async function pollGenerationJob(jobId, maxWaitMs = 600_000, intervalMs = 5_000)
348
366
  const deadline = Date.now() + maxWaitMs;
349
367
  let interval = intervalMs;
350
368
  while (Date.now() < deadline) {
351
- const res = await fetch(`${gatewayUrl}/api/mcp/jobs/${encodeURIComponent(jobId)}`, {
352
- headers: gatewayHeaders(token, "/api/mcp/jobs"),
353
- signal: AbortSignal.timeout(15_000),
354
- });
355
- const data = await readJsonBody(res);
356
- if (!res.ok) {
357
- throw new ToolDispatchError(String(data.message || "Job poll failed"));
369
+ let res;
370
+ try {
371
+ res = await fetch(`${gatewayUrl}/api/mcp/jobs/${encodeURIComponent(jobId)}`, {
372
+ headers: gatewayHeaders(token, "/api/mcp/jobs"),
373
+ signal: AbortSignal.timeout(15_000),
374
+ });
358
375
  }
376
+ catch (err) {
377
+ throw new CodedToolError("unavailable", `Job poll failed: ${describeNetworkError(err)}`, { jobId, ...networkDetails(err) });
378
+ }
379
+ const data = await readJsonBody(res);
380
+ if (!res.ok)
381
+ throw gatewayFailure(res.status, { message: "Job poll failed", ...data });
359
382
  if (data.status === "completed")
360
383
  return data;
361
384
  if (data.status === "failed") {
@@ -364,7 +387,15 @@ async function pollGenerationJob(jobId, maxWaitMs = 600_000, intervalMs = 5_000)
364
387
  await new Promise((resolve) => setTimeout(resolve, interval));
365
388
  interval = Math.min(interval * 1.2, 15_000);
366
389
  }
367
- throw new ToolDispatchError(`Timed out after ${maxWaitMs / 1000}s. Re-check later with: summer tool check-job --json '{"jobId":"${jobId}"}'`);
390
+ throw new ToolDispatchError(`Timed out after ${maxWaitMs / 1000}s. Re-check later with: ${cliCheckJobCommand(jobId)}`);
391
+ }
392
+ function cliCheckJobCommand(jobId) {
393
+ return `summer tool check-job --args '{"jobId":"${jobId}"}'`;
394
+ }
395
+ /** generate-3d / generate-motion return the job at once, like the MCP face;
396
+ * `--args '{"wait":true,…}'` blocks instead. */
397
+ function cliCheckJobNext(jobId) {
398
+ return `The job runs on Summer's servers. Check it with: ${cliCheckJobCommand(jobId)}`;
368
399
  }
369
400
  async function searchAssetsGateway(params) {
370
401
  const search = new URLSearchParams();
@@ -401,9 +432,21 @@ async function gatewayReply(call) {
401
432
  catch (error) {
402
433
  if (!(error instanceof ToolDispatchError))
403
434
  throw error;
435
+ if (error instanceof CodedToolError) {
436
+ const { code, recovery } = error.result;
437
+ return { error: error.message, status: 0, code, recovery };
438
+ }
404
439
  return { error: error.message, status: 0 };
405
440
  }
406
441
  }
442
+ /** summer tool app-screenshot: the PNG goes to `out` (default ./summer-app-screenshot.png), not into the printed JSON. */
443
+ async function cliScreenshot(args, deps) {
444
+ const shot = await appScreenshot({ ...args, out: args.out ?? "summer-app-screenshot.png" }, deps);
445
+ if (shot.ok !== true || !("image" in shot))
446
+ return shot;
447
+ const { image: _image, ...report } = shot;
448
+ return report;
449
+ }
407
450
  function sfxChoicesDeps() {
408
451
  return {
409
452
  post: (endpoint, body, timeoutMs) => gatewayReply(() => gatewayPost(endpoint, body, timeoutMs)),
@@ -906,6 +949,45 @@ export const TOOL_DISPATCH = [
906
949
  throw new ToolResultError(result, String(result.error));
907
950
  return result;
908
951
  }),
952
+ // Summer Apps (core/capabilities/apps.ts): the same functions as the MCP face.
953
+ ...[
954
+ ["summer_app_guide", "Read the Summer Apps build guide (SDK, manifest, kit, layout, design, examples)", appGuideArgsSchema, appGuide],
955
+ ["summer_app_list", "List the Summer Apps in the person's workspaces", appListArgsSchema, appList],
956
+ ["summer_app_create", "Create a scratch Summer App and open it in Summer Studio", appCreateArgsSchema, appCreate],
957
+ ["summer_app_publish", "Publish a new version of a Summer App from a folder or files", appPublishArgsSchema, appPublish],
958
+ ["summer_app_get", "Read a Summer App's manifest, files and data summary", appGetArgsSchema, appGet],
959
+ ["summer_app_update", "Rename a Summer App or keep, archive or restore it", appUpdateArgsSchema, appUpdate],
960
+ ["summer_app_events", "Wait for events a Summer App sends to agents", appEventsArgsSchema, appEvents],
961
+ ["summer_app_page", "Read or use the open app's declared fields and buttons", appPageArgsSchema, appPage],
962
+ ["summer_app_data", "Read or write a Summer App's shared data", appDataArgsSchema, appData],
963
+ ["summer_app_screenshot", "See a Summer App rendered (read-only) with its console and errors; out saves the PNG", appScreenshotArgsSchema, cliScreenshot],
964
+ ["summer_app_tools", "List a Summer App's agent tools", appToolsArgsSchema, appTools],
965
+ ["summer_app_call", "Run a Summer App's agent tool in the person's open app", appCallArgsSchema, appCall],
966
+ ["summer_app_report_gap", "Report an SDK capability a Summer App needed", appReportGapArgsSchema, appReportGap],
967
+ ].map(([name, summary, schema, run]) => entry(name, summary, false, async (args) => {
968
+ const result = await run(parseToolArgs(schema, args, name.replace(/^summer_/, "").replace(/_/g, "-")), { request: appsGateway("cli", name) });
969
+ if (result.ok !== true)
970
+ throw new ToolResultError(result, String(result.error));
971
+ return result;
972
+ })),
973
+ entry("summer_enable_plugin", "Enable an editor plugin and report whether it really loaded", true, async (args, ctx) => {
974
+ const parsed = parseToolArgs(enablePluginArgsSchema, args, "enable-plugin");
975
+ const result = interpretEnablePluginResult(await (await ctx.engine()).executeOps([enablePluginOp(parsed)]));
976
+ if (result.ok !== true)
977
+ throw new ToolResultError(result, String(result.error));
978
+ return result;
979
+ }),
980
+ entry("summer_app_dock", "Dock a Summer App in the editor, close its dock, or list docks", true, async (args, ctx) => {
981
+ const parsed = parseToolArgs(appDockArgsSchema, args, "app-dock");
982
+ if (parsed.action !== "list" && !parsed.appId)
983
+ throw new ToolDispatchError(`${parsed.action} needs appId`);
984
+ const op = appDockOp(parsed);
985
+ const client = await ctx.engine();
986
+ const missing = missingEngineOpResult(client, op.op, APP_DOCK_FALLBACK);
987
+ if (missing)
988
+ throw new ToolResultError({ ...missing }, missing.error);
989
+ return requireEngineSuccess(await client.executeOps([op]));
990
+ }),
909
991
  entry("summer_generate_3d", "Generate a 3D model (optional auto-rig + animations)", false, async (args) => {
910
992
  const options = {
911
993
  ...(args.options ?? {}),
@@ -929,8 +1011,8 @@ export const TOOL_DISPATCH = [
929
1011
  options,
930
1012
  });
931
1013
  const jobId = typeof result.jobId === "string" ? result.jobId : undefined;
932
- if (args.wait === false || !jobId)
933
- return result;
1014
+ if (args.wait !== true || !jobId)
1015
+ return jobId ? { ...result, next: cliCheckJobNext(jobId) } : result;
934
1016
  const final = await pollGenerationJob(jobId);
935
1017
  return { ...final, jobId };
936
1018
  }),
@@ -951,7 +1033,7 @@ export const TOOL_DISPATCH = [
951
1033
  const result = await gatewayPost("/api/mcp/generate/motion", built.body);
952
1034
  const jobId = typeof result.jobId === "string" ? result.jobId : undefined;
953
1035
  if (!parsed.wait || !jobId)
954
- return result;
1036
+ return jobId ? { ...result, next: cliCheckJobNext(jobId) } : result;
955
1037
  const final = await pollGenerationJob(jobId, 600_000);
956
1038
  return { ...final, jobId };
957
1039
  }),
@@ -1204,19 +1286,19 @@ export const TOOL_DISPATCH = [
1204
1286
  return runBatch(await ctx.engine(), { scenePath, ops, receipt });
1205
1287
  }),
1206
1288
  // --- scene scripting ---
1207
- entry("summer_run_script", "Run a GDScript func run(ctx) inside the live editor against the open scene", true, async (args, ctx) => {
1289
+ entry("summer_run_script", "Run a GDScript func run(ctx) inside the live editor against scenePath (or the open scene)", true, async (args, ctx) => {
1208
1290
  const client = await ctx.engine();
1209
1291
  const missing = missingEngineOpResult(client, "RunSceneScript", RUN_SCRIPT_FALLBACK);
1210
1292
  if (missing)
1211
1293
  refuseMissingOp(missing);
1212
1294
  const undo = optStr(args, "undo");
1213
- const { op, timeoutMs } = buildRunSceneScriptOp({
1295
+ return requireSupportedOp(await runSceneScriptOn(client, {
1296
+ scenePath: optStr(args, "scenePath"),
1214
1297
  source: str(args, "source"),
1215
1298
  max_seconds: typeof args.max_seconds === "number" ? args.max_seconds : undefined,
1216
1299
  checkpoint: typeof args.checkpoint === "boolean" ? args.checkpoint : undefined,
1217
1300
  undo: undo === "action" || undo === "none" ? undo : undefined,
1218
- });
1219
- return requireSupportedOp(await client.executeIdentityBoundOps([op], undefined, timeoutMs), "RunSceneScript", RUN_SCRIPT_FALLBACK);
1301
+ }), "RunSceneScript", RUN_SCRIPT_FALLBACK);
1220
1302
  }),
1221
1303
  entry("summer_run_editor_script", "Run an EditorScript in a fresh headless child editor against the on-disk project", true, async (args, ctx) => {
1222
1304
  const client = await ctx.engine();
@@ -1681,5 +1763,7 @@ export async function dispatchTool(nameOrSlug, args, ctx = createDefaultDispatch
1681
1763
  // The one gate every result passes, mirroring withEngine on the MCP face:
1682
1764
  // whatever the MCP face would mark isError is a ToolResultError here, so the
1683
1765
  // CLI exit code says what the receipt says — for every tool, not per handler.
1684
- return requireEngineSuccess(await dispatchEntry.handler(args, ctx));
1766
+ // Summer requests made for this call name the tool (core/agent-host.ts); the
1767
+ // MCP face sets the same context in its call wrapper.
1768
+ return requireEngineSuccess(await runWithToolContext(dispatchEntry.name, "cli", () => dispatchEntry.handler(args, ctx)));
1685
1769
  }
@@ -49,6 +49,10 @@ export const CLI_KNOWN_OP_NEEDS = [
49
49
  // engine's one-table op; the other three are the legacy
50
50
  // fallbacks on engines that predate it.
51
51
  "Navigate", "OpenResource", "FocusDock", "RevealInFileSystem",
52
+ // Summer Apps editor docks (summer_app_dock: core/capabilities/apps.ts)
53
+ "OpenAppDock", "CloseAppDock", "ListAppDocks",
54
+ // summer_enable_plugin (core/capabilities/enable-plugin.ts)
55
+ "EnableEditorPlugin",
52
56
  // Project + input
53
57
  "ProjectSetting", "InputMapAddAction", "InputMapBind",
54
58
  // Files (summer_write_file / summer_replace_text / summer_create_scene)
@@ -47,6 +47,8 @@ export interface EmbedProviderOptions {
47
47
  token?: string | null;
48
48
  timeoutMs: number;
49
49
  fetchImpl?: typeof fetch;
50
+ /** Extra request headers (the runtime's client and agent-host headers). */
51
+ headers?: Record<string, string>;
50
52
  }
51
53
  export declare function encodeVector(vector: readonly number[]): string;
52
54
  export declare function decodeVector(encoded: string): Float32Array;
@@ -140,7 +140,7 @@ export function createEmbedProvider(options) {
140
140
  const controller = new AbortController();
141
141
  const timer = setTimeout(() => controller.abort(), options.timeoutMs);
142
142
  try {
143
- const headers = { "Content-Type": "application/json" };
143
+ const headers = { ...options.headers, "Content-Type": "application/json" };
144
144
  if (options.token)
145
145
  headers.Authorization = `Bearer ${options.token}`;
146
146
  const response = await fetchImpl(options.url, {
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Stable codes for the failures any Summer tool can hit before it does its
3
+ * job: the engine is not running, the person is not signed in, the account
4
+ * has no credits left, or the network failed. Agents branch on `code` and
5
+ * follow `recovery` (one next step); the older fields each tool returned
6
+ * (`error`, `message`, `hint`) stay next to them so 3.x callers keep working.
7
+ *
8
+ * The store sign-in keeps its own code, `store_login_required`
9
+ * (core/oauth.ts): it is a second grant with its own recovery
10
+ * (`summer login --store`).
11
+ *
12
+ * The codes are the ones the 4.0 tools use (one closed list, shared with the
13
+ * hosted Summer MCP), so 4.0 changes where they sit, not their names.
14
+ */
15
+ export type SummerErrorCode = "engine_not_running" | "not_signed_in" | "no_credits" | "unavailable";
16
+ export declare const SIGN_IN_COMMAND = "npx -y summer-engine@latest login";
17
+ export declare const CREDITS_URL = "https://summerengine.com/studio/credits";
18
+ /** The one sentence every tool uses when there is no Summer account token. */
19
+ export declare const NOT_SIGNED_IN = "Not signed in to Summer.";
20
+ /** A token the server refused (expired, revoked): plain `login` would say
21
+ * "Already logged in", so the step forces a new sign-in. */
22
+ export declare const SIGN_IN_AGAIN_RECOVERY = "Ask the person to sign in again: npx -y summer-engine@latest login --force";
23
+ /** The one next step per code, as the MCP face words it (the agent may not
24
+ * have `summer` on PATH, so commands go through npx). */
25
+ export declare const RECOVERY: Record<SummerErrorCode, string>;
26
+ /** The same steps for `summer tool` in a shell, where `summer` is the CLI. */
27
+ export declare const CLI_RECOVERY: Record<SummerErrorCode, string>;
28
+ export interface CodedFailure {
29
+ ok: false;
30
+ code: SummerErrorCode;
31
+ error: string;
32
+ recovery: string;
33
+ }
34
+ /** `{ok:false, code, error, recovery}` first, then any other fields the
35
+ * tool already returned (`message`, `hint`, `status`, …). The four named
36
+ * fields win over `extra`; `recovery` defaults to the MCP wording. */
37
+ export declare function codedFailure(code: SummerErrorCode, error: string, extra?: Record<string, unknown>, recovery?: string): CodedFailure & Record<string, unknown>;
38
+ /** The code for a failed Summer web request by HTTP status, when it is one
39
+ * of the shared ones. */
40
+ export declare function codeForStatus(status: number): SummerErrorCode | null;
41
+ /** The message for a failed request, with the real cause in it. */
42
+ export declare function describeNetworkError(error: unknown): string;
43
+ /** `details.cause` for an `unavailable` answer. */
44
+ export declare function networkDetails(error: unknown): {
45
+ details: {
46
+ cause: string;
47
+ };
48
+ };
49
+ /** The engine connect failure that means "nothing is running for this
50
+ * project", worded for the person; the raw reason (token files, instance
51
+ * registry paths) stays in the logs, not in the line the agent repeats. */
52
+ export declare class EngineNotRunningError extends Error {
53
+ readonly reason: string;
54
+ readonly code: "engine_not_running";
55
+ constructor(message: string, reason: string);
56
+ }
57
+ /** A connect error from core/engine.ts → EngineNotRunningError when it means
58
+ * no editor is reachable; null for the others (several editors open, …),
59
+ * which already say what to do. */
60
+ export declare function engineNotRunningFromConnectError(reason: string): EngineNotRunningError | null;
61
+ /** Engine-free tools keep working while the engine is down. */
62
+ export declare const ENGINE_FREE_NOTE: string;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Stable codes for the failures any Summer tool can hit before it does its
3
+ * job: the engine is not running, the person is not signed in, the account
4
+ * has no credits left, or the network failed. Agents branch on `code` and
5
+ * follow `recovery` (one next step); the older fields each tool returned
6
+ * (`error`, `message`, `hint`) stay next to them so 3.x callers keep working.
7
+ *
8
+ * The store sign-in keeps its own code, `store_login_required`
9
+ * (core/oauth.ts): it is a second grant with its own recovery
10
+ * (`summer login --store`).
11
+ *
12
+ * The codes are the ones the 4.0 tools use (one closed list, shared with the
13
+ * hosted Summer MCP), so 4.0 changes where they sit, not their names.
14
+ */
15
+ export const SIGN_IN_COMMAND = "npx -y summer-engine@latest login";
16
+ export const CREDITS_URL = "https://summerengine.com/studio/credits";
17
+ /** The one sentence every tool uses when there is no Summer account token. */
18
+ export const NOT_SIGNED_IN = "Not signed in to Summer.";
19
+ /** A token the server refused (expired, revoked): plain `login` would say
20
+ * "Already logged in", so the step forces a new sign-in. */
21
+ export const SIGN_IN_AGAIN_RECOVERY = `Ask the person to sign in again: ${SIGN_IN_COMMAND} --force`;
22
+ /** The one next step per code, as the MCP face words it (the agent may not
23
+ * have `summer` on PATH, so commands go through npx). */
24
+ export const RECOVERY = {
25
+ engine_not_running: "Open the project in Summer Engine, or run: npx -y summer-engine@latest run <project-path> (the folder that holds project.godot).",
26
+ not_signed_in: `Ask the person to sign in: ${SIGN_IN_COMMAND}`,
27
+ no_credits: `Ask the person to add credits: ${CREDITS_URL}`,
28
+ unavailable: "Check the network connection, then retry.",
29
+ };
30
+ /** The same steps for `summer tool` in a shell, where `summer` is the CLI. */
31
+ export const CLI_RECOVERY = {
32
+ ...RECOVERY,
33
+ engine_not_running: "Open the project in Summer Engine, or run: summer run <project-path> (the folder that holds project.godot).",
34
+ not_signed_in: "Run: summer login",
35
+ };
36
+ /** `{ok:false, code, error, recovery}` first, then any other fields the
37
+ * tool already returned (`message`, `hint`, `status`, …). The four named
38
+ * fields win over `extra`; `recovery` defaults to the MCP wording. */
39
+ export function codedFailure(code, error, extra = {}, recovery = RECOVERY[code]) {
40
+ const named = { ok: false, code, error, recovery };
41
+ return Object.assign({ ...named }, extra, named);
42
+ }
43
+ /** The code for a failed Summer web request by HTTP status, when it is one
44
+ * of the shared ones. */
45
+ export function codeForStatus(status) {
46
+ if (status === 401)
47
+ return "not_signed_in";
48
+ if (status === 402)
49
+ return "no_credits";
50
+ return null;
51
+ }
52
+ /** `fetch failed` says nothing; Node puts the real reason on `cause`
53
+ * (`connect ECONNREFUSED 127.0.0.1:443`, `getaddrinfo ENOTFOUND …`). */
54
+ function networkCause(error) {
55
+ const message = error instanceof Error ? error.message : String(error);
56
+ const cause = error instanceof Error ? error.cause : undefined;
57
+ return cause instanceof Error ? cause.message : typeof cause === "string" ? cause : message;
58
+ }
59
+ /** The message for a failed request, with the real cause in it. */
60
+ export function describeNetworkError(error) {
61
+ const message = error instanceof Error ? error.message : String(error);
62
+ const cause = networkCause(error);
63
+ return message.includes(cause) ? message : `${message} (${cause})`;
64
+ }
65
+ /** `details.cause` for an `unavailable` answer. */
66
+ export function networkDetails(error) {
67
+ return { details: { cause: networkCause(error) } };
68
+ }
69
+ /** The engine connect failure that means "nothing is running for this
70
+ * project", worded for the person; the raw reason (token files, instance
71
+ * registry paths) stays in the logs, not in the line the agent repeats. */
72
+ export class EngineNotRunningError extends Error {
73
+ reason;
74
+ code = "engine_not_running";
75
+ constructor(message, reason) {
76
+ super(message);
77
+ this.reason = reason;
78
+ this.name = "EngineNotRunningError";
79
+ }
80
+ }
81
+ /** A connect error from core/engine.ts → EngineNotRunningError when it means
82
+ * no editor is reachable; null for the others (several editors open, …),
83
+ * which already say what to do. */
84
+ export function engineNotRunningFromConnectError(reason) {
85
+ const port = reason.match(/not responding on port (\d+)/)?.[1];
86
+ if (port)
87
+ return new EngineNotRunningError(`Summer Engine is not responding on port ${port}.`, reason);
88
+ if (/^No running Summer editor matches/.test(reason)) {
89
+ return new EngineNotRunningError(reason.split(/(?<=\.)\s/)[0], reason);
90
+ }
91
+ if (/not running/i.test(reason))
92
+ return new EngineNotRunningError("Summer Engine is not running.", reason);
93
+ return null;
94
+ }
95
+ /** Engine-free tools keep working while the engine is down. */
96
+ export const ENGINE_FREE_NOTE = "Only tools that touch the local project need the engine. Library, generation and asset tools " +
97
+ "(summer_search_library, summer_generate_*, summer_search_assets, summer_list_my_assets, summer_get_asset, summer_check_job) work now.";
@@ -1,3 +1,5 @@
1
+ /** ANSI colour only for a terminal: NO_COLOR turns it off, FORCE_COLOR on. */
2
+ export declare function useColor(): boolean;
1
3
  export declare const c: {
2
4
  bold: (s: string) => string;
3
5
  dim: (s: string) => string;
@@ -10,7 +10,8 @@ const ANSI = {
10
10
  // Summer brand orange (matches banner.ts mid gradient)
11
11
  brand: "\x1b[38;2;255;143;23m",
12
12
  };
13
- function useColor() {
13
+ /** ANSI colour only for a terminal: NO_COLOR turns it off, FORCE_COLOR on. */
14
+ export function useColor() {
14
15
  if (process.env.NO_COLOR)
15
16
  return false;
16
17
  if (process.env.FORCE_COLOR)
@@ -1,4 +1,5 @@
1
1
  import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
+ import { OAuthError } from "./oauth.js";
2
3
  /** The part of an MCP client the mount and the CLI use (a fake in tests). */
3
4
  export interface HostedClient {
4
5
  listTools(params?: {
@@ -54,7 +55,26 @@ export interface HostedConnectDependencies {
54
55
  connect: (url: string, token: () => Promise<string>) => Promise<HostedClient>;
55
56
  }
56
57
  export declare function connectHostedMcp(url: string, token: () => Promise<string>): Promise<HostedClient>;
58
+ /**
59
+ * The hosted server's 3.x surface: the same address with `?surface=v3`. Once
60
+ * the hosted server serves 4.0 to every request that does not ask, only 3.x
61
+ * npm releases keep 3.x without asking, so the 3.x tool names here ask.
62
+ */
63
+ export declare function withV3Surface(url: string): string;
57
64
  export declare const defaultHostedConnectDependencies: HostedConnectDependencies;
65
+ /** The hosted server could not be reached, so no call was sent (a sign-in problem is an OAuthError instead). */
66
+ export declare class HostedUnreachableError extends Error {
67
+ readonly recovery: string;
68
+ constructor(message: string, recovery: string);
69
+ }
70
+ /** The HTTP status an MCP transport error carries (the SDK's StreamableHTTPError puts it on `code`). */
71
+ export declare function httpStatusOf(error: unknown): number | undefined;
72
+ /**
73
+ * A failure to connect to the hosted server, before any call was sent: a
74
+ * sign-in problem (an OAuthError, or a 401), an account the server refuses
75
+ * (403, store_access_denied), or the server not answering.
76
+ */
77
+ export declare function hostedConnectFailure(error: unknown, unreachableRecovery: string): OAuthError | HostedUnreachableError;
58
78
  /** True when this machine has a store sign-in on disk (no network). */
59
79
  export declare function hasStoreSignIn(): Promise<boolean>;
60
80
  export declare function listAllHostedTools(client: HostedClient): Promise<Tool[]>;
@@ -113,3 +133,5 @@ export type HostedCallOutcome = {
113
133
  };
114
134
  /** Call a hosted tool by its name or slug with the store sign-in (one connection). */
115
135
  export declare function callHostedToolForCli(name: string, args: Record<string, unknown>, deps?: HostedConnectDependencies, signedIn?: () => Promise<boolean>): Promise<HostedCallOutcome>;
136
+ /** The tool a tools/call JSON-RPC body names, for the X-Summer-MCP-Tool header. */
137
+ export declare function calledTool(body: unknown): string | undefined;
@@ -2,6 +2,7 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
2
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
3
3
  import { getStoreAccessToken, OAuthError, readStoredOAuthToken, resolveMcpResourceUrl } from "./oauth.js";
4
4
  import { TOOLKIT_VERSION } from "./version.js";
5
+ import { summerRequestHeaders } from "./agent-host.js";
5
6
  /**
6
7
  * A client for the hosted Summer Engine MCP (mcp.summerengine.com), signed in
7
8
  * with the store sign-in ("summer login --store"). The local MCP mounts its
@@ -15,6 +16,8 @@ export async function connectHostedMcp(url, token) {
15
16
  // A fresh (refreshed when near expiry) token on every request.
16
17
  fetch: async (input, init) => {
17
18
  const headers = new Headers(init?.headers);
19
+ for (const [name, value] of Object.entries(summerRequestHeaders({ tool: calledTool(init?.body), surface: "mcp" })))
20
+ headers.set(name, value);
18
21
  headers.set("authorization", `Bearer ${await token()}`);
19
22
  return fetch(input, { ...init, headers });
20
23
  },
@@ -32,11 +35,51 @@ export async function connectHostedMcp(url, token) {
32
35
  close: () => client.close(),
33
36
  };
34
37
  }
38
+ /**
39
+ * The hosted server's 3.x surface: the same address with `?surface=v3`. Once
40
+ * the hosted server serves 4.0 to every request that does not ask, only 3.x
41
+ * npm releases keep 3.x without asking, so the 3.x tool names here ask.
42
+ */
43
+ export function withV3Surface(url) {
44
+ const parsed = new URL(url);
45
+ parsed.searchParams.set("surface", "v3");
46
+ return parsed.href;
47
+ }
35
48
  export const defaultHostedConnectDependencies = {
36
- url: () => resolveMcpResourceUrl(),
49
+ url: () => withV3Surface(resolveMcpResourceUrl()),
37
50
  token: () => getStoreAccessToken(),
38
51
  connect: connectHostedMcp,
39
52
  };
53
+ /** The hosted server could not be reached, so no call was sent (a sign-in problem is an OAuthError instead). */
54
+ export class HostedUnreachableError extends Error {
55
+ recovery;
56
+ constructor(message, recovery) {
57
+ super(`${message} ${recovery}`);
58
+ this.recovery = recovery;
59
+ this.name = "HostedUnreachableError";
60
+ }
61
+ }
62
+ /** The HTTP status an MCP transport error carries (the SDK's StreamableHTTPError puts it on `code`). */
63
+ export function httpStatusOf(error) {
64
+ const code = error?.code;
65
+ return typeof code === "number" && code >= 100 && code <= 599 ? code : undefined;
66
+ }
67
+ /**
68
+ * A failure to connect to the hosted server, before any call was sent: a
69
+ * sign-in problem (an OAuthError, or a 401), an account the server refuses
70
+ * (403, store_access_denied), or the server not answering.
71
+ */
72
+ export function hostedConnectFailure(error, unreachableRecovery) {
73
+ if (error instanceof OAuthError || error instanceof HostedUnreachableError)
74
+ return error;
75
+ const cause = error instanceof Error ? error.message : String(error);
76
+ const status = httpStatusOf(error);
77
+ if (status === 401)
78
+ return new OAuthError("oauth_token_invalid", `Summer's hosted server refused the sign-in: ${cause}.`, 'Recovery: run "summer login --store --force".');
79
+ if (status === 403)
80
+ return new OAuthError("store_access_denied", `Summer's hosted server refused this account: ${cause}.`, "Recovery: check the account in Summer Studio (for example confirm the email), then try again.");
81
+ return new HostedUnreachableError(`The hosted Summer Engine MCP did not answer: ${cause}.`, unreachableRecovery);
82
+ }
40
83
  /** True when this machine has a store sign-in on disk (no network). */
41
84
  export async function hasStoreSignIn() {
42
85
  return (await readStoredOAuthToken()) !== null;
@@ -162,3 +205,15 @@ export async function callHostedToolForCli(name, args, deps = defaultHostedConne
162
205
  return { status: "unavailable", message: error instanceof Error ? error.message : String(error) };
163
206
  }
164
207
  }
208
+ /** The tool a tools/call JSON-RPC body names, for the X-Summer-MCP-Tool header. */
209
+ export function calledTool(body) {
210
+ if (typeof body !== "string" || !body.includes('"tools/call"'))
211
+ return undefined;
212
+ try {
213
+ const message = JSON.parse(body);
214
+ return message.method === "tools/call" && typeof message.params?.name === "string" ? message.params.name : undefined;
215
+ }
216
+ catch {
217
+ return undefined;
218
+ }
219
+ }