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
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  description: Summer Engine game-dev persona and command router. Use for "/summer <anything>" — routes the request to the right Summer skill and starts the game-dev workflow.
3
3
  argument-hint: <what you want to build, fix, or ship>
4
- allowed-tools: Read Glob Grep Edit Write Skill Bash summer_get_project_context summer_get_scene_tree summer_get_diagnostics summer_search_assets summer_create_debug_report
4
+ allowed-tools: Read Glob Grep Edit Write Skill Bash summer_get_project_context summer_get_scene_tree summer_get_diagnostics summer_assets_search summer_create_debug_report summer_call
5
5
  ---
6
6
 
7
7
  # /summer — Summer Engine persona
@@ -16,7 +16,7 @@ $ARGUMENTS
16
16
 
17
17
  ## Voice
18
18
 
19
- You know the engine cold. Scenes are `.tscn`, resources are `.tres`, scripts are GDScript unless the user said C#. The `summer-engine` MCP server drives the running editor. Read every file in the project freely with Read / Glob / Grep — code, scenes, resources, configs; that is how you understand the project. The one rule: do not hand-edit `.tscn` / `.tres` files with Write / Edit while the editor has that scene open — the editor's in-memory state overwrites you on save. Mutate scenes through `summer_*` MCP tools. Scripts, configs, and any closed scene are fine to edit directly.
19
+ You know the engine cold. Scenes are `.tscn`, resources are `.tres`, scripts are GDScript unless the user said C#. The `summer-engine` MCP server drives the running editor. Read every file in the project freely with Read / Glob / Grep — code, scenes, resources, configs; that is how you understand the project. The one rule: do not hand-edit `.tscn` / `.tres` files with Write / Edit while the editor has that scene open — the editor's in-memory state overwrites you on save. Mutate scenes through `summer_*` MCP tools: 3 or more scene edits are one `summer_run_script` with `scenePath` (snapshot, script, diff, screenshot). Scripts, configs, and any closed scene are fine to edit directly.
20
20
 
21
21
  You are opinionated about scope. When the user describes three features in one sentence, ask which one is the playable demo and defer the other two. "Wouldn't it be cool if" gets "yes, after the core loop runs." Get the core loop into the player's hands by the end of the session, then iterate. Polish happens after the game is playable, not before.
22
22
 
@@ -25,7 +25,7 @@ You speak game-dev shorthand (PCs, NPCs, juice, hit-stop, root motion, blendspac
25
25
  ## What to do
26
26
 
27
27
  1. Detect the request shape (new game / new feature / new asset / bug / discussion / build).
28
- 2. Confirm Summer Engine context. Call `summer_get_project_context` if available. If it returns nothing, the user is not in a Summer project yet — route to the `brainstorm-game` skill.
28
+ 2. Confirm Summer Engine context. Call `summer_get_project_context` if available. If it returns nothing and the user wants a game, they are not in a Summer project yet — route to the `brainstorm-game` skill. An asset-only request (a sound, music, a voice line, an image, a model) needs no project, no engine and no brainstorm: go straight to its asset skill. The asset tools run on Summer's servers.
29
29
  3. Invoke the right Summer skill with the `Skill` tool. Do not paraphrase the skill; let the specialist run and follow it exactly.
30
30
  4. Before any generation call, say what you will generate and roughly how long it takes, and wait for an OK.
31
31
 
@@ -40,9 +40,11 @@ Skills are invoked by their bare slug, such as `brainstorm-game`. There is no `s
40
40
  | make me a game from scratch | `make-game` |
41
41
  | add a [character / enemy / NPC / prop / vehicle] | `asset-strategy` |
42
42
  | add a sound for [event] | `sound-effect` |
43
+ | make me a [sound / track / voice line / image / model], no game yet | `sound-effect`, `music-track`, `voice-line`, `concept-art`, `prop-model` (no project needed) |
43
44
  | add ambient music | `music-track` |
44
45
  | make me fire / smoke / lightning / muzzle flash / magic glow / hit spark / dissolve / water ripple | `vfx-fire`, `vfx-smoke`, `vfx-lightning`, `vfx-muzzle-flash`, `vfx-magic-glow`, `vfx-hit-spark`, `vfx-dissolve`, `vfx-water-ripple` |
45
46
  | build the FPS controller | `fps-controller` |
47
+ | build or change a scene, level, HUD or layout in several steps | `scene-scripting` (3 or more scene edits: one `summer_run_script` with `scenePath`) |
46
48
  | debug / the game crashes when [X] / broken behavior / cloud or Codex failure / send this to support | `debug` (support-report mode first: call `summer_create_debug_report` when available and tell the user where the Markdown report was written; keep fixing only if they also asked for a fix) |
47
49
  | add an animation to [character] | `generate-motion` |
48
50
  | wire up a state machine for [character] | `animation-tree` |
@@ -1,3 +1,4 @@
1
+ import { useColor } from "../core/format.js";
1
2
  export function getBanner(version) {
2
3
  const reset = "\x1b[0m";
3
4
  // Vertical gradient for SUMMER ENGINE
@@ -29,5 +30,7 @@ export function getBanner(version) {
29
30
  " ███████╗██║ ╚████║╚██████╔╝██║██║ ╚████║███████╗ ",
30
31
  " ╚══════╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝╚══════╝ ",
31
32
  ];
33
+ if (!useColor())
34
+ return headerLines.join("\n");
32
35
  return headerLines.map((line, i) => `${colors[i]}${line}${reset}`).join("\n");
33
36
  }
@@ -1,5 +1,32 @@
1
1
  import { Command } from "commander";
2
2
  export declare const loginCommand: Command;
3
+ /** How long `summer login` waits for the store's Allow click after the account sign-in. */
4
+ export declare const STORE_STEP_TIMEOUT_MS: number;
5
+ export interface LoginCommandDependencies {
6
+ hasAuthToken: () => Promise<boolean>;
7
+ hasStoreSignIn: () => Promise<boolean>;
8
+ login: () => Promise<void>;
9
+ storeLogin: (options: {
10
+ newClient: boolean;
11
+ timeoutMs?: number;
12
+ }) => Promise<unknown>;
13
+ log: (message: string) => void;
14
+ }
15
+ /**
16
+ * One `summer login`, one browser: the Summer account sign-in (the CLI token
17
+ * for the engine, generation and asset tools), then right away the store
18
+ * sign-in (an OAuth grant for the hosted Summer Engine MCP: store,
19
+ * publishing, board, Grow). The browser is signed in by then, so the second
20
+ * step is one Allow click, or none when this machine was approved before.
21
+ * The two are separate credentials on the server, so a failed store step
22
+ * keeps the account sign-in and says how to finish later.
23
+ *
24
+ * --store: only the store step (as before). --no-store: only the account.
25
+ */
26
+ export declare function runLoginCommand(opts: {
27
+ store?: boolean;
28
+ force?: boolean;
29
+ }, overrides?: Partial<LoginCommandDependencies>): Promise<void>;
3
30
  export interface LoginDependencies {
4
31
  fetch: typeof fetch;
5
32
  openUrl: (url: string) => Promise<unknown>;
@@ -2,6 +2,7 @@ import { Command } from "commander";
2
2
  import { randomUUID } from "crypto";
3
3
  import open from "open";
4
4
  import { getAuthToken, saveLoginSession, } from "../../core/auth.js";
5
+ import { summerRequestHeaders } from "../../core/agent-host.js";
5
6
  import { resolveGatewayUrl } from "../../core/config.js";
6
7
  import { readStoredOAuthToken, runStoreLogin } from "../../core/oauth.js";
7
8
  const POLL_INTERVAL_MS = 2000;
@@ -13,27 +14,71 @@ const POLL_INTERVAL_MS = 2000;
13
14
  const POLL_TIMEOUT_MS = 900000;
14
15
  const HEARTBEAT_MS = 30000;
15
16
  export const loginCommand = new Command("login")
16
- .description("Sign in to Summer Engine via your browser")
17
- .option("--store", "Sign in to the Summer store so agents can upload builds (summer_publish_build)")
17
+ .description("Sign in to Summer in your browser: your Summer account, then the store, publishing and Grow tools in the same browser")
18
+ .option("--store", "Only the store sign-in (summer_publish_build, the store, publishing, board and Grow tools); plain summer login does it too")
19
+ .option("--no-store", "Only the Summer account sign-in; skip the store sign-in")
18
20
  .option("--force", "Force re-authentication even if already logged in")
19
21
  .action(async (opts) => {
20
- if (opts.store) {
21
- if ((await readStoredOAuthToken()) && !opts.force) {
22
- console.log("Already signed in to the Summer store. Use --store --force to sign in again.");
22
+ await runLoginCommand(opts);
23
+ });
24
+ /** How long `summer login` waits for the store's Allow click after the account sign-in. */
25
+ export const STORE_STEP_TIMEOUT_MS = 3 * 60_000;
26
+ const defaultCommandDependencies = {
27
+ hasAuthToken: async () => Boolean(await getAuthToken()),
28
+ hasStoreSignIn: async () => Boolean(await readStoredOAuthToken()),
29
+ login: () => runLogin(),
30
+ storeLogin: ({ newClient, timeoutMs }) => runStoreLogin({ fetch, now: Date.now, openUrl: open, log: console.log, newClient, ...(timeoutMs ? { timeoutMs } : {}) }),
31
+ log: console.log,
32
+ };
33
+ /**
34
+ * One `summer login`, one browser: the Summer account sign-in (the CLI token
35
+ * for the engine, generation and asset tools), then right away the store
36
+ * sign-in (an OAuth grant for the hosted Summer Engine MCP: store,
37
+ * publishing, board, Grow). The browser is signed in by then, so the second
38
+ * step is one Allow click, or none when this machine was approved before.
39
+ * The two are separate credentials on the server, so a failed store step
40
+ * keeps the account sign-in and says how to finish later.
41
+ *
42
+ * --store: only the store step (as before). --no-store: only the account.
43
+ */
44
+ export async function runLoginCommand(opts, overrides = {}) {
45
+ const deps = { ...defaultCommandDependencies, ...overrides };
46
+ const force = Boolean(opts.force);
47
+ if (opts.store === true) {
48
+ if ((await deps.hasStoreSignIn()) && !force) {
49
+ deps.log("Already signed in to the Summer store. Use --store --force to sign in again.");
23
50
  return;
24
51
  }
25
52
  // --force also registers a new client, the way back if this machine's was removed.
26
- await runStoreLogin({ fetch, now: Date.now, openUrl: open, log: console.log, newClient: Boolean(opts.force) });
27
- console.log("Signed in to the Summer store. Your core Summer login was not changed.");
53
+ await deps.storeLogin({ newClient: force });
54
+ deps.log("Signed in to the Summer store. Your core Summer login was not changed.");
28
55
  return;
29
56
  }
30
- const existing = await getAuthToken();
31
- if (existing && !opts.force) {
32
- console.log("Already logged in. Use --force to re-authenticate.");
57
+ const signedIn = (await deps.hasAuthToken()) && !force;
58
+ const storeNeeded = opts.store !== false && (force || !(await deps.hasStoreSignIn()));
59
+ if (signedIn) {
60
+ deps.log(storeNeeded
61
+ ? "Already logged in to Summer. Connecting the store, publishing and Grow tools next."
62
+ : "Already logged in. Use --force to re-authenticate.");
63
+ }
64
+ else {
65
+ await deps.login();
66
+ deps.log("Signed-in MCP sessions report each tool call to Summer (tool name, success, duration, agent app name); SUMMER_NO_TELEMETRY=1 turns that off.");
67
+ }
68
+ if (!storeNeeded)
33
69
  return;
70
+ deps.log("");
71
+ deps.log("Next, the store, publishing and Grow tools: approve Summer CLI in the same browser.");
72
+ try {
73
+ await deps.storeLogin({ newClient: false, timeoutMs: STORE_STEP_TIMEOUT_MS });
74
+ deps.log("Signed in to the Summer store too. One sign-in covers every Summer tool on this machine.");
34
75
  }
35
- await runLogin();
36
- });
76
+ catch (error) {
77
+ const reason = error instanceof Error ? error.message : String(error);
78
+ deps.log(`The store sign-in did not finish: ${reason}`);
79
+ deps.log('Your Summer login is saved. To add the store, publishing and Grow tools later, run "summer login --store".');
80
+ }
81
+ }
37
82
  /** The gateway answered with a terminal 4xx — retrying the same URL cannot help. */
38
83
  class LoginRejectedError extends Error {
39
84
  }
@@ -80,6 +125,7 @@ export async function runLogin(overrides = {}) {
80
125
  let completed = null;
81
126
  try {
82
127
  const res = await deps.fetch(pollUrl, {
128
+ headers: summerRequestHeaders({ surface: "cli" }),
83
129
  signal: AbortSignal.timeout(5000),
84
130
  });
85
131
  if (!res.ok) {
@@ -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;