summer-engine 3.8.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (485) hide show
  1. package/.claude-plugin/marketplace.json +2 -13
  2. package/.claude-plugin/plugin.json +23 -22
  3. package/.codex-plugin/plugin.json +4 -12
  4. package/.cursor-plugin/plugin.json +4 -12
  5. package/.factory-plugin/plugin.json +4 -12
  6. package/AGENTS.md +19 -12
  7. package/CHANGELOG.md +96 -0
  8. package/GEMINI.md +3 -3
  9. package/README.md +103 -33
  10. package/assets/icon.png +0 -0
  11. package/commands/start.md +71 -0
  12. package/commands/summer.md +3 -2
  13. package/dist/cli/banner.js +3 -0
  14. package/dist/cli/commands/login.d.ts +27 -0
  15. package/dist/cli/commands/login.js +58 -12
  16. package/dist/cli/commands/ops.d.ts +47 -0
  17. package/dist/cli/commands/ops.js +301 -0
  18. package/dist/cli/commands/setup.d.ts +2 -0
  19. package/dist/cli/commands/setup.js +37 -12
  20. package/dist/cli/commands/skills.js +11 -7
  21. package/dist/cli/index.js +7 -0
  22. package/dist/core/agent-host.d.ts +65 -0
  23. package/dist/core/agent-host.js +193 -0
  24. package/dist/core/capabilities/agent-playbook.d.ts +3 -0
  25. package/dist/core/capabilities/agent-playbook.js +54 -2
  26. package/dist/core/capabilities/apps.d.ts +25 -2
  27. package/dist/core/capabilities/apps.js +25 -12
  28. package/dist/core/capabilities/doctor.d.ts +3 -0
  29. package/dist/core/capabilities/doctor.js +20 -15
  30. package/dist/core/capabilities/fabricate-mesh.d.ts +2 -2
  31. package/dist/core/capabilities/game-task-plan.d.ts +12 -6
  32. package/dist/core/capabilities/game-task-plan.js +80 -5
  33. package/dist/core/capabilities/motion-generation.js +2 -2
  34. package/dist/core/capabilities/navigation/open.d.ts +6 -2
  35. package/dist/core/capabilities/navigation/open.js +3 -0
  36. package/dist/core/capabilities/publish-build.js +2 -0
  37. package/dist/core/capabilities/runtime-control.d.ts +4 -4
  38. package/dist/core/capabilities/scene-script-target.d.ts +17 -0
  39. package/dist/core/capabilities/scene-script-target.js +70 -0
  40. package/dist/core/capabilities/sfx-choices.d.ts +4 -0
  41. package/dist/core/capabilities/sfx-choices.js +13 -6
  42. package/dist/core/capabilities/tool-dispatch.d.ts +12 -3
  43. package/dist/core/capabilities/tool-dispatch.js +81 -46
  44. package/dist/core/embeddings.d.ts +2 -0
  45. package/dist/core/embeddings.js +1 -1
  46. package/dist/core/error-codes.d.ts +62 -0
  47. package/dist/core/error-codes.js +97 -0
  48. package/dist/core/format.d.ts +2 -0
  49. package/dist/core/format.js +2 -1
  50. package/dist/core/hosted-mcp.d.ts +22 -0
  51. package/dist/core/hosted-mcp.js +56 -1
  52. package/dist/core/library-read.js +5 -0
  53. package/dist/core/library-search.js +2 -1
  54. package/dist/core/oauth.js +4 -0
  55. package/dist/core/ops/catalog.d.ts +41 -0
  56. package/dist/core/ops/catalog.js +145 -0
  57. package/dist/core/ops/cloud.d.ts +56 -0
  58. package/dist/core/ops/cloud.js +175 -0
  59. package/dist/core/ops/contract.d.ts +119 -0
  60. package/dist/core/ops/contract.js +142 -0
  61. package/dist/core/ops/engine-answer.d.ts +25 -0
  62. package/dist/core/ops/engine-answer.js +117 -0
  63. package/dist/core/ops/engine.d.ts +55 -0
  64. package/dist/core/ops/engine.js +649 -0
  65. package/dist/core/ops/save-files.d.ts +78 -0
  66. package/dist/core/ops/save-files.js +419 -0
  67. package/dist/core/ops/search.d.ts +9 -0
  68. package/dist/core/ops/search.js +55 -0
  69. package/dist/core/skills-registry.d.ts +16 -1
  70. package/dist/core/skills-registry.js +35 -2
  71. package/dist/core/telemetry.d.ts +32 -0
  72. package/dist/core/telemetry.js +38 -10
  73. package/dist/core/tool-profiles.d.ts +25 -0
  74. package/dist/core/tool-profiles.js +41 -0
  75. package/dist/installer/agent-config.d.ts +17 -4
  76. package/dist/installer/agent-config.js +22 -6
  77. package/dist/installer/agent-table.d.ts +3 -0
  78. package/dist/installer/agent-table.js +10 -7
  79. package/dist/installer/setup.d.ts +2 -0
  80. package/dist/installer/setup.js +9 -4
  81. package/dist/installer/version-check.d.ts +29 -9
  82. package/dist/installer/version-check.js +81 -28
  83. package/dist/mcp/command.js +7 -0
  84. package/dist/mcp/hosted-mount.d.ts +27 -2
  85. package/dist/mcp/hosted-mount.js +53 -23
  86. package/dist/mcp/legacy-toolset.d.ts +27 -0
  87. package/dist/mcp/legacy-toolset.js +43 -0
  88. package/dist/mcp/ops-surface.d.ts +59 -0
  89. package/dist/mcp/ops-surface.js +443 -0
  90. package/dist/mcp/server.d.ts +35 -11
  91. package/dist/mcp/server.js +234 -89
  92. package/dist/mcp/tool-results.d.ts +26 -0
  93. package/dist/mcp/tool-results.js +81 -0
  94. package/dist/mcp/tool-surface.d.ts +65 -0
  95. package/dist/mcp/tool-surface.js +317 -0
  96. package/dist/mcp/tools/app-tools.js +9 -2
  97. package/dist/mcp/tools/asset-tools.js +55 -53
  98. package/dist/mcp/tools/audit-tools.js +21 -21
  99. package/dist/mcp/tools/debug-tools.js +6 -6
  100. package/dist/mcp/tools/fabricate-tools.js +6 -6
  101. package/dist/mcp/tools/generate-tools.js +76 -70
  102. package/dist/mcp/tools/project-tools.d.ts +9 -4
  103. package/dist/mcp/tools/project-tools.js +16 -10
  104. package/dist/mcp/tools/scene-tools.js +12 -23
  105. package/dist/mcp/tools/script-tools.js +9 -5
  106. package/dist/mcp/tools/with-engine.d.ts +6 -0
  107. package/dist/mcp/tools/with-engine.js +19 -0
  108. package/gemini-extension.json +4 -12
  109. package/hooks/pre-commit-doctor.sh +5 -4
  110. package/hooks/session-start.sh +24 -28
  111. package/integrations/claude-desktop/README.md +1 -1
  112. package/integrations/copilot-jetbrains/README.md +1 -1
  113. package/integrations/junie/README.md +1 -1
  114. package/integrations/lm-studio/README.md +1 -1
  115. package/integrations/trae/README.md +1 -1
  116. package/integrations/visual-studio/README.md +1 -1
  117. package/library/references/mcp-tools-reference/mcp-tools-reference.md +79 -51
  118. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  119. package/library/references/product-map/resource.yaml +2 -2
  120. package/library/skills/3d-lighting/SKILL.md +53 -28
  121. package/library/skills/3d-lighting/resource.yaml +1 -1
  122. package/library/skills/README.md +119 -117
  123. package/library/skills/adaptive-music/SKILL.md +19 -23
  124. package/library/skills/adaptive-music/resource.yaml +1 -1
  125. package/library/skills/agent-playtesting/SKILL.md +1 -1
  126. package/library/skills/agent-playtesting/resource.yaml +1 -1
  127. package/library/skills/ai-characters-in-games/SKILL.md +1 -1
  128. package/library/skills/ai-characters-in-games/resource.yaml +1 -1
  129. package/library/skills/ambient-bed/SKILL.md +22 -13
  130. package/library/skills/ambient-bed/resource.yaml +1 -1
  131. package/library/skills/animated-loop/SKILL.md +41 -32
  132. package/library/skills/animated-loop/resource.yaml +1 -1
  133. package/library/skills/animation-tree/SKILL.md +1 -1
  134. package/library/skills/animation-tree/resource.yaml +1 -1
  135. package/library/skills/art-direction/SKILL.md +3 -3
  136. package/library/skills/art-direction/resource.yaml +1 -1
  137. package/library/skills/asset-strategy/SKILL.md +21 -4
  138. package/library/skills/asset-strategy/resource.yaml +2 -1
  139. package/library/skills/audio-direction/SKILL.md +10 -10
  140. package/library/skills/audio-direction/resource.yaml +1 -1
  141. package/library/skills/auto-fire-targeting/SKILL.md +1 -1
  142. package/library/skills/auto-fire-targeting/resource.yaml +1 -1
  143. package/library/skills/bounded-engine-runs/SKILL.md +1 -1
  144. package/library/skills/bounded-engine-runs/resource.yaml +1 -1
  145. package/library/skills/brainstorm-game/SKILL.md +1 -1
  146. package/library/skills/brainstorm-game/resource.yaml +1 -1
  147. package/library/skills/brainstorming/SKILL.md +1 -1
  148. package/library/skills/brainstorming/resource.yaml +1 -1
  149. package/library/skills/browse-templates/SKILL.md +1 -1
  150. package/library/skills/browse-templates/resource.yaml +1 -1
  151. package/library/skills/camera-rigs/SKILL.md +2 -2
  152. package/library/skills/camera-rigs/resource.yaml +1 -1
  153. package/library/skills/celeste-momentum-platforming/resource.yaml +1 -0
  154. package/library/skills/character-animation-wiring/SKILL.md +4 -4
  155. package/library/skills/character-animation-wiring/resource.yaml +1 -1
  156. package/library/skills/character-model/SKILL.md +55 -47
  157. package/library/skills/character-model/resource.yaml +1 -1
  158. package/library/skills/character-movement/SKILL.md +3 -3
  159. package/library/skills/character-movement/resource.yaml +1 -1
  160. package/library/skills/character-portrait/SKILL.md +24 -19
  161. package/library/skills/character-portrait/resource.yaml +1 -1
  162. package/library/skills/cinematic-cutscene/SKILL.md +58 -46
  163. package/library/skills/cinematic-cutscene/resource.yaml +1 -1
  164. package/library/skills/combat-basics/SKILL.md +1 -1
  165. package/library/skills/combat-basics/resource.yaml +1 -1
  166. package/library/skills/compatibility-renderer-traps/SKILL.md +1 -1
  167. package/library/skills/compatibility-renderer-traps/resource.yaml +1 -1
  168. package/library/skills/concept-art/SKILL.md +16 -12
  169. package/library/skills/concept-art/resource.yaml +1 -1
  170. package/library/skills/concept-to-level/SKILL.md +239 -0
  171. package/library/skills/concept-to-level/references/technical-rules.md +150 -0
  172. package/library/skills/concept-to-level/resource.yaml +44 -0
  173. package/library/skills/create-asset-sheet/SKILL.md +19 -13
  174. package/library/skills/create-asset-sheet/resource.yaml +1 -1
  175. package/library/skills/debug/SKILL.md +2 -2
  176. package/library/skills/debug/resource.yaml +1 -1
  177. package/library/skills/debugging-game-feel/SKILL.md +1 -1
  178. package/library/skills/debugging-game-feel/resource.yaml +1 -1
  179. package/library/skills/design-level/SKILL.md +23 -35
  180. package/library/skills/design-level/resource.yaml +1 -1
  181. package/library/skills/design-mechanic/SKILL.md +1 -1
  182. package/library/skills/design-mechanic/resource.yaml +1 -1
  183. package/library/skills/design-npc/SKILL.md +22 -24
  184. package/library/skills/design-npc/resource.yaml +1 -1
  185. package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
  186. package/library/skills/diagnosing-perf-regressions/resource.yaml +1 -1
  187. package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
  188. package/library/skills/driving-the-editor-ui/resource.yaml +1 -1
  189. package/library/skills/environment-kit/SKILL.md +20 -16
  190. package/library/skills/environment-kit/resource.yaml +1 -1
  191. package/library/skills/export-and-ship/SKILL.md +6 -6
  192. package/library/skills/export-and-ship/resource.yaml +1 -1
  193. package/library/skills/fabricating-assets/SKILL.md +7 -7
  194. package/library/skills/fabricating-assets/resource.yaml +3 -3
  195. package/library/skills/facial-and-lipsync/SKILL.md +14 -15
  196. package/library/skills/facial-and-lipsync/resource.yaml +1 -1
  197. package/library/skills/fps-controller/SKILL.md +33 -41
  198. package/library/skills/fps-controller/resource.yaml +1 -1
  199. package/library/skills/game-feel/SKILL.md +8 -8
  200. package/library/skills/game-feel/resource.yaml +1 -1
  201. package/library/skills/gameskill/SKILL.md +4 -4
  202. package/library/skills/gameskill/resource.yaml +1 -1
  203. package/library/skills/gdscript-patterns/SKILL.md +1 -1
  204. package/library/skills/gdscript-patterns/resource.yaml +1 -1
  205. package/library/skills/generate-motion/SKILL.md +30 -21
  206. package/library/skills/generate-motion/resource.yaml +1 -1
  207. package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
  208. package/library/skills/godogen-visual-proof-game-generation/resource.yaml +1 -0
  209. package/library/skills/grow-analytics/SKILL.md +3 -3
  210. package/library/skills/grow-analytics/resource.yaml +1 -1
  211. package/library/skills/headless-scripting/SKILL.md +1 -1
  212. package/library/skills/headless-scripting/resource.yaml +1 -1
  213. package/library/skills/in-game-purchases/SKILL.md +1 -1
  214. package/library/skills/in-game-purchases/resource.yaml +1 -1
  215. package/library/skills/instantiate-asset-pack/SKILL.md +2 -2
  216. package/library/skills/instantiate-asset-pack/resource.yaml +1 -1
  217. package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +1 -0
  218. package/library/skills/make-game/SKILL.md +4 -4
  219. package/library/skills/make-game/references/2d-platformer.md +1 -1
  220. package/library/skills/make-game/references/3d-fps.md +1 -1
  221. package/library/skills/make-game/references/3d-horror.md +1 -1
  222. package/library/skills/make-game/references/3d-third-person.md +2 -2
  223. package/library/skills/make-game/resource.yaml +1 -1
  224. package/library/skills/multiplayer/SKILL.md +1 -1
  225. package/library/skills/multiplayer/resource.yaml +1 -1
  226. package/library/skills/multiplayer-movement/SKILL.md +1 -1
  227. package/library/skills/multiplayer-movement/resource.yaml +1 -1
  228. package/library/skills/multiplayer-project/SKILL.md +1 -1
  229. package/library/skills/multiplayer-project/resource.yaml +1 -1
  230. package/library/skills/multiplayer-publish/SKILL.md +8 -7
  231. package/library/skills/multiplayer-publish/resource.yaml +3 -3
  232. package/library/skills/multiplayer-state/SKILL.md +1 -1
  233. package/library/skills/multiplayer-state/resource.yaml +1 -1
  234. package/library/skills/multiplayer-testing/SKILL.md +1 -1
  235. package/library/skills/multiplayer-testing/resource.yaml +1 -1
  236. package/library/skills/music-track/SKILL.md +22 -13
  237. package/library/skills/music-track/resource.yaml +1 -1
  238. package/library/skills/navigate-summer/SKILL.md +11 -9
  239. package/library/skills/navigate-summer/resource.yaml +1 -1
  240. package/library/skills/new-project/SKILL.md +1 -1
  241. package/library/skills/new-project/resource.yaml +1 -1
  242. package/library/skills/organic-model/SKILL.md +24 -18
  243. package/library/skills/organic-model/resource.yaml +1 -1
  244. package/library/skills/pixel-art/SKILL.md +27 -23
  245. package/library/skills/pixel-art/resource.yaml +1 -1
  246. package/library/skills/play/SKILL.md +1 -1
  247. package/library/skills/play/resource.yaml +1 -1
  248. package/library/skills/playtesting-a-feature/SKILL.md +1 -1
  249. package/library/skills/playtesting-a-feature/resource.yaml +1 -1
  250. package/library/skills/procedural-animation/SKILL.md +20 -16
  251. package/library/skills/procedural-animation/resource.yaml +1 -1
  252. package/library/skills/prop-model/SKILL.md +25 -19
  253. package/library/skills/prop-model/resource.yaml +1 -1
  254. package/library/skills/psx-retro-rendering/resource.yaml +1 -0
  255. package/library/skills/publish-your-game/SKILL.md +16 -6
  256. package/library/skills/publish-your-game/resource.yaml +3 -3
  257. package/library/skills/realtime-wet-surfaces/resource.yaml +1 -0
  258. package/library/skills/release-readiness/SKILL.md +1 -1
  259. package/library/skills/release-readiness/resource.yaml +1 -1
  260. package/library/skills/remote-deploy/SKILL.md +1 -1
  261. package/library/skills/remote-deploy/resource.yaml +1 -1
  262. package/library/skills/retarget/SKILL.md +23 -20
  263. package/library/skills/retarget/resource.yaml +1 -1
  264. package/library/skills/running-in-the-cloud/SKILL.md +1 -1
  265. package/library/skills/running-in-the-cloud/resource.yaml +1 -1
  266. package/library/skills/save-load/SKILL.md +1 -1
  267. package/library/skills/save-load/resource.yaml +1 -1
  268. package/library/skills/scene-composition/SKILL.md +1 -1
  269. package/library/skills/scene-composition/resource.yaml +1 -1
  270. package/library/skills/scene-hierarchy-design/SKILL.md +2 -2
  271. package/library/skills/scene-hierarchy-design/resource.yaml +1 -1
  272. package/library/skills/scene-scripting/SKILL.md +66 -636
  273. package/library/skills/scene-scripting/references/ctx-api.md +184 -0
  274. package/library/skills/scene-scripting/references/recipes-2d-ui.md +193 -0
  275. package/library/skills/scene-scripting/references/recipes-3d.md +280 -0
  276. package/library/skills/scene-scripting/resource.yaml +4 -4
  277. package/library/skills/scene-to-level/SKILL.md +2 -2
  278. package/library/skills/scene-to-level/resource.yaml +1 -1
  279. package/library/skills/skill-create/resource.yaml +1 -0
  280. package/library/skills/skill-improve/resource.yaml +1 -0
  281. package/library/skills/skill-test/SKILL.md +2 -2
  282. package/library/skills/skill-test/resource.yaml +1 -0
  283. package/library/skills/skintokens-auto-rigging/resource.yaml +1 -0
  284. package/library/skills/skybox-panorama/SKILL.md +27 -21
  285. package/library/skills/skybox-panorama/resource.yaml +1 -1
  286. package/library/skills/sound-effect/SKILL.md +29 -20
  287. package/library/skills/sound-effect/resource.yaml +1 -1
  288. package/library/skills/spatial-placement/SKILL.md +14 -9
  289. package/library/skills/spatial-placement/resource.yaml +1 -1
  290. package/library/skills/sprite-sheet/SKILL.md +32 -27
  291. package/library/skills/sprite-sheet/resource.yaml +1 -1
  292. package/library/skills/store-art/SKILL.md +3 -3
  293. package/library/skills/store-art/resource.yaml +2 -2
  294. package/library/skills/store-listing/SKILL.md +3 -3
  295. package/library/skills/store-listing/resource.yaml +2 -2
  296. package/library/skills/summer-analytics/SKILL.md +7 -5
  297. package/library/skills/summer-analytics/resource.yaml +2 -2
  298. package/library/skills/summer-apps/SKILL.md +48 -32
  299. package/library/skills/summer-apps/manifest.md +1 -1
  300. package/library/skills/summer-apps/minimal-app.md +7 -7
  301. package/library/skills/summer-apps/resource.yaml +1 -1
  302. package/library/skills/summer-apps/sdk-reference.md +5 -5
  303. package/library/skills/summer-apps-design/SKILL.md +1 -1
  304. package/library/skills/summer-apps-design/resource.yaml +1 -1
  305. package/library/skills/summer-assets/SKILL.md +56 -0
  306. package/library/skills/summer-assets/resource.yaml +34 -0
  307. package/library/skills/summer-store/SKILL.md +1 -1
  308. package/library/skills/text-to-motion/SKILL.md +30 -23
  309. package/library/skills/text-to-motion/prompts-and-controls.md +5 -5
  310. package/library/skills/text-to-motion/resource.yaml +1 -1
  311. package/library/skills/text-to-motion/rigging-for-text-motion.md +2 -2
  312. package/library/skills/tileable-texture/SKILL.md +19 -15
  313. package/library/skills/tileable-texture/resource.yaml +1 -1
  314. package/library/skills/trailer-shot/SKILL.md +28 -24
  315. package/library/skills/trailer-shot/resource.yaml +1 -1
  316. package/library/skills/tune-performance/SKILL.md +6 -6
  317. package/library/skills/tune-performance/resource.yaml +1 -1
  318. package/library/skills/ui-basics/SKILL.md +41 -36
  319. package/library/skills/ui-basics/resource.yaml +1 -1
  320. package/library/skills/ui-graphics/SKILL.md +47 -38
  321. package/library/skills/ui-graphics/resource.yaml +1 -1
  322. package/library/skills/use-widget-asset/SKILL.md +1 -1
  323. package/library/skills/use-widget-asset/resource.yaml +1 -1
  324. package/library/skills/using-summer/SKILL.md +6 -5
  325. package/library/skills/using-summer/resource.yaml +1 -1
  326. package/library/skills/vehicle-model/SKILL.md +65 -57
  327. package/library/skills/vehicle-model/resource.yaml +1 -1
  328. package/library/skills/verification-before-completion/SKILL.md +1 -1
  329. package/library/skills/verification-before-completion/resource.yaml +1 -1
  330. package/library/skills/verifying-scenes/SKILL.md +2 -2
  331. package/library/skills/verifying-scenes/resource.yaml +1 -1
  332. package/library/skills/vfx-dissolve/SKILL.md +2 -2
  333. package/library/skills/vfx-dissolve/resource.yaml +1 -1
  334. package/library/skills/vfx-fire/SKILL.md +15 -41
  335. package/library/skills/vfx-fire/resource.yaml +1 -1
  336. package/library/skills/vfx-hit-spark/SKILL.md +1 -1
  337. package/library/skills/vfx-hit-spark/resource.yaml +1 -1
  338. package/library/skills/vfx-lightning/SKILL.md +7 -16
  339. package/library/skills/vfx-lightning/resource.yaml +1 -1
  340. package/library/skills/vfx-magic-glow/SKILL.md +23 -32
  341. package/library/skills/vfx-magic-glow/resource.yaml +1 -1
  342. package/library/skills/vfx-muzzle-flash/SKILL.md +20 -35
  343. package/library/skills/vfx-muzzle-flash/resource.yaml +1 -1
  344. package/library/skills/vfx-smoke/SKILL.md +13 -31
  345. package/library/skills/vfx-smoke/resource.yaml +1 -1
  346. package/library/skills/vfx-water-ripple/SKILL.md +12 -31
  347. package/library/skills/vfx-water-ripple/resource.yaml +1 -1
  348. package/library/skills/voice-line/SKILL.md +71 -40
  349. package/library/skills/voice-line/resource.yaml +1 -1
  350. package/library/skills/web-and-touch-input/SKILL.md +1 -1
  351. package/library/skills/web-and-touch-input/resource.yaml +1 -1
  352. package/library/skills/web-compatibility-look/SKILL.md +1 -1
  353. package/library/skills/web-compatibility-look/resource.yaml +1 -1
  354. package/library/skills/world-building-3d/SKILL.md +1 -1
  355. package/library/skills/world-building-3d/resource.yaml +1 -1
  356. package/library/skills/writing-skills/resource.yaml +1 -0
  357. package/library/tools/add-node/GUIDE.md +14 -0
  358. package/library/tools/align-distribute-3d/GUIDE.md +7 -0
  359. package/library/tools/app-call/resource.yaml +1 -1
  360. package/library/tools/app-guide/resource.yaml +2 -2
  361. package/library/tools/app-page/resource.yaml +1 -1
  362. package/library/tools/app-screenshot/resource.yaml +19 -1
  363. package/library/tools/app-tools/resource.yaml +1 -1
  364. package/library/tools/attach-to-surface/GUIDE.md +15 -0
  365. package/library/tools/batch/GUIDE.md +27 -0
  366. package/library/tools/camera-bookmark/GUIDE.md +12 -0
  367. package/library/tools/capture-gameplay/GUIDE.md +3 -0
  368. package/library/tools/capture-gameplay/resource.yaml +3 -3
  369. package/library/tools/check-job/resource.yaml +1 -1
  370. package/library/tools/clear-console/GUIDE.md +3 -0
  371. package/library/tools/connect-ports/GUIDE.md +9 -0
  372. package/library/tools/connect-signal/GUIDE.md +14 -0
  373. package/library/tools/create-debug-report/GUIDE.md +10 -0
  374. package/library/tools/create-scene/GUIDE.md +10 -0
  375. package/library/tools/debug-views/GUIDE.md +7 -0
  376. package/library/tools/enable-plugin/GUIDE.md +3 -0
  377. package/library/tools/export-game/GUIDE.md +3 -0
  378. package/library/tools/export-game/resource.yaml +3 -3
  379. package/library/tools/export-templates/GUIDE.md +3 -0
  380. package/library/tools/fabricate-3d/GUIDE.md +19 -0
  381. package/library/tools/frame-nodes/GUIDE.md +9 -0
  382. package/library/tools/frame-shot/GUIDE.md +9 -0
  383. package/library/tools/game-control/GUIDE.md +9 -0
  384. package/library/tools/game-input/GUIDE.md +9 -0
  385. package/library/tools/game-probe/GUIDE.md +9 -0
  386. package/library/tools/generate-3d/resource.yaml +3 -3
  387. package/library/tools/generate-motion/resource.yaml +2 -2
  388. package/library/tools/get-console/GUIDE.md +9 -0
  389. package/library/tools/get-console/resource.yaml +5 -0
  390. package/library/tools/get-debugger-errors/GUIDE.md +7 -0
  391. package/library/tools/get-debugger-errors/resource.yaml +5 -0
  392. package/library/tools/get-debugger-warnings/GUIDE.md +7 -0
  393. package/library/tools/get-debugger-warnings/resource.yaml +5 -0
  394. package/library/tools/get-diagnostics/GUIDE.md +13 -0
  395. package/library/tools/get-project-context/GUIDE.md +25 -0
  396. package/library/tools/get-runtime-tree/GUIDE.md +7 -0
  397. package/library/tools/get-runtime-tree/resource.yaml +5 -0
  398. package/library/tools/get-scene-tree/GUIDE.md +11 -0
  399. package/library/tools/get-scene-tree/resource.yaml +5 -0
  400. package/library/tools/get-script-errors/GUIDE.md +5 -0
  401. package/library/tools/grep/GUIDE.md +11 -0
  402. package/library/tools/import-asset/GUIDE.md +8 -0
  403. package/library/tools/import-asset-by-id/GUIDE.md +12 -0
  404. package/library/tools/import-from-url/GUIDE.md +10 -0
  405. package/library/tools/import-from-url-batch/GUIDE.md +3 -0
  406. package/library/tools/import-hdri/GUIDE.md +16 -0
  407. package/library/tools/input-map-bind/GUIDE.md +11 -0
  408. package/library/tools/inspect-asset/GUIDE.md +14 -0
  409. package/library/tools/inspect-asset/resource.yaml +5 -0
  410. package/library/tools/inspect-node/GUIDE.md +11 -0
  411. package/library/tools/inspect-node/resource.yaml +5 -0
  412. package/library/tools/inspect-resource/GUIDE.md +7 -0
  413. package/library/tools/inspect-resource/resource.yaml +5 -0
  414. package/library/tools/inspect-runtime-node/GUIDE.md +7 -0
  415. package/library/tools/inspect-runtime-node/resource.yaml +5 -0
  416. package/library/tools/instantiate-scene/GUIDE.md +12 -0
  417. package/library/tools/is-running/GUIDE.md +3 -0
  418. package/library/tools/measure/GUIDE.md +8 -0
  419. package/library/tools/navigation-probe/GUIDE.md +9 -0
  420. package/library/tools/open/resource.yaml +2 -2
  421. package/library/tools/open-main-scene/GUIDE.md +6 -0
  422. package/library/tools/open-scene/GUIDE.md +8 -0
  423. package/library/tools/place-adjacent/GUIDE.md +7 -0
  424. package/library/tools/play/GUIDE.md +13 -0
  425. package/library/tools/project-setting/GUIDE.md +9 -0
  426. package/library/tools/publish-build/resource.yaml +6 -6
  427. package/library/tools/raycast/GUIDE.md +7 -0
  428. package/library/tools/read-file/GUIDE.md +10 -0
  429. package/library/tools/read-library/resource.yaml +5 -0
  430. package/library/tools/recent-events/GUIDE.md +7 -0
  431. package/library/tools/remove-node/GUIDE.md +3 -0
  432. package/library/tools/repeat-along/GUIDE.md +5 -0
  433. package/library/tools/replace-node/GUIDE.md +9 -0
  434. package/library/tools/replace-text/GUIDE.md +5 -0
  435. package/library/tools/run-editor-script/GUIDE.md +16 -0
  436. package/library/tools/run-script/GUIDE.md +30 -0
  437. package/library/tools/run-script/resource.yaml +6 -3
  438. package/library/tools/runtime-animate/GUIDE.md +7 -0
  439. package/library/tools/runtime-call/GUIDE.md +7 -0
  440. package/library/tools/runtime-set/GUIDE.md +9 -0
  441. package/library/tools/runtime-spawn/GUIDE.md +9 -0
  442. package/library/tools/save-scene/GUIDE.md +3 -0
  443. package/library/tools/scene-audit/GUIDE.md +29 -0
  444. package/library/tools/screenshot/GUIDE.md +17 -0
  445. package/library/tools/select-node/GUIDE.md +3 -0
  446. package/library/tools/set-prop/GUIDE.md +23 -0
  447. package/library/tools/set-resource-property/GUIDE.md +8 -0
  448. package/library/tools/shot-sheet/GUIDE.md +7 -0
  449. package/library/tools/snap-to-surface/GUIDE.md +17 -0
  450. package/library/tools/snapshot-diff/GUIDE.md +7 -0
  451. package/library/tools/starcast/GUIDE.md +12 -0
  452. package/library/tools/stop/GUIDE.md +3 -0
  453. package/library/tools/test-placement/GUIDE.md +7 -0
  454. package/library/tools/ui-actions/GUIDE.md +12 -0
  455. package/library/tools/ui-activate/GUIDE.md +11 -0
  456. package/library/tools/ui-screenshot/GUIDE.md +9 -0
  457. package/library/tools/ui-tree/GUIDE.md +10 -0
  458. package/library/tools/wait-for-event/GUIDE.md +11 -0
  459. package/library/tools/world-snapshot/GUIDE.md +9 -0
  460. package/library/tools/write-file/GUIDE.md +5 -0
  461. package/library/tools/zoom/GUIDE.md +5 -0
  462. package/package.json +6 -4
  463. package/registry/generated/counts.json +2 -2
  464. package/registry/generated/gemini-extension.json +4 -12
  465. package/registry/generated/index.json +433 -339
  466. package/registry/generated/marketplace.claude.json +2 -13
  467. package/registry/generated/plugin.claude.json +23 -22
  468. package/registry/generated/plugin.codex.json +4 -12
  469. package/registry/generated/plugin.cursor.json +4 -12
  470. package/registry/generated/plugin.factory.json +4 -12
  471. package/registry/generated/server.json +34 -0
  472. package/registry/generated/skills-index.md +119 -117
  473. package/registry/generated/skills-registry.json +153 -115
  474. package/registry/operations/fixtures/invalid-deprecated-without-replacement.json +60 -0
  475. package/registry/operations/fixtures/invalid-name.json +60 -0
  476. package/registry/operations/fixtures/invalid-publish-without-owner.json +82 -0
  477. package/registry/operations/fixtures/invalid-spend-without-estimate.json +42 -0
  478. package/registry/operations/fixtures/invalid-unknown-field.json +61 -0
  479. package/registry/operations/fixtures/valid-player-facing.json +82 -0
  480. package/registry/operations/fixtures/valid-read.json +60 -0
  481. package/registry/operations/fixtures/valid-spend.json +43 -0
  482. package/registry/operations/legacy-names.json +1206 -0
  483. package/registry/schemas/operation.schema.json +318 -0
  484. package/registry/schemas/skill.schema.json +4 -0
  485. package/CLAUDE.md +0 -7
@@ -0,0 +1,47 @@
1
+ import { Command } from "commander";
2
+ import { type HostedCall } from "../../core/ops/cloud.js";
3
+ import { type Answer } from "../../core/ops/contract.js";
4
+ import { FileSaver } from "../../core/ops/save-files.js";
5
+ import { dispatchTool } from "../../core/capabilities/tool-dispatch.js";
6
+ /**
7
+ * The CLI view of the operation catalog (on by default; SUMMER_SURFACE=v3 leaves it out):
8
+ *
9
+ * summer <area> <action> [--<field> <value> ...] [--input '<json>'] [--dry-run] [--idempotency-key <k>] [--wait] [--json]
10
+ * summer whoami
11
+ * summer ops search <words...> | summer ops describe <op>
12
+ *
13
+ * Engine and local operations run in this process (the same functions
14
+ * `summer tool` runs); cloud operations run on the hosted Summer server
15
+ * through its summer_call, with the person's sign-in.
16
+ */
17
+ /** Areas with operations today; CLI command words stay out of this list. */
18
+ export declare const CLI_AREAS: readonly ["team", "profile", "docs", "assets", "makers", "jobs", "projects", "plans", "games", "store", "jams", "pricing", "analytics", "experiments", "marketing", "players", "economy", "inbox", "apps", "studio", "chats", "stories", "plugins", "engine", "account"];
19
+ type JsonSchema = {
20
+ type?: string | string[];
21
+ properties?: Record<string, JsonSchema>;
22
+ items?: JsonSchema;
23
+ };
24
+ export interface ParsedCall {
25
+ input: Record<string, unknown>;
26
+ json: boolean;
27
+ dryRun: boolean;
28
+ wait: boolean;
29
+ idempotencyKey?: string;
30
+ }
31
+ /** `--max-items 3 --tag a --tag b --no-loop` -> `{ maxItems: 3, tag: ["a", "b"], loop: false }`, typed by the schema. */
32
+ export declare function parseCallFlags(argv: readonly string[], schema: JsonSchema | null): ParsedCall;
33
+ export interface OpsCliDeps {
34
+ hosted: HostedCall;
35
+ dispatch: typeof dispatchTool;
36
+ print: (text: string) => void;
37
+ printError: (text: string) => void;
38
+ /** Saves generated files (`--out`, else the project's asset folder). Default: a new FileSaver per run. */
39
+ files?: FileSaver;
40
+ }
41
+ export declare const defaultOpsCliDeps: OpsCliDeps;
42
+ /** The answer for a person; `out` is the --out to keep in the printed wait command. */
43
+ export declare function formatAnswer(answer: Answer, out?: string): string;
44
+ /** Run one operation from the command line and print its answer; returns the exit code. */
45
+ export declare function runOpFromCli(op: string, argv: readonly string[], deps?: OpsCliDeps): Promise<number>;
46
+ export declare function opsCliCommands(): Command[];
47
+ export {};
@@ -0,0 +1,301 @@
1
+ import { Command } from "commander";
2
+ import { localEntries, localInputSchema, localWireForm, missingInput } from "../../core/ops/catalog.js";
3
+ import { answerOfHosted, callHostedV4, hostedCallFailure, searchEverywhere } from "../../core/ops/cloud.js";
4
+ import { errorAnswer, isLocalOp, localToolsFor, opFromCli, OP_NAME } from "../../core/ops/contract.js";
5
+ import { ENGINE_SPLIT_OPS, engineOpDef, splitToolArgs } from "../../core/ops/engine.js";
6
+ import { engineFailure, engineNotRunning } from "../../core/ops/engine-answer.js";
7
+ import { loadLibraryIndex } from "../../core/library-search.js";
8
+ import { FileSaver, withOutField } from "../../core/ops/save-files.js";
9
+ import { dispatchTool, EngineUnavailableError, ToolResultError } from "../../core/capabilities/tool-dispatch.js";
10
+ /**
11
+ * The CLI view of the operation catalog (on by default; SUMMER_SURFACE=v3 leaves it out):
12
+ *
13
+ * summer <area> <action> [--<field> <value> ...] [--input '<json>'] [--dry-run] [--idempotency-key <k>] [--wait] [--json]
14
+ * summer whoami
15
+ * summer ops search <words...> | summer ops describe <op>
16
+ *
17
+ * Engine and local operations run in this process (the same functions
18
+ * `summer tool` runs); cloud operations run on the hosted Summer server
19
+ * through its summer_call, with the person's sign-in.
20
+ */
21
+ /** Areas with operations today; CLI command words stay out of this list. */
22
+ export const CLI_AREAS = [
23
+ "team", "profile", "docs", "assets", "makers", "jobs", "projects", "plans", "games", "store", "jams", "pricing",
24
+ "analytics", "experiments", "marketing", "players", "economy", "inbox", "apps", "studio", "chats", "stories",
25
+ "plugins", "engine", "account",
26
+ ];
27
+ const RESERVED_FLAGS = new Set(["json", "dry-run", "wait", "idempotency-key", "input"]);
28
+ const camel = (flag) => flag.replace(/-([a-z0-9])/g, (_match, letter) => letter.toUpperCase());
29
+ /** A flag's field: camelCase (`--scene-path` is scenePath), or snake_case when the schema names it so (`--look-at` is look_at). */
30
+ function fieldName(flag, schema) {
31
+ const snake = flag.replace(/-/g, "_");
32
+ return snake !== flag && schema?.properties?.[snake] && !schema.properties[camel(flag)] ? snake : camel(flag);
33
+ }
34
+ function coerce(value, schema) {
35
+ const type = Array.isArray(schema?.type) ? schema?.type[0] : schema?.type;
36
+ if (value === true)
37
+ return true;
38
+ if (type === "number" || type === "integer")
39
+ return Number(value);
40
+ if (type === "boolean")
41
+ return value === "true";
42
+ if (type === "string")
43
+ return value;
44
+ if (type === "object" || type === "array") {
45
+ try {
46
+ return JSON.parse(value);
47
+ }
48
+ catch {
49
+ return type === "array" ? value.split(",") : value;
50
+ }
51
+ }
52
+ return /^(-?\d+(\.\d+)?|true|false)$/.test(value) ? JSON.parse(value) : value;
53
+ }
54
+ /** `--max-items 3 --tag a --tag b --no-loop` -> `{ maxItems: 3, tag: ["a", "b"], loop: false }`, typed by the schema. */
55
+ export function parseCallFlags(argv, schema) {
56
+ const out = { input: {}, json: false, dryRun: false, wait: false };
57
+ const fields = {};
58
+ for (let index = 0; index < argv.length; index++) {
59
+ const token = argv[index];
60
+ if (!token.startsWith("--"))
61
+ throw new Error(`Unexpected argument "${token}". Pass fields as --name value.`);
62
+ const [rawName, inline] = token.slice(2).split(/=(.*)/s, 2);
63
+ if (rawName === "json")
64
+ out.json = true;
65
+ else if (rawName === "dry-run")
66
+ out.dryRun = true;
67
+ else if (rawName === "wait")
68
+ out.wait = true;
69
+ else if (rawName === "idempotency-key" || rawName === "input") {
70
+ const value = inline ?? argv[++index];
71
+ if (value === undefined)
72
+ throw new Error(`--${rawName} needs a value.`);
73
+ if (rawName === "input") {
74
+ const parsed = JSON.parse(value);
75
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
76
+ throw new Error("--input must be a JSON object.");
77
+ Object.assign(out.input, parsed);
78
+ }
79
+ else
80
+ out.idempotencyKey = value;
81
+ }
82
+ else if (rawName.startsWith("no-") && !RESERVED_FLAGS.has(rawName)) {
83
+ fields[fieldName(rawName.slice(3), schema)] = false;
84
+ }
85
+ else {
86
+ const name = fieldName(rawName, schema);
87
+ const next = argv[index + 1];
88
+ const value = inline ?? (next !== undefined && !next.startsWith("--") ? (index++, next) : true);
89
+ const property = schema?.properties?.[name];
90
+ const typed = property?.type === "array" ? coerce(value, property.items) : coerce(value, property);
91
+ if (property?.type === "array")
92
+ fields[name] = [...(fields[name] ?? []), ...(Array.isArray(typed) ? typed : [typed])];
93
+ else
94
+ fields[name] = name in fields ? [...[fields[name]].flat(), typed] : typed;
95
+ }
96
+ }
97
+ out.input = { ...out.input, ...fields };
98
+ return out;
99
+ }
100
+ export const defaultOpsCliDeps = {
101
+ hosted: (name, args) => callHostedV4(name, args),
102
+ dispatch: dispatchTool,
103
+ print: (text) => process.stdout.write(`${text}\n`),
104
+ printError: (text) => process.stderr.write(`${text}\n`),
105
+ };
106
+ /** The docs.read id of a local tool's guide (tool/<slug>). */
107
+ function guideOf(toolName) {
108
+ const entry = loadLibraryIndex().find((candidate) => candidate.kind === "tool" && candidate.mcp_tool_name === toolName);
109
+ return entry?.id;
110
+ }
111
+ async function runLocal(op, call, deps) {
112
+ // A split operation runs its 3.x tool with the action fixed (core/ops/engine.ts).
113
+ const split = ENGINE_SPLIT_OPS[op];
114
+ const entry = localEntries().find((candidate) => candidate.name === op);
115
+ const tool = split?.tool ?? entry?.mcpTool ?? localToolsFor(op)[0];
116
+ if (!tool)
117
+ return errorAnswer("not_found", `No operation is named "${op}".`, { next: { op: "ops.search", input: { query: op } } });
118
+ const args = split ? splitToolArgs(split, call.input) : call.input;
119
+ const def = engineOpDef(op);
120
+ const guide = guideOf(tool);
121
+ const describe = guide && def ? { op: "docs.read", input: { id: guide } } : { op: "ops.describe", input: { name: op } };
122
+ const missing = missingInput(localInputSchema(op), call.input);
123
+ if (missing)
124
+ return errorAnswer("invalid_input", missing, { next: describe });
125
+ if (call.dryRun) {
126
+ return { ok: true, status: "dry_run", preview: { summary: `${entry?.title ?? op}: the input is valid. Nothing was done.`, changes: [], approval: entry?.approval ?? "none", estimate: null, valid: true } };
127
+ }
128
+ try {
129
+ return { ok: true, status: "done", result: await deps.dispatch(tool, args) };
130
+ }
131
+ catch (error) {
132
+ if (error instanceof EngineUnavailableError)
133
+ return engineNotRunning();
134
+ if (error instanceof ToolResultError) {
135
+ return def ? engineFailure(JSON.stringify(error.result), op, { effect: def.effect, guide }) : errorAnswer("invalid_input", error.message, { details: { tool: error.result } });
136
+ }
137
+ return errorAnswer("invalid_input", error instanceof Error ? error.message : String(error), { next: describe });
138
+ }
139
+ }
140
+ async function runCloud(op, call, deps) {
141
+ try {
142
+ return answerOfHosted(await deps.hosted("summer_call", { op, input: call.input, ...(call.dryRun ? { dryRun: true } : {}), ...(call.idempotencyKey ? { idempotencyKey: call.idempotencyKey } : {}) }));
143
+ }
144
+ catch (error) {
145
+ return hostedCallFailure(error, { op, dryRun: call.dryRun, idempotencyKey: call.idempotencyKey });
146
+ }
147
+ }
148
+ /** The input schema used to type flags: the local descriptor, or the hosted ops.describe. */
149
+ async function schemaFor(op, deps) {
150
+ if (isLocalOp(op))
151
+ return localInputSchema(op);
152
+ const answer = await runCloud("ops.describe", { input: { name: op }, json: true, dryRun: false, wait: false }, deps);
153
+ const input = answer.ok && answer.status === "done" ? answer.result.operation?.input : undefined;
154
+ return input ? withOutField(op, input) : null;
155
+ }
156
+ /** Failed waits the job itself does not cause: the call to Summer did not get through. */
157
+ const WAIT_DID_NOT_GET_THROUGH = new Set(["unavailable", "outcome_unknown", "not_signed_in", "forbidden", "rate_limited"]);
158
+ /** Follow a running job or an approval until it ends (jobs.wait, at most 50 s per call). */
159
+ async function waitFor(answer, deps) {
160
+ let current = answer;
161
+ if (current.ok && current.status === "needs_approval")
162
+ deps.printError(`Waiting for approval: ${current.approval.url}`);
163
+ for (let round = 0; round < 120 && current.ok && (current.status === "running" || current.status === "needs_approval"); round++) {
164
+ const job = current.job.id;
165
+ const waited = await runCloud("jobs.wait", { input: { jobId: job, timeoutSeconds: 50 }, json: true, dryRun: false, wait: false }, deps);
166
+ // The job runs on whatever the wait answered: a failed wait names it, so the job is waited on, not started again.
167
+ // One that did not get through says to wait again; any other keeps its own next step (sign in, slow down).
168
+ if (!waited.ok && WAIT_DID_NOT_GET_THROUGH.has(waited.error.code)) {
169
+ const { code, message, retry, next, details } = waited.error;
170
+ return errorAnswer(code, `${message} Job ${job} is still on Summer's server.`, {
171
+ retry,
172
+ next: code === "unavailable" ? { op: "jobs.wait", input: { jobId: job } } : next,
173
+ details: { ...details, job },
174
+ });
175
+ }
176
+ if (!waited.ok || waited.status !== "done")
177
+ return waited;
178
+ const result = waited.result;
179
+ if (!result.finished)
180
+ continue;
181
+ // An approved generation runs on as its own job: follow that job.
182
+ const chained = result.job.result;
183
+ if (result.job.state === "done" && chained?.status === "running" && chained.job?.id) {
184
+ current = { ok: true, status: "running", job: chained.job };
185
+ continue;
186
+ }
187
+ if (result.job.state === "done")
188
+ return { ok: true, status: "done", result: result.job.result ?? {} };
189
+ return errorAnswer(result.job.state === "failed" ? "invalid_input" : "conflict", result.job.error?.message ?? `The job ended: ${result.job.state}.`, { details: { job } });
190
+ }
191
+ return current;
192
+ }
193
+ /** A value as one shell word: single quotes, so the shell expands nothing in it. */
194
+ const shellWord = (value) => (/^[\w./:@+=-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`);
195
+ /** The answer for a person; `out` is the --out to keep in the printed wait command. */
196
+ export function formatAnswer(answer, out) {
197
+ const waitFlags = (id) => `summer jobs wait --job-id ${id}${out ? ` --out ${shellWord(out)}` : ""}`;
198
+ if (!answer.ok) {
199
+ const next = answer.error.next;
200
+ const step = !next ? "" : "op" in next ? `\nNext: ${next.op}` : "url" in next ? `\nNext: ${next.label}: ${next.url}` : `\nNext: ${next.say}`;
201
+ return `Error (${answer.error.code}): ${answer.error.message}${step}`;
202
+ }
203
+ switch (answer.status) {
204
+ case "done":
205
+ return JSON.stringify(answer.result, null, 2);
206
+ case "running":
207
+ return `Started: job ${answer.job.id}. Wait for it: ${waitFlags(answer.job.id)}`;
208
+ case "needs_approval":
209
+ return `Needs approval (${answer.approval.who}): ${answer.approval.summary}\n${answer.approval.url}\nNothing changes until they approve. Follow it: ${waitFlags(answer.job.id)}`;
210
+ case "dry_run":
211
+ return `Dry run: ${String(answer.preview.summary ?? "")}\n${JSON.stringify(answer.preview, null, 2)}`;
212
+ }
213
+ }
214
+ /** Run one operation from the command line and print its answer; returns the exit code. */
215
+ export async function runOpFromCli(op, argv, deps = defaultOpsCliDeps) {
216
+ if (!OP_NAME.test(op)) {
217
+ deps.printError(formatAnswer(errorAnswer("invalid_input", `"${op}" is not an operation name (area action).`, { next: { op: "ops.search" } })));
218
+ return 1;
219
+ }
220
+ let call;
221
+ try {
222
+ const hasFields = argv.some((token) => token.startsWith("--") && !RESERVED_FLAGS.has(token.slice(2).split("=")[0]));
223
+ call = parseCallFlags(argv, hasFields ? await schemaFor(op, deps) : null);
224
+ }
225
+ catch (error) {
226
+ deps.printError(formatAnswer(errorAnswer("invalid_input", error instanceof Error ? error.message : String(error))));
227
+ return 1;
228
+ }
229
+ let answer;
230
+ let out;
231
+ if (isLocalOp(op)) {
232
+ answer = await runLocal(op, call, deps);
233
+ if (call.wait)
234
+ answer = await waitFor(answer, deps);
235
+ }
236
+ else {
237
+ // --out stays here: the files save on this machine once the answer (or the waited job) names them.
238
+ const files = deps.files ?? new FileSaver({ saveByDefault: true });
239
+ const taken = files.take(op, call.input);
240
+ out = taken.out;
241
+ answer = await runCloud(op, { ...call, input: taken.input }, deps);
242
+ if (call.wait)
243
+ answer = await waitFor(answer, deps);
244
+ answer = await files.finish(op, answer, out);
245
+ }
246
+ (answer.ok ? deps.print : deps.printError)(call.json ? JSON.stringify(answer) : formatAnswer(answer, out));
247
+ if (!call.json && answer.ok)
248
+ for (const warning of answer.warnings ?? [])
249
+ deps.printError(`Warning: ${warning}`);
250
+ return answer.ok ? 0 : 1;
251
+ }
252
+ function areaCommand(area) {
253
+ return new Command(area)
254
+ .description(`Summer ${area} operations: summer ${area} <action> --field value. Find them: summer ops search ${area}`)
255
+ .argument("<action>", "The operation's action, e.g. list or set-base")
256
+ .allowUnknownOption(true)
257
+ .allowExcessArguments(true)
258
+ .helpOption(false)
259
+ .action(async (action, _options, command) => {
260
+ process.exitCode = await runOpFromCli(opFromCli(area, action), command.args.slice(1));
261
+ });
262
+ }
263
+ export function opsCliCommands() {
264
+ const whoami = new Command("whoami")
265
+ .description("Who is signed in, and their credits")
266
+ .allowUnknownOption(true)
267
+ .allowExcessArguments(true)
268
+ .action(async (_options, command) => {
269
+ process.exitCode = await runOpFromCli("whoami", command.args);
270
+ });
271
+ const ops = new Command("ops").description("Find and describe Summer operations");
272
+ ops
273
+ .command("search <words...>")
274
+ .description("Find operations by describing the job in plain words")
275
+ .option("--area <area>", "Only this area")
276
+ .option("--limit <n>", "Most results", "8")
277
+ .option("--json", "Print the answer as JSON")
278
+ .action(async (wordsArg, options) => {
279
+ const { items, warning } = await searchEverywhere(wordsArg.join(" "), { area: options.area, limit: Number(options.limit) || 8 }, defaultOpsCliDeps.hosted);
280
+ if (options.json) {
281
+ defaultOpsCliDeps.print(JSON.stringify({ ok: true, status: "done", result: { items }, ...(warning ? { warnings: [warning] } : {}) }));
282
+ return;
283
+ }
284
+ for (const item of items)
285
+ defaultOpsCliDeps.print(`${item.name.padEnd(32)} ${item.effect.padEnd(13)} ${item.title}`);
286
+ if (warning)
287
+ defaultOpsCliDeps.printError(warning);
288
+ });
289
+ ops
290
+ .command("describe <op>")
291
+ .description("Show one operation with its exact input")
292
+ .action(async (op) => {
293
+ const local = localWireForm(op);
294
+ if (local) {
295
+ defaultOpsCliDeps.print(JSON.stringify(local, null, 2));
296
+ return;
297
+ }
298
+ process.exitCode = await runOpFromCli("ops.describe", ["--name", op]);
299
+ });
300
+ return [whoami, ops, ...CLI_AREAS.map(areaCommand)];
301
+ }
@@ -1,2 +1,4 @@
1
1
  import { Command } from "commander";
2
2
  export declare const setupCommand: Command;
3
+ /** One line instead of a row per three skills: the first few names and how many more. `--json` keeps the full list. */
4
+ export declare function skillNamesSample(names: readonly string[], max?: number): string;
@@ -6,6 +6,12 @@ import { brandLine, c, sym, tildeify } from "../../core/format.js";
6
6
  import { TOOLKIT_VERSION as cliVersion } from "../../core/version.js";
7
7
  import { resolveDefaultChannel } from "../../installer/version-check.js";
8
8
  import { agentLabel } from "../../installer/agent-table.js";
9
+ import { PROFILES, parseProfile } from "../../core/tool-profiles.js";
10
+ const PROFILE_NOTES = {
11
+ full: "Every Summer tool.",
12
+ engine: "Engine, generation and store tools. Every tool: summer setup <agent> --profile full",
13
+ assets: "Generation and asset tools, no engine tools. Every tool: summer setup <agent> --profile full",
14
+ };
9
15
  export const setupCommand = new Command("setup")
10
16
  .description("Configure Summer Engine for an AI agent and run diagnostics. For agents that can sign in to it, it also adds Summer Games (summer-games).")
11
17
  .argument("[agent]", `Agent to configure: ${supportedAgents.join(", ")}`)
@@ -14,9 +20,11 @@ export const setupCommand = new Command("setup")
14
20
  .option("--dry-run", "Show planned changes without writing files")
15
21
  .option("--print", "Print the MCP config snippet instead of writing files")
16
22
  .option("--local-dev", "Point the agent at this checkout's built CLI (node <repo>/dist/bin/summer.js mcp) instead of npx summer-engine@latest — for testing unpublished builds. SUMMER_DEV=1 does the same.")
17
- .option("--channel <dist-tag>", "npm dist-tag the agent's MCP entry runs: npx -y summer-engine@<dist-tag> mcp (default latest; use next while a release soaks on the next tag). SUMMER_CHANNEL does the same.")
23
+ .option("--channel <dist-tag>", "npm dist-tag or exact version the agent's MCP entry runs: npx -y summer-engine@<dist-tag> mcp (default latest; a CLI newer than npm latest pins next when next is this version, else this version). SUMMER_CHANNEL does the same.")
18
24
  .option("--yes", "Apply practical setup steps without prompting")
19
25
  .option("--no-games", "Do not add the Summer Games MCP (summer-games: friends, parties and messages as you, signed in through summer.games)")
26
+ .option("--profile <profile>", "MCP tool profile: full (every tool, the default), engine (engine, generation and the store; under 128 tools; the default for VS Code Copilot), assets (generation and the asset library, no engine tools)")
27
+ .option("--assets-only", "Set up for making assets without Summer Engine: the assets profile, only the asset skills, and no Summer Games")
20
28
  .option("--json", "Print setup result as JSON")
21
29
  .option("--force", "Overwrite existing skill content (passes --force through to skills install)")
22
30
  .option("--recommended", "Install only the recommended skill subset instead of the whole library")
@@ -26,6 +34,7 @@ export const setupCommand = new Command("setup")
26
34
  .action(async (agentArg, opts) => {
27
35
  const agent = resolveAgentSelection(agentArg, opts.agent);
28
36
  const scope = resolveConfigScope(opts.scope);
37
+ const profile = resolveSetupProfile(opts);
29
38
  const defaultChannel = await resolveDefaultChannel(cliVersion);
30
39
  const config = await configureAgentMcp({
31
40
  agent,
@@ -34,8 +43,9 @@ export const setupCommand = new Command("setup")
34
43
  print: opts.print,
35
44
  localDev: Boolean(opts.localDev) || process.env.SUMMER_DEV === "1",
36
45
  channel: opts.channel ?? process.env.SUMMER_CHANNEL ?? defaultChannel.channel,
46
+ profile,
37
47
  });
38
- const games = opts.games === false || opts.print
48
+ const games = opts.games === false || opts.assetsOnly || opts.print
39
49
  ? null
40
50
  : await configureSummerGamesMcp({ agent, scope, dryRun: opts.dryRun });
41
51
  if (!opts.channel && !process.env.SUMMER_CHANNEL && defaultChannel.note && !opts.print) {
@@ -48,6 +58,7 @@ export const setupCommand = new Command("setup")
48
58
  scope,
49
59
  recommended: Boolean(opts.recommended),
50
60
  stableOnly: Boolean(opts.stableOnly),
61
+ assetsOnly: Boolean(opts.assetsOnly),
51
62
  });
52
63
  const doctor = await runDoctor({ quiet: true });
53
64
  if (opts.json) {
@@ -66,6 +77,19 @@ export const setupCommand = new Command("setup")
66
77
  process.exit(1);
67
78
  }
68
79
  });
80
+ /** --assets-only means the assets profile; --profile must name a profile and agree with it. */
81
+ function resolveSetupProfile(opts) {
82
+ const profile = opts.profile === undefined ? undefined : parseProfile(opts.profile);
83
+ if (profile === null) {
84
+ throw new Error(`Unknown --profile "${opts.profile}". Use one of: ${Object.keys(PROFILES).join(", ")}.`);
85
+ }
86
+ if (opts.assetsOnly) {
87
+ if (profile && profile !== "assets")
88
+ throw new Error("--assets-only uses the assets profile; leave out --profile.");
89
+ return "assets";
90
+ }
91
+ return profile;
92
+ }
69
93
  function printSetupResult(config, games, skills, doctor) {
70
94
  if (config.print) {
71
95
  console.log(config.snippet.trimEnd());
@@ -90,6 +114,9 @@ function printSetupResult(config, games, skills, doctor) {
90
114
  else if (config.channel !== "latest") {
91
115
  console.log(` ${c.dim(`(channel ${config.channel})`)} MCP server command: ${c.dim(`${config.server.command} ${config.server.args.join(" ")}`)}`);
92
116
  }
117
+ if (config.profile !== "full") {
118
+ console.log(` ${c.dim(`(profile ${config.profile})`)} ${c.dim(PROFILE_NOTES[config.profile])}`);
119
+ }
93
120
  if (games) {
94
121
  const name = c.bold("Summer Games");
95
122
  const url = c.dim(games.url);
@@ -114,15 +141,7 @@ function printSetupResult(config, games, skills, doctor) {
114
141
  ? c.dim(` (${skills.installed.added} new, ${skills.installed.updated} updated${note ? `; ${note}` : ""})`)
115
142
  : "";
116
143
  console.log(` ${sym.ok()} Installed ${c.bold(String(installed.length) + " skills")}${tally} ${where ? c.dim(tildeify(where)) : ""}`);
117
- const grouped = installed.reduce((rows, name, i) => {
118
- const row = Math.floor(i / 3);
119
- rows[row] = rows[row] ?? [];
120
- rows[row].push(name);
121
- return rows;
122
- }, []);
123
- for (const row of grouped) {
124
- console.log(` ${c.dim(row.join(" · "))}`);
125
- }
144
+ console.log(` ${c.dim(skillNamesSample(installed))}`);
126
145
  }
127
146
  else {
128
147
  console.log(` ${sym.ok()} ${skills.message}`);
@@ -147,9 +166,15 @@ function printSetupResult(config, games, skills, doctor) {
147
166
  printDoctorResult(doctor);
148
167
  if (doctor.ok && skills.status !== "failed" && !config.dryRun) {
149
168
  console.log("");
150
- console.log(`${c.dim("Try it:")} open ${label} and ask: ${c.bold("\"add a DirectionalLight3D and Camera3D to my scene\"")}`);
169
+ const ask = config.profile === "assets" ? "make a sword clash sound effect" : "add a DirectionalLight3D and Camera3D to my scene";
170
+ console.log(`${c.dim("Try it:")} open ${label} and ask: ${c.bold(`"${ask}"`)}`);
151
171
  }
152
172
  }
173
+ /** One line instead of a row per three skills: the first few names and how many more. `--json` keeps the full list. */
174
+ export function skillNamesSample(names, max = 8) {
175
+ const shown = names.slice(0, max).join(" · ");
176
+ return names.length > max ? `${shown} · and ${names.length - max} more` : shown;
177
+ }
153
178
  function parseInstalledSkills(stdout) {
154
179
  if (!stdout)
155
180
  return [];
@@ -62,25 +62,26 @@ function previewIncludedLine(count) {
62
62
  return ` ${count} preview skill${count === 1 ? "" : "s"} included — labelled in ${count === 1 ? "its" : "each skill's"} guidance; add --stable-only to skip.`;
63
63
  }
64
64
  function selectSkills(name, opts) {
65
- if (opts.all && opts.recommended) {
66
- die("Use only one bulk option: --all or --recommended.");
65
+ if ([opts.all, opts.recommended, opts.assets].filter(Boolean).length > 1) {
66
+ die("Use only one bulk option: --all, --recommended or --assets.");
67
67
  }
68
- if (name && (opts.all || opts.recommended)) {
68
+ if (name && (opts.all || opts.recommended || opts.assets)) {
69
69
  die("Specify either a skill name or a bulk option, not both.");
70
70
  }
71
71
  const skills = getBuiltinSkills();
72
- if (opts.all || opts.recommended) {
72
+ if (opts.all || opts.recommended || opts.assets) {
73
73
  // Bulk installs take stable and preview skills (preview is a label, not a
74
74
  // gate); --stable-only skips preview. An explicit name below installs
75
75
  // regardless of status.
76
76
  const { selected, previewIncluded, previewSkipped } = selectSkillsForBulkInstall(skills, {
77
77
  recommended: Boolean(opts.recommended),
78
78
  stableOnly: Boolean(opts.stableOnly),
79
+ assetsOnly: Boolean(opts.assets),
79
80
  });
80
81
  return { skills: selected, previewIncluded, previewSkipped };
81
82
  }
82
83
  if (!name) {
83
- console.error("Specify a skill name, --recommended, or --all.");
84
+ console.error("Specify a skill name, --recommended, --assets, or --all.");
84
85
  printAvailableSkillNames();
85
86
  process.exit(1);
86
87
  }
@@ -276,7 +277,8 @@ skillsCommand
276
277
  .description("Install Summer skills for a target agent")
277
278
  .option("--all", "Install all available skills")
278
279
  .option("--recommended", "Install only the recommended skill subset (summer setup installs all by default)")
279
- .option("--stable-only", "With --all / --recommended, skip preview skills (installed by default; labelled preview in their guidance)")
280
+ .option("--assets", "Install only the asset skills (sound, music, voice, images, 3D, animation, video) for agents that make assets without the engine")
281
+ .option("--stable-only", "With --all / --recommended / --assets, skip preview skills (installed by default; labelled preview in their guidance)")
280
282
  .option("--agent <agent>", `Target agent: ${AGENT_CLIENTS.join("|")}`)
281
283
  .option("--scope <scope>", "Install scope: user or project")
282
284
  // Legacy aliases: still accepted for old scripts, hidden from --help.
@@ -342,7 +344,9 @@ skillsCommand
342
344
  console.log(previewSkippedLine(previewSkipped));
343
345
  // Claude Code: also install slash commands (`commands/*.md`)
344
346
  // into `~/.claude/commands/`. Other agents don't have an equivalent today.
345
- if (agent === "claude-code") {
347
+ // The commands start and route game work in the engine, so the asset
348
+ // skills (--assets, setup --assets-only) leave them out.
349
+ if (agent === "claude-code" && !opts.assets) {
346
350
  const commandResults = installClaudeCommands(scope, Boolean(opts.force));
347
351
  for (const r of commandResults) {
348
352
  console.log(` ${r.action} command ${r.name} -> ${r.path}`);
package/dist/cli/index.js CHANGED
@@ -16,9 +16,11 @@ import { debugCommand } from "./commands/debug.js";
16
16
  import { configCommand } from "./commands/config.js";
17
17
  import { eventsCommand } from "./commands/events.js";
18
18
  import { toolCommand } from "./commands/tool.js";
19
+ import { opsCliCommands } from "./commands/ops.js";
19
20
  import { getBanner } from "./banner.js";
20
21
  import { runRootAction } from "./root-action.js";
21
22
  import { c, sym } from "../core/format.js";
23
+ import { resolveSurface } from "../core/tool-profiles.js";
22
24
  import { TOOLKIT_VERSION as version } from "../core/version.js";
23
25
  /**
24
26
  * Build and run the summer CLI. The `mcp` command is injected by the bin
@@ -51,6 +53,11 @@ export function runCli(mcpCommand) {
51
53
  program.addCommand(configCommand);
52
54
  program.addCommand(eventsCommand);
53
55
  program.addCommand(toolCommand);
56
+ // The 4.0 operation catalog (`summer <area> <action>`); SUMMER_SURFACE=v3 leaves it out.
57
+ if (resolveSurface(undefined) === "v4") {
58
+ for (const command of opsCliCommands())
59
+ program.addCommand(command);
60
+ }
54
61
  program.parseAsync().catch((err) => {
55
62
  console.error(err instanceof Error ? err.message : String(err));
56
63
  process.exit(1);
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Which agent app runs Summer (Claude Code, Codex, Cursor, ...) and which tool
3
+ * made a request, sent as headers on every request to Summer's servers
4
+ * (summerengine.com and the hosted Summer Engine MCP), so usage can be
5
+ * counted per agent app and per tool.
6
+ *
7
+ * The server reads X-Summer-Agent-Host / X-Summer-Agent-Host-Source
8
+ * (publicsummerengine src/lib/mcp/agent-host.ts) into the attribution of the
9
+ * usage rows a request causes, and X-Summer-MCP-Tool on generation errors.
10
+ * X-Summer-Agent-Host-Name / -Version carry the MCP handshake's clientInfo
11
+ * as the app sent it.
12
+ *
13
+ * Host resolution: SUMMER_AGENT_HOST (explicit override), then the MCP
14
+ * initialize handshake's clientInfo.name, then the environment an agent sets
15
+ * for the commands it runs (the CLI surface), else "unknown".
16
+ *
17
+ * SUMMER_NO_TELEMETRY=1 / DO_NOT_TRACK=1 drop the host and tool headers; the
18
+ * product headers (X-Summer-Client, -Version, -Surface) stay, like a
19
+ * user agent.
20
+ */
21
+ export declare const AGENT_HOST_HEADER = "X-Summer-Agent-Host";
22
+ export declare const AGENT_HOST_SOURCE_HEADER = "X-Summer-Agent-Host-Source";
23
+ export declare const AGENT_HOST_NAME_HEADER = "X-Summer-Agent-Host-Name";
24
+ export declare const AGENT_HOST_VERSION_HEADER = "X-Summer-Agent-Host-Version";
25
+ export declare const MCP_TOOL_HEADER = "X-Summer-MCP-Tool";
26
+ export declare const AGENT_HOST_OVERRIDE_ENV = "SUMMER_AGENT_HOST";
27
+ export type AgentHostSource = "override" | "mcp-client" | "env" | "none";
28
+ export type ClientSurface = "mcp" | "cli";
29
+ export interface AgentHost {
30
+ id: string;
31
+ source: AgentHostSource;
32
+ }
33
+ export interface McpClientInfo {
34
+ name?: string;
35
+ version?: string;
36
+ }
37
+ type Env = Record<string, string | undefined>;
38
+ /** The opt-out switches, the same two the library feedback mailbox honors. */
39
+ export declare function isTelemetryDisabled(env?: Env): boolean;
40
+ /** Lowercase `[a-z0-9-]`, at most 40 characters: the server's host id shape. */
41
+ export declare function sanitizeHostId(raw: string): string;
42
+ /** A known host id, or "other.<name>" for a client Summer does not know yet. */
43
+ export declare function hostFromClientName(name: string | undefined | null): string | null;
44
+ /** AI_AGENT ("<name>_<version>_<mode>") first, then the per-host variables. */
45
+ export declare function hostFromEnv(env: Env): string | null;
46
+ export declare function registerMcpClientSource(source: (() => McpClientInfo | undefined) | null): void;
47
+ export declare function currentMcpClient(): McpClientInfo | undefined;
48
+ export declare function resolveAgentHost(env?: Env, client?: McpClientInfo | undefined): AgentHost;
49
+ interface ToolContext {
50
+ tool: string;
51
+ surface: ClientSurface;
52
+ }
53
+ /** Run one tool call so every Summer request it makes names the tool and surface. */
54
+ export declare function runWithToolContext<T>(tool: string, surface: ClientSurface, fn: () => T): T;
55
+ /** The tool call running now, if any (a tool that runs inside another one sees the outer call). */
56
+ export declare function currentToolContext(): ToolContext | undefined;
57
+ /**
58
+ * Headers for a request to Summer's servers. `tool` names the tool when no
59
+ * tool call is running (the endpoint's own tool); a running call's tool wins.
60
+ */
61
+ export declare function summerRequestHeaders(options?: {
62
+ tool?: string;
63
+ surface?: ClientSurface;
64
+ }, env?: Env): Record<string, string>;
65
+ export {};