summer-engine 3.0.0 → 3.2.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 (413) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +27 -5
  3. package/.codex-plugin/plugin.json +28 -6
  4. package/.cursor-plugin/plugin.json +27 -5
  5. package/.factory-plugin/plugin.json +27 -5
  6. package/.opencode/plugins/summer.js +1 -1
  7. package/CHANGELOG.md +120 -0
  8. package/README.md +22 -7
  9. package/assets/audit/scene_audit.gd +4136 -0
  10. package/assets/seeing/seeing_probe.gd +1873 -0
  11. package/dist/cli/commands/setup.js +6 -19
  12. package/dist/cli/commands/skills.js +57 -32
  13. package/dist/core/api-client.d.ts +9 -1
  14. package/dist/core/api-client.js +21 -4
  15. package/dist/core/capabilities/agent-playbook.js +46 -0
  16. package/dist/core/capabilities/audit/accept.d.ts +55 -0
  17. package/dist/core/capabilities/audit/accept.js +147 -0
  18. package/dist/core/capabilities/audit/args.d.ts +95 -0
  19. package/dist/core/capabilities/audit/args.js +89 -0
  20. package/dist/core/capabilities/audit/audit.d.ts +56 -0
  21. package/dist/core/capabilities/audit/audit.js +287 -0
  22. package/dist/core/capabilities/audit/frame.d.ts +14 -0
  23. package/dist/core/capabilities/audit/frame.js +35 -0
  24. package/dist/core/capabilities/audit/gaps.d.ts +96 -0
  25. package/dist/core/capabilities/audit/gaps.js +257 -0
  26. package/dist/core/capabilities/audit/judge.d.ts +162 -0
  27. package/dist/core/capabilities/audit/judge.js +1134 -0
  28. package/dist/core/capabilities/audit/math.d.ts +110 -0
  29. package/dist/core/capabilities/audit/math.js +263 -0
  30. package/dist/core/capabilities/audit/summary.d.ts +74 -0
  31. package/dist/core/capabilities/audit/summary.js +212 -0
  32. package/dist/core/capabilities/board.d.ts +31 -0
  33. package/dist/core/capabilities/board.js +43 -0
  34. package/dist/core/capabilities/camera-view.d.ts +4 -2
  35. package/dist/core/capabilities/camera-view.js +6 -3
  36. package/dist/core/capabilities/connect-signal.d.ts +85 -0
  37. package/dist/core/capabilities/connect-signal.js +285 -0
  38. package/dist/core/capabilities/engine-fallbacks.d.ts +5 -0
  39. package/dist/core/capabilities/engine-fallbacks.js +5 -0
  40. package/dist/core/capabilities/engine-ops.d.ts +5 -1
  41. package/dist/core/capabilities/engine-ops.js +0 -3
  42. package/dist/core/capabilities/engine-receipt.d.ts +12 -0
  43. package/dist/core/capabilities/engine-receipt.js +26 -0
  44. package/dist/core/capabilities/file-read.d.ts +64 -0
  45. package/dist/core/capabilities/file-read.js +325 -0
  46. package/dist/core/capabilities/game-task-plan.js +4 -2
  47. package/dist/core/capabilities/grep.d.ts +60 -0
  48. package/dist/core/capabilities/grep.js +190 -0
  49. package/dist/core/capabilities/inspect-node.d.ts +56 -0
  50. package/dist/core/capabilities/inspect-node.js +225 -0
  51. package/dist/core/capabilities/inspect-resource.d.ts +61 -0
  52. package/dist/core/capabilities/inspect-resource.js +376 -0
  53. package/dist/core/capabilities/math3d.d.ts +28 -0
  54. package/dist/core/capabilities/math3d.js +88 -0
  55. package/dist/core/capabilities/motion-generation.d.ts +62 -0
  56. package/dist/core/capabilities/motion-generation.js +138 -0
  57. package/dist/core/capabilities/placement-batch.d.ts +102 -0
  58. package/dist/core/capabilities/placement-batch.js +483 -0
  59. package/dist/core/capabilities/placement-math.d.ts +70 -0
  60. package/dist/core/capabilities/placement-math.js +209 -0
  61. package/dist/core/capabilities/placement-script.d.ts +42 -0
  62. package/dist/core/capabilities/placement-script.js +1096 -0
  63. package/dist/core/capabilities/placement.d.ts +485 -0
  64. package/dist/core/capabilities/placement.js +1731 -0
  65. package/dist/core/capabilities/project-context.d.ts +33 -2
  66. package/dist/core/capabilities/project-context.js +87 -4
  67. package/dist/core/capabilities/replace-node.d.ts +91 -0
  68. package/dist/core/capabilities/replace-node.js +423 -0
  69. package/dist/core/capabilities/runtime-control.d.ts +20 -4
  70. package/dist/core/capabilities/runtime-control.js +67 -2
  71. package/dist/core/capabilities/scene-batch.d.ts +63 -0
  72. package/dist/core/capabilities/scene-batch.js +394 -0
  73. package/dist/core/capabilities/scene-readback.d.ts +36 -0
  74. package/dist/core/capabilities/scene-readback.js +54 -0
  75. package/dist/core/capabilities/seeing/args.d.ts +348 -0
  76. package/dist/core/capabilities/seeing/args.js +178 -0
  77. package/dist/core/capabilities/seeing/candidates.d.ts +127 -0
  78. package/dist/core/capabilities/seeing/candidates.js +282 -0
  79. package/dist/core/capabilities/seeing/math.d.ts +134 -0
  80. package/dist/core/capabilities/seeing/math.js +269 -0
  81. package/dist/core/capabilities/seeing/probe.d.ts +62 -0
  82. package/dist/core/capabilities/seeing/probe.js +188 -0
  83. package/dist/core/capabilities/seeing/scoring.d.ts +235 -0
  84. package/dist/core/capabilities/seeing/scoring.js +639 -0
  85. package/dist/core/capabilities/seeing/seeing.d.ts +233 -0
  86. package/dist/core/capabilities/seeing/seeing.js +1341 -0
  87. package/dist/core/capabilities/seeing/shot-store.d.ts +52 -0
  88. package/dist/core/capabilities/seeing/shot-store.js +204 -0
  89. package/dist/core/capabilities/surface-snap-mesh.d.ts +88 -0
  90. package/dist/core/capabilities/surface-snap-mesh.js +425 -0
  91. package/dist/core/capabilities/surface-snap.d.ts +77 -0
  92. package/dist/core/capabilities/surface-snap.js +461 -0
  93. package/dist/core/capabilities/tool-dispatch.js +231 -72
  94. package/dist/core/capabilities/tscn.d.ts +85 -0
  95. package/dist/core/capabilities/tscn.js +391 -0
  96. package/dist/core/capabilities/world-snapshot.d.ts +58 -0
  97. package/dist/core/capabilities/world-snapshot.js +150 -0
  98. package/dist/core/capability-skew.d.ts +5 -5
  99. package/dist/core/capability-skew.js +14 -6
  100. package/dist/core/headless/worker-engine-client.d.ts +1 -1
  101. package/dist/core/headless/worker-engine-client.js +2 -2
  102. package/dist/core/library-read.d.ts +37 -5
  103. package/dist/core/library-read.js +264 -33
  104. package/dist/core/library-search.d.ts +2 -2
  105. package/dist/core/skills-registry.d.ts +9 -1
  106. package/dist/core/skills-registry.js +25 -2
  107. package/dist/installer/agent-config.d.ts +9 -4
  108. package/dist/installer/agent-config.js +194 -392
  109. package/dist/installer/agent-table.d.ts +119 -0
  110. package/dist/installer/agent-table.js +619 -0
  111. package/dist/installer/setup.js +4 -2
  112. package/dist/installer/skill-locations.d.ts +8 -17
  113. package/dist/installer/skill-locations.js +22 -101
  114. package/dist/installer/version-check.d.ts +5 -1
  115. package/dist/installer/version-check.js +38 -28
  116. package/dist/mcp/server.js +9 -3
  117. package/dist/mcp/tools/asset-tools.js +21 -3
  118. package/dist/mcp/tools/audit-tools.d.ts +23 -0
  119. package/dist/mcp/tools/audit-tools.js +60 -0
  120. package/dist/mcp/tools/debug-tools.js +3 -1
  121. package/dist/mcp/tools/file-tools.js +17 -4
  122. package/dist/mcp/tools/generate-tools.js +74 -66
  123. package/dist/mcp/tools/library-tools.js +2 -0
  124. package/dist/mcp/tools/perception-tools.js +6 -19
  125. package/dist/mcp/tools/placement-tools.d.ts +24 -0
  126. package/dist/mcp/tools/placement-tools.js +91 -0
  127. package/dist/mcp/tools/project-tools.js +18 -15
  128. package/dist/mcp/tools/scene-tools.js +71 -83
  129. package/dist/mcp/tools/seeing-tools.d.ts +24 -0
  130. package/dist/mcp/tools/seeing-tools.js +64 -0
  131. package/dist/mcp/tools/spatial-tools.js +17 -9
  132. package/dist/mcp/tools/visual-tools.js +59 -7
  133. package/gemini-extension.json +26 -4
  134. package/integrations/README.md +48 -19
  135. package/integrations/amp/README.md +12 -0
  136. package/integrations/amp/manifest-target.json +3 -0
  137. package/integrations/antigravity/README.md +12 -0
  138. package/integrations/antigravity/manifest-target.json +3 -0
  139. package/integrations/claude-desktop/README.md +12 -0
  140. package/integrations/claude-desktop/manifest-target.json +3 -0
  141. package/integrations/cline/README.md +8 -9
  142. package/integrations/cline-cli/README.md +12 -0
  143. package/integrations/cline-cli/manifest-target.json +3 -0
  144. package/integrations/copilot-jetbrains/README.md +12 -0
  145. package/integrations/copilot-jetbrains/manifest-target.json +3 -0
  146. package/integrations/crush/README.md +12 -0
  147. package/integrations/crush/manifest-target.json +3 -0
  148. package/integrations/github-copilot/README.md +8 -8
  149. package/integrations/goose/README.md +12 -0
  150. package/integrations/goose/manifest-target.json +3 -0
  151. package/integrations/grok-build/README.md +12 -0
  152. package/integrations/grok-build/manifest-target.json +3 -0
  153. package/integrations/hermes/README.md +12 -0
  154. package/integrations/hermes/manifest-target.json +3 -0
  155. package/integrations/junie/README.md +12 -0
  156. package/integrations/junie/manifest-target.json +3 -0
  157. package/integrations/kilo-code/README.md +6 -10
  158. package/integrations/kimi-code/README.md +12 -0
  159. package/integrations/kimi-code/manifest-target.json +3 -0
  160. package/integrations/kiro/README.md +12 -0
  161. package/integrations/kiro/manifest-target.json +3 -0
  162. package/integrations/lm-studio/README.md +8 -8
  163. package/integrations/mistral-vibe/README.md +12 -0
  164. package/integrations/mistral-vibe/manifest-target.json +3 -0
  165. package/integrations/opencode/README.md +9 -12
  166. package/integrations/qoder/README.md +12 -0
  167. package/integrations/qoder/manifest-target.json +3 -0
  168. package/integrations/qwen-code/README.md +12 -0
  169. package/integrations/qwen-code/manifest-target.json +3 -0
  170. package/integrations/roo-code/README.md +8 -7
  171. package/integrations/rovo-dev/README.md +12 -0
  172. package/integrations/rovo-dev/manifest-target.json +3 -0
  173. package/integrations/trae/README.md +12 -0
  174. package/integrations/trae/manifest-target.json +3 -0
  175. package/integrations/visual-studio/README.md +12 -0
  176. package/integrations/visual-studio/manifest-target.json +3 -0
  177. package/integrations/vscode-copilot/README.md +9 -9
  178. package/integrations/warp/README.md +12 -0
  179. package/integrations/warp/manifest-target.json +3 -0
  180. package/integrations/windsurf/README.md +8 -9
  181. package/integrations/zed/README.md +12 -0
  182. package/integrations/zed/manifest-target.json +3 -0
  183. package/library/references/mcp-tools-reference/mcp-tools-reference.md +59 -15
  184. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  185. package/library/references/summer-folder/resource.yaml +1 -1
  186. package/library/references/summer-folder/summer-folder.md +1 -1
  187. package/library/skills/3d-lighting/SKILL.md +1 -1
  188. package/library/skills/README.md +264 -0
  189. package/library/skills/adaptive-music/SKILL.md +1 -1
  190. package/library/skills/agent-playtesting/SKILL.md +1 -1
  191. package/library/skills/ai-characters-in-games/SKILL.md +220 -0
  192. package/library/skills/ai-characters-in-games/resource.yaml +30 -0
  193. package/library/skills/ambient-bed/SKILL.md +1 -1
  194. package/library/skills/animated-loop/SKILL.md +1 -1
  195. package/library/skills/animation-tree/SKILL.md +1 -1
  196. package/library/skills/art-direction/SKILL.md +1 -1
  197. package/library/skills/asset-strategy/SKILL.md +2 -1
  198. package/library/skills/asset-strategy/resource.yaml +2 -1
  199. package/library/skills/audio-direction/SKILL.md +1 -1
  200. package/library/skills/auto-fire-targeting/SKILL.md +1 -1
  201. package/library/skills/brainstorm-game/SKILL.md +1 -1
  202. package/library/skills/brainstorming/SKILL.md +1 -1
  203. package/library/skills/browse-templates/SKILL.md +3 -3
  204. package/library/skills/browse-templates/resource.yaml +1 -1
  205. package/library/skills/camera-rigs/SKILL.md +128 -0
  206. package/library/skills/camera-rigs/resource.yaml +29 -0
  207. package/library/skills/celeste-momentum-platforming/SKILL.md +1 -1
  208. package/library/skills/character-animation-wiring/SKILL.md +1 -1
  209. package/library/skills/character-model/SKILL.md +1 -1
  210. package/library/skills/character-movement/SKILL.md +326 -0
  211. package/library/skills/character-movement/references/default-third-person-controller.gd +201 -0
  212. package/library/skills/character-movement/references/default-third-person-verification-probe.gd +154 -0
  213. package/library/skills/character-movement/references/movement-3d.md +136 -0
  214. package/library/skills/character-movement/references/platformer-feel.md +83 -0
  215. package/library/skills/character-movement/resource.yaml +40 -0
  216. package/library/skills/character-portrait/SKILL.md +1 -1
  217. package/library/skills/cinematic-cutscene/SKILL.md +1 -1
  218. package/library/skills/combat-basics/SKILL.md +159 -0
  219. package/library/skills/combat-basics/references/projectiles-and-aoe.md +100 -0
  220. package/library/skills/combat-basics/resource.yaml +34 -0
  221. package/library/skills/concept-art/SKILL.md +1 -1
  222. package/library/skills/create-asset-sheet/SKILL.md +1 -1
  223. package/library/skills/debug/SKILL.md +1 -1
  224. package/library/skills/debugging-game-feel/SKILL.md +1 -1
  225. package/library/skills/design-level/SKILL.md +1 -1
  226. package/library/skills/design-mechanic/SKILL.md +1 -1
  227. package/library/skills/design-npc/SKILL.md +1 -1
  228. package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
  229. package/library/skills/dispatching-parallel-agents/SKILL.md +1 -1
  230. package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
  231. package/library/skills/environment-kit/SKILL.md +1 -1
  232. package/library/skills/export-and-ship/SKILL.md +1 -1
  233. package/library/skills/fabricating-assets/SKILL.md +1 -1
  234. package/library/skills/facial-and-lipsync/SKILL.md +1 -1
  235. package/library/skills/fps-controller/SKILL.md +9 -7
  236. package/library/skills/fps-controller/resource.yaml +4 -1
  237. package/library/skills/game-feel/SKILL.md +1 -1
  238. package/library/skills/gameskill/SKILL.md +1 -1
  239. package/library/skills/gdscript-patterns/SKILL.md +1 -1
  240. package/library/skills/generate-motion/SKILL.md +9 -9
  241. package/library/skills/generate-motion/resource.yaml +2 -1
  242. package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
  243. package/library/skills/headless-scripting/SKILL.md +1 -1
  244. package/library/skills/in-game-purchases/SKILL.md +254 -0
  245. package/library/skills/in-game-purchases/resource.yaml +29 -0
  246. package/library/skills/instantiate-asset-pack/SKILL.md +1 -1
  247. package/library/skills/investigating-bugs/SKILL.md +1 -1
  248. package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +1 -1
  249. package/library/skills/make-game/SKILL.md +25 -3
  250. package/library/skills/make-game/references/2d-platformer-polish.md +93 -0
  251. package/library/skills/make-game/references/2d-platformer.md +117 -0
  252. package/library/skills/make-game/references/2d-rpg-content.md +234 -0
  253. package/library/skills/make-game/references/2d-rpg.md +241 -0
  254. package/library/skills/make-game/references/2d-survivors-progression.md +201 -0
  255. package/library/skills/make-game/references/2d-survivors.md +237 -0
  256. package/library/skills/make-game/references/3d-fps-systems.md +216 -0
  257. package/library/skills/make-game/references/3d-fps.md +177 -0
  258. package/library/skills/make-game/references/3d-horror-systems.md +186 -0
  259. package/library/skills/make-game/references/3d-horror.md +201 -0
  260. package/library/skills/make-game/references/3d-third-person-systems.md +220 -0
  261. package/library/skills/make-game/references/3d-third-person.md +215 -0
  262. package/library/skills/make-game/resource.yaml +6 -1
  263. package/library/skills/multiplayer/SKILL.md +150 -0
  264. package/library/skills/multiplayer/resource.yaml +33 -0
  265. package/library/skills/multiplayer-movement/SKILL.md +510 -0
  266. package/library/skills/multiplayer-movement/files.md +501 -0
  267. package/library/skills/multiplayer-movement/resource.yaml +30 -0
  268. package/library/skills/multiplayer-project/SKILL.md +521 -0
  269. package/library/skills/multiplayer-project/files.md +448 -0
  270. package/library/skills/multiplayer-project/resource.yaml +36 -0
  271. package/library/skills/multiplayer-publish/SKILL.md +229 -0
  272. package/library/skills/multiplayer-publish/export-errors.md +89 -0
  273. package/library/skills/multiplayer-publish/resource.yaml +28 -0
  274. package/library/skills/multiplayer-state/SKILL.md +438 -0
  275. package/library/skills/multiplayer-state/files.md +592 -0
  276. package/library/skills/multiplayer-state/resource.yaml +35 -0
  277. package/library/skills/multiplayer-testing/SKILL.md +236 -0
  278. package/library/skills/multiplayer-testing/resource.yaml +39 -0
  279. package/library/skills/music-track/SKILL.md +1 -1
  280. package/library/skills/navigate-summer/SKILL.md +1 -1
  281. package/library/skills/new-project/SKILL.md +1 -1
  282. package/library/skills/organic-model/SKILL.md +1 -1
  283. package/library/skills/pixel-art/SKILL.md +1 -1
  284. package/library/skills/play/SKILL.md +1 -1
  285. package/library/skills/playtesting-a-feature/SKILL.md +1 -1
  286. package/library/skills/procedural-animation/SKILL.md +2 -2
  287. package/library/skills/procedural-animation/resource.yaml +1 -1
  288. package/library/skills/prop-model/SKILL.md +1 -1
  289. package/library/skills/psx-retro-rendering/SKILL.md +1 -1
  290. package/library/skills/realtime-wet-surfaces/SKILL.md +2 -2
  291. package/library/skills/remote-deploy/SKILL.md +1 -1
  292. package/library/skills/retarget/SKILL.md +1 -1
  293. package/library/skills/running-in-the-cloud/SKILL.md +1 -1
  294. package/library/skills/save-load/SKILL.md +156 -0
  295. package/library/skills/save-load/resource.yaml +27 -0
  296. package/library/skills/scene-composition/SKILL.md +1 -1
  297. package/library/skills/scene-hierarchy-design/SKILL.md +1 -1
  298. package/library/skills/scene-scripting/SKILL.md +1 -1
  299. package/library/skills/scene-to-level/SKILL.md +1 -1
  300. package/library/skills/skill-create/SKILL.md +1 -1
  301. package/library/skills/skill-improve/SKILL.md +1 -1
  302. package/library/skills/skill-test/SKILL.md +1 -1
  303. package/library/skills/skintokens-auto-rigging/SKILL.md +1 -1
  304. package/library/skills/skybox-panorama/SKILL.md +1 -1
  305. package/library/skills/sound-effect/SKILL.md +1 -1
  306. package/library/skills/spatial-placement/SKILL.md +134 -3
  307. package/library/skills/spatial-placement/references/kit-placement-tools.md +364 -0
  308. package/library/skills/spatial-placement/resource.yaml +16 -2
  309. package/library/skills/sprite-sheet/SKILL.md +1 -1
  310. package/library/skills/summer-analytics/SKILL.md +147 -0
  311. package/library/skills/summer-analytics/resource.yaml +28 -0
  312. package/library/skills/summer-friends/SKILL.md +226 -0
  313. package/library/skills/summer-friends/resource.yaml +28 -0
  314. package/library/skills/summer-leaderboards/SKILL.md +231 -0
  315. package/library/skills/summer-leaderboards/resource.yaml +30 -0
  316. package/library/skills/summer-match-results/SKILL.md +286 -0
  317. package/library/skills/summer-match-results/resource.yaml +32 -0
  318. package/library/skills/summer-matchmaking/SKILL.md +301 -0
  319. package/library/skills/summer-matchmaking/resource.yaml +32 -0
  320. package/library/skills/summer-parties/SKILL.md +253 -0
  321. package/library/skills/summer-parties/resource.yaml +30 -0
  322. package/library/skills/summer-player-data/SKILL.md +322 -0
  323. package/library/skills/summer-player-data/resource.yaml +30 -0
  324. package/library/skills/summer-store/SKILL.md +271 -0
  325. package/library/skills/summer-store/resource.yaml +29 -0
  326. package/library/skills/summer-world-chat/SKILL.md +195 -0
  327. package/library/skills/summer-world-chat/resource.yaml +30 -0
  328. package/library/skills/summer-world-saves/SKILL.md +284 -0
  329. package/library/skills/summer-world-saves/resource.yaml +29 -0
  330. package/library/skills/text-to-motion/SKILL.md +99 -0
  331. package/library/skills/text-to-motion/prompts-and-controls.md +34 -0
  332. package/library/skills/text-to-motion/resource.yaml +41 -0
  333. package/library/skills/text-to-motion/rigging-for-text-motion.md +54 -0
  334. package/library/skills/tileable-texture/SKILL.md +1 -1
  335. package/library/skills/trailer-shot/SKILL.md +1 -1
  336. package/library/skills/tune-performance/SKILL.md +1 -1
  337. package/library/skills/ui-basics/SKILL.md +10 -1
  338. package/library/skills/ui-graphics/SKILL.md +1 -1
  339. package/library/skills/use-widget-asset/SKILL.md +1 -1
  340. package/library/skills/using-summer/SKILL.md +2 -2
  341. package/library/skills/using-summer/resource.yaml +2 -2
  342. package/library/skills/vehicle-model/SKILL.md +1 -1
  343. package/library/skills/verification-before-completion/SKILL.md +1 -1
  344. package/library/skills/verifying-scenes/SKILL.md +76 -2
  345. package/library/skills/verifying-scenes/resource.yaml +13 -2
  346. package/library/skills/vfx-dissolve/SKILL.md +1 -1
  347. package/library/skills/vfx-fire/SKILL.md +1 -1
  348. package/library/skills/vfx-hit-spark/SKILL.md +1 -1
  349. package/library/skills/vfx-lightning/SKILL.md +1 -1
  350. package/library/skills/vfx-magic-glow/SKILL.md +1 -1
  351. package/library/skills/vfx-muzzle-flash/SKILL.md +1 -1
  352. package/library/skills/vfx-smoke/SKILL.md +1 -1
  353. package/library/skills/vfx-water-ripple/SKILL.md +1 -1
  354. package/library/skills/voice-line/SKILL.md +1 -1
  355. package/library/skills/web-and-touch-input/SKILL.md +38 -0
  356. package/library/skills/web-and-touch-input/resource.yaml +28 -0
  357. package/library/skills/web-compatibility-look/SKILL.md +62 -0
  358. package/library/skills/web-compatibility-look/resource.yaml +30 -0
  359. package/library/skills/world-building-3d/SKILL.md +8 -1
  360. package/library/skills/world-building-3d/references/spatial-tools.md +1 -1
  361. package/library/skills/world-building-3d/resource.yaml +2 -1
  362. package/library/skills/writing-plans/SKILL.md +1 -1
  363. package/library/skills/writing-skills/SKILL.md +1 -1
  364. package/library/templates/3d-lan-multiplayer-starter/resource.yaml +2 -2
  365. package/library/tools/attach-to-surface/resource.yaml +142 -0
  366. package/library/tools/batch/resource.yaml +9 -3
  367. package/library/tools/connect-ports/resource.yaml +120 -0
  368. package/library/tools/connect-signal/resource.yaml +3 -2
  369. package/library/tools/debug-views/resource.yaml +94 -0
  370. package/library/tools/frame-nodes/resource.yaml +104 -0
  371. package/library/tools/frame-shot/resource.yaml +134 -0
  372. package/library/tools/generate-motion/resource.yaml +44 -9
  373. package/library/tools/get-board/resource.yaml +50 -0
  374. package/library/tools/get-project-context/resource.yaml +13 -2
  375. package/library/tools/grep/resource.yaml +77 -0
  376. package/library/tools/inspect-asset/resource.yaml +71 -0
  377. package/library/tools/inspect-node/resource.yaml +9 -2
  378. package/library/tools/inspect-resource/resource.yaml +16 -5
  379. package/library/tools/instantiate-scene/resource.yaml +27 -2
  380. package/library/tools/measure/resource.yaml +96 -0
  381. package/library/tools/place-adjacent/resource.yaml +113 -0
  382. package/library/tools/play/resource.yaml +15 -2
  383. package/library/tools/raycast/resource.yaml +101 -0
  384. package/library/tools/read-file/resource.yaml +36 -2
  385. package/library/tools/read-library/resource.yaml +2 -2
  386. package/library/tools/repeat-along/resource.yaml +129 -0
  387. package/library/tools/replace-node/resource.yaml +11 -5
  388. package/library/tools/scene-audit/resource.yaml +144 -0
  389. package/library/tools/screenshot/resource.yaml +13 -2
  390. package/library/tools/search-assets/resource.yaml +18 -0
  391. package/library/tools/shot-sheet/resource.yaml +110 -0
  392. package/library/tools/snap-to-surface/resource.yaml +4 -1
  393. package/library/tools/world-snapshot/resource.yaml +24 -3
  394. package/library/tools/zoom/resource.yaml +105 -0
  395. package/package.json +3 -3
  396. package/registry/generated/aliases.json +17 -3
  397. package/registry/generated/counts.json +3 -3
  398. package/registry/generated/gemini-extension.json +26 -4
  399. package/registry/generated/index.json +2154 -469
  400. package/registry/generated/marketplace.claude.json +2 -2
  401. package/registry/generated/plugin.claude.json +27 -5
  402. package/registry/generated/plugin.codex.json +28 -6
  403. package/registry/generated/plugin.cursor.json +27 -5
  404. package/registry/generated/plugin.factory.json +27 -5
  405. package/registry/generated/skills-index.md +264 -0
  406. package/registry/generated/skills-registry.json +901 -206
  407. package/registry/generated/templates-registry.json +2 -2
  408. package/library/skills/host-authoritative-state/SKILL.md +0 -332
  409. package/library/skills/host-authoritative-state/resource.yaml +0 -28
  410. package/library/skills/peer-to-peer-multiplayer/SKILL.md +0 -373
  411. package/library/skills/peer-to-peer-multiplayer/resource.yaml +0 -28
  412. package/library/skills/setup-multiplayer/SKILL.md +0 -336
  413. package/library/skills/setup-multiplayer/resource.yaml +0 -28
@@ -2,56 +2,12 @@ import { existsSync, readFileSync } from "fs";
2
2
  import { copyFile, mkdir, readFile, writeFile } from "fs/promises";
3
3
  import { dirname, join, resolve } from "path";
4
4
  import { fileURLToPath } from "url";
5
+ import { Document, isMap, parseDocument } from "yaml";
5
6
  import { PACKAGE_ROOT } from "../core/package-root.js";
6
- import { homedir, platform } from "os";
7
+ import { agentAliasMap, agentSpec, defaultPathContext, resolveMcpPath, supportedAgents, } from "./agent-table.js";
8
+ export { supportedAgents } from "./agent-table.js";
7
9
  export const SUMMER_MCP_SERVER_NAME = "summer-engine";
8
- export const supportedAgents = [
9
- "codex",
10
- "claude-code",
11
- "cursor",
12
- "windsurf",
13
- "cline",
14
- "roo-code",
15
- "kilo-code",
16
- "gemini",
17
- "github-copilot",
18
- "vscode-copilot",
19
- "opencode",
20
- "lm-studio",
21
- ];
22
- const agentAliases = {
23
- claude: "claude-code",
24
- "claude-code": "claude-code",
25
- codex: "codex",
26
- cursor: "cursor",
27
- windsurf: "windsurf",
28
- devin: "windsurf",
29
- "devin-desktop": "windsurf",
30
- devindesktop: "windsurf",
31
- cline: "cline",
32
- "roo-code": "roo-code",
33
- roo: "roo-code",
34
- roocode: "roo-code",
35
- kilo: "kilo-code",
36
- kilocode: "kilo-code",
37
- "kilo-code": "kilo-code",
38
- gemini: "gemini",
39
- "gemini-cli": "gemini",
40
- copilot: "github-copilot",
41
- "copilot-cli": "github-copilot",
42
- "github-copilot": "github-copilot",
43
- "github-copilot-cli": "github-copilot",
44
- vscode: "vscode-copilot",
45
- "vs-code": "vscode-copilot",
46
- "vscode-copilot": "vscode-copilot",
47
- "vs-code-copilot": "vscode-copilot",
48
- "github-copilot-vscode": "vscode-copilot",
49
- opencode: "opencode",
50
- "open-code": "opencode",
51
- lmstudio: "lm-studio",
52
- "lm-studio": "lm-studio",
53
- "lm_studio": "lm-studio",
54
- };
10
+ const agentAliases = agentAliasMap();
55
11
  export function parseAgent(value) {
56
12
  if (!value)
57
13
  return null;
@@ -90,31 +46,22 @@ export async function configureAgentMcp(options) {
90
46
  const cwd = resolve(options.cwd ?? process.cwd());
91
47
  const channel = normalizeChannel(options.channel);
92
48
  const server = createSummerMcpServerConfig(Boolean(options.localDev), process.platform, channel);
93
- const target = resolveConfigTarget(options.agent, options.scope, cwd, env);
49
+ const spec = agentSpec(options.agent);
50
+ const target = resolveConfigTarget(spec, options.scope, cwd, env);
94
51
  const snippet = renderConfigSnippet(options.agent, server);
95
52
  const dryRun = Boolean(options.dryRun);
96
53
  const print = Boolean(options.print);
97
54
  const shouldWrite = !dryRun && !print;
98
55
  const update = print
99
56
  ? { changed: true }
100
- : target.format === "toml"
101
- ? await upsertCodexConfig(target.path, server, shouldWrite)
102
- : target.format === "json-opencode"
103
- ? await upsertOpencodeConfig(target.path, server, shouldWrite)
104
- : target.format === "json-copilot"
105
- ? await upsertCopilotConfig(target.path, server, shouldWrite)
106
- : target.format === "json-vscode"
107
- ? await upsertVsCodeMcpConfig(target.path, server, shouldWrite)
108
- : options.agent === "gemini"
109
- ? await upsertGeminiExtension(target.path, server, shouldWrite)
110
- : await upsertJsonMcpConfig(target.path, server, shouldWrite);
57
+ : await upsertConfig(spec.format, target.path, server, shouldWrite);
111
58
  return {
112
59
  agent: options.agent,
113
60
  scope: options.scope,
114
61
  path: target.path,
115
62
  serverName: SUMMER_MCP_SERVER_NAME,
116
63
  server,
117
- format: target.format,
64
+ format: spec.format,
118
65
  snippet,
119
66
  changed: update.changed,
120
67
  wrote: shouldWrite && update.changed,
@@ -123,9 +70,24 @@ export async function configureAgentMcp(options) {
123
70
  localDev: Boolean(options.localDev),
124
71
  channel,
125
72
  warnings: target.warnings,
126
- nextSteps: createNextSteps(options.agent, options.scope, target.path),
73
+ nextSteps: [`Updated ${target.path}.`, spec.restart],
127
74
  };
128
75
  }
76
+ async function upsertConfig(format, path, server, write) {
77
+ switch (format) {
78
+ case "toml":
79
+ return upsertCodexConfig(path, server, write);
80
+ case "toml-array":
81
+ return upsertTomlArrayConfig(path, server, write);
82
+ case "json-gemini":
83
+ return upsertGeminiExtension(path, server, write);
84
+ case "yaml-goose":
85
+ case "yaml-hermes":
86
+ return upsertYamlConfig(path, [topLevelKey(format), SUMMER_MCP_SERVER_NAME], mcpEntry(format, server), write);
87
+ default:
88
+ return upsertJsonEntry(path, format, server, write);
89
+ }
90
+ }
129
91
  export const DEFAULT_CHANNEL = "latest";
130
92
  /** npm dist-tags are lowercase words like `latest`, `next`, `beta`, `v3-preview`;
131
93
  * anything that could be read as a version or a path is refused (a bare
@@ -164,39 +126,87 @@ export function createSummerMcpServerConfig(localDev, platform = process.platfor
164
126
  };
165
127
  }
166
128
  export function renderConfigSnippet(agent, server) {
167
- if (agent === "codex") {
129
+ const format = agentSpec(agent).format;
130
+ if (format === "toml")
168
131
  return renderCodexServerTable(server);
169
- }
170
- if (agent === "opencode") {
171
- return (JSON.stringify({
172
- $schema: "https://opencode.ai/config.json",
173
- mcp: {
174
- [SUMMER_MCP_SERVER_NAME]: opencodeServerEntry(server),
175
- },
176
- }, null, 2) + "\n");
177
- }
178
- if (agent === "github-copilot") {
179
- return (JSON.stringify({
180
- mcpServers: {
181
- [SUMMER_MCP_SERVER_NAME]: copilotServerEntry(server),
182
- },
183
- }, null, 2) + "\n");
184
- }
185
- if (agent === "vscode-copilot") {
186
- return (JSON.stringify({
187
- servers: {
188
- [SUMMER_MCP_SERVER_NAME]: vsCodeServerEntry(server),
189
- },
190
- }, null, 2) + "\n");
191
- }
192
- if (agent === "gemini") {
132
+ if (format === "toml-array")
133
+ return renderTomlArrayEntry(server);
134
+ if (format === "json-gemini") {
193
135
  return renderJsonFile(geminiExtensionManifest(server, readBundledGeminiManifestSync()));
194
136
  }
195
- return (JSON.stringify({
196
- mcpServers: {
197
- [SUMMER_MCP_SERVER_NAME]: server,
198
- },
199
- }, null, 2) + "\n");
137
+ if (format === "yaml-goose" || format === "yaml-hermes") {
138
+ const doc = new Document({});
139
+ doc.setIn([topLevelKey(format), SUMMER_MCP_SERVER_NAME], doc.createNode(mcpEntry(format, server)));
140
+ return doc.toString();
141
+ }
142
+ const file = {};
143
+ if (format === "json-opencode" && agent === "opencode")
144
+ file.$schema = OPENCODE_SCHEMA;
145
+ file[topLevelKey(format)] = { [SUMMER_MCP_SERVER_NAME]: mcpEntry(format, server) };
146
+ return renderJsonFile(file);
147
+ }
148
+ const OPENCODE_SCHEMA = "https://opencode.ai/config.json";
149
+ /** The key under which the file lists MCP servers (see McpFormat in agent-table.ts). */
150
+ export function topLevelKey(format) {
151
+ switch (format) {
152
+ case "json-vscode":
153
+ case "json-servers":
154
+ return "servers";
155
+ case "json-opencode":
156
+ case "json-crush":
157
+ return "mcp";
158
+ case "json-zed":
159
+ return "context_servers";
160
+ case "json-amp":
161
+ return "amp.mcpServers";
162
+ case "yaml-goose":
163
+ return "extensions";
164
+ case "yaml-hermes":
165
+ case "toml":
166
+ case "toml-array":
167
+ return "mcp_servers";
168
+ default:
169
+ return "mcpServers";
170
+ }
171
+ }
172
+ /** One server entry in the shape the agent's file expects. */
173
+ export function mcpEntry(format, server) {
174
+ const env = server.env && Object.keys(server.env).length > 0 ? { ...server.env } : undefined;
175
+ switch (format) {
176
+ case "json-opencode":
177
+ return {
178
+ type: "local",
179
+ command: [server.command, ...server.args],
180
+ enabled: true,
181
+ ...(env ? { environment: env } : {}),
182
+ };
183
+ case "json-copilot":
184
+ return { type: "local", command: server.command, args: server.args, tools: ["*"], ...(env ? { env } : {}) };
185
+ case "json-vscode":
186
+ case "json-stdio":
187
+ case "json-crush":
188
+ return { type: "stdio", command: server.command, args: server.args, ...(env ? { env } : {}) };
189
+ case "json-zed":
190
+ return { command: server.command, args: server.args, env: env ?? {} };
191
+ case "json-transport":
192
+ return { command: server.command, args: server.args, transport: "stdio", ...(env ? { env } : {}) };
193
+ case "toml-array":
194
+ return { name: SUMMER_MCP_SERVER_NAME, transport: "stdio", command: server.command, args: server.args, ...(env ? { env } : {}) };
195
+ case "yaml-goose":
196
+ return {
197
+ type: "stdio",
198
+ name: SUMMER_MCP_SERVER_NAME,
199
+ description: "Summer Engine: scenes, scripts, play mode and diagnostics over MCP",
200
+ cmd: server.command,
201
+ args: server.args,
202
+ enabled: true,
203
+ timeout: 300,
204
+ env_keys: [],
205
+ envs: env ?? {},
206
+ };
207
+ default:
208
+ return { command: server.command, args: server.args, ...(env ? { env } : {}) };
209
+ }
200
210
  }
201
211
  function resolveLocalCliPath() {
202
212
  const thisFile = fileURLToPath(import.meta.url);
@@ -210,205 +220,21 @@ export function resolvePackageRoot() {
210
220
  export const GEMINI_EXTENSION_DIR_NAME = "summer-engine";
211
221
  /** Files copied next to the extension manifest so `contextFileName` (GEMINI.md, which imports AGENTS.md) resolves. */
212
222
  const GEMINI_CONTEXT_FILES = ["GEMINI.md", "AGENTS.md"];
213
- function resolveConfigTarget(agent, scope, cwd, env) {
214
- const override = getConfigPathOverride(agent, env);
215
- const warnings = [];
216
- if (override) {
217
- if (scope === "project" &&
218
- (agent === "cline" || agent === "roo-code" || agent === "gemini" || agent === "lm-studio")) {
219
- warnings.push(`${agent} MCP config has no project scope today; treating as user scope.`);
220
- }
221
- return {
222
- path: resolve(override),
223
- format: agent === "codex"
224
- ? "toml"
225
- : agent === "opencode"
226
- ? "json-opencode"
227
- : agent === "github-copilot"
228
- ? "json-copilot"
229
- : agent === "vscode-copilot"
230
- ? "json-vscode"
231
- : "json",
232
- warnings,
233
- };
234
- }
235
- if (agent === "codex") {
236
- return {
237
- path: scope === "user"
238
- ? join(homedir(), ".codex", "config.toml")
239
- : join(cwd, ".codex", "config.toml"),
240
- format: "toml",
241
- warnings,
242
- };
243
- }
244
- if (agent === "claude-code") {
245
- return {
246
- path: scope === "user"
247
- ? join(homedir(), ".claude.json")
248
- : join(cwd, ".mcp.json"),
249
- format: "json",
250
- warnings,
251
- };
252
- }
253
- if (agent === "cursor") {
254
- return {
255
- path: scope === "user"
256
- ? join(homedir(), ".cursor", "mcp.json")
257
- : join(cwd, ".cursor", "mcp.json"),
258
- format: "json",
259
- warnings,
260
- };
261
- }
262
- if (agent === "cline") {
263
- if (scope === "project") {
264
- warnings.push("Cline MCP config has no project scope today; writing to user-scope global VS Code storage instead.");
265
- }
266
- return {
267
- path: vsCodeGlobalStoragePath(env, "saoudrizwan.claude-dev"),
268
- format: "json",
269
- warnings,
270
- };
271
- }
272
- if (agent === "roo-code") {
273
- if (scope === "project") {
274
- warnings.push("Roo Code MCP config has no project scope today; writing to user-scope global VS Code storage instead.");
275
- }
276
- return {
277
- path: vsCodeGlobalStoragePath(env, "rooveterinaryinc.roo-cline"),
278
- format: "json",
279
- warnings,
280
- };
281
- }
282
- if (agent === "kilo-code") {
283
- return {
284
- path: scope === "user"
285
- ? vsCodeGlobalStoragePath(env, "kilocode.kilo-code", "mcp_settings.json")
286
- : join(cwd, ".kilocode", "mcp.json"),
287
- format: "json",
288
- warnings,
289
- };
290
- }
291
- if (agent === "lm-studio") {
292
- if (scope === "project") {
293
- warnings.push("LM Studio's MCP config is app-global (~/.lmstudio/mcp.json); treating as user scope.");
294
- }
295
- return {
296
- path: join(homedir(), ".lmstudio", "mcp.json"),
297
- format: "json",
298
- warnings,
299
- };
300
- }
301
- if (agent === "gemini") {
302
- if (scope === "project") {
303
- warnings.push("Gemini extensions are user-scoped today; writing to ~/.gemini/extensions/summer-engine/ instead of project.");
304
- }
305
- return {
306
- path: join(homedir(), ".gemini", "extensions", "summer-engine", "gemini-extension.json"),
307
- format: "json",
308
- warnings,
309
- };
310
- }
311
- if (agent === "github-copilot") {
312
- return {
313
- path: scope === "user"
314
- ? join(homedir(), ".copilot", "mcp-config.json")
315
- : join(cwd, ".mcp.json"),
316
- format: "json-copilot",
317
- warnings,
318
- };
319
- }
320
- if (agent === "vscode-copilot") {
321
- return {
322
- path: scope === "user"
323
- ? vsCodeUserMcpPath(env)
324
- : join(cwd, ".vscode", "mcp.json"),
325
- format: "json-vscode",
326
- warnings,
327
- };
328
- }
329
- if (agent === "opencode") {
330
- return {
331
- path: scope === "user"
332
- ? opencodeUserConfigPath(env)
333
- : join(cwd, "opencode.json"),
334
- format: "json-opencode",
335
- warnings,
336
- };
337
- }
338
- if (scope === "project") {
339
- warnings.push("Devin Desktop (formerly Windsurf) documents MCP configuration as user-scoped; project scope writes .windsurf/mcp_config.json for teams that load workspace config.");
340
- }
341
- return {
342
- path: scope === "user"
343
- ? join(homedir(), ".codeium", "windsurf", "mcp_config.json")
344
- : join(cwd, ".windsurf", "mcp_config.json"),
345
- format: "json",
346
- warnings,
347
- };
223
+ function resolveConfigTarget(spec, scope, cwd, env) {
224
+ const resolved = resolveMcpPath(spec, scope, defaultPathContext(env, cwd));
225
+ const override = env[spec.envOverride];
226
+ return { path: override ? resolve(override) : resolved.path, warnings: resolved.warnings };
348
227
  }
349
- function vsCodeGlobalStoragePath(env, extensionId, fileName = "cline_mcp_settings.json") {
350
- const os = platform();
351
- if (os === "win32") {
352
- const appData = env.APPDATA ?? join(homedir(), "AppData", "Roaming");
353
- return join(appData, "Code", "User", "globalStorage", extensionId, "settings", fileName);
354
- }
355
- if (os === "darwin") {
356
- return join(homedir(), "Library", "Application Support", "Code", "User", "globalStorage", extensionId, "settings", fileName);
357
- }
358
- // Linux and other Unix
359
- const xdg = env.XDG_CONFIG_HOME ?? join(homedir(), ".config");
360
- return join(xdg, "Code", "User", "globalStorage", extensionId, "settings", fileName);
361
- }
362
- function opencodeUserConfigPath(env) {
363
- const os = platform();
364
- if (os === "win32") {
365
- const appData = env.APPDATA ?? join(homedir(), "AppData", "Roaming");
366
- return join(appData, "opencode", "opencode.json");
367
- }
368
- const xdg = env.XDG_CONFIG_HOME ?? join(homedir(), ".config");
369
- return join(xdg, "opencode", "opencode.json");
370
- }
371
- function vsCodeUserMcpPath(env) {
372
- const os = platform();
373
- if (os === "win32") {
374
- const appData = env.APPDATA ?? join(homedir(), "AppData", "Roaming");
375
- return join(appData, "Code", "User", "mcp.json");
376
- }
377
- if (os === "darwin") {
378
- return join(homedir(), "Library", "Application Support", "Code", "User", "mcp.json");
379
- }
380
- const xdg = env.XDG_CONFIG_HOME ?? join(homedir(), ".config");
381
- return join(xdg, "Code", "User", "mcp.json");
382
- }
383
- function getConfigPathOverride(agent, env) {
384
- if (agent === "codex")
385
- return env.SUMMER_CODEX_CONFIG_FILE;
386
- if (agent === "claude-code")
387
- return env.SUMMER_CLAUDE_CONFIG_FILE;
388
- if (agent === "cursor")
389
- return env.SUMMER_CURSOR_MCP_CONFIG_FILE;
390
- if (agent === "cline")
391
- return env.SUMMER_CLINE_CONFIG_FILE;
392
- if (agent === "roo-code")
393
- return env.SUMMER_ROO_CODE_CONFIG_FILE;
394
- if (agent === "kilo-code")
395
- return env.SUMMER_KILO_CODE_CONFIG_FILE;
396
- if (agent === "lm-studio")
397
- return env.SUMMER_LM_STUDIO_CONFIG_FILE;
398
- if (agent === "gemini")
399
- return env.SUMMER_GEMINI_CONFIG_FILE;
400
- if (agent === "github-copilot")
401
- return env.SUMMER_GITHUB_COPILOT_CONFIG_FILE;
402
- if (agent === "vscode-copilot")
403
- return env.SUMMER_VSCODE_COPILOT_CONFIG_FILE;
404
- if (agent === "opencode")
405
- return env.SUMMER_OPENCODE_CONFIG_FILE;
406
- return env.SUMMER_WINDSURF_MCP_CONFIG_FILE;
407
- }
408
- async function upsertJsonMcpConfig(path, server, write) {
228
+ /** Merge one server entry into a JSON config file under the format's top-level key. */
229
+ async function upsertJsonEntry(path, format, server, write) {
409
230
  const current = await readJsonConfig(path);
410
231
  const next = copyJsonObject(current);
411
- next.mcpServers = mergeMcpServers(next.mcpServers, server);
232
+ const key = topLevelKey(format);
233
+ // OpenCode's file carries its schema; Kilo shares the shape but has its own.
234
+ if (format === "json-opencode" && typeof next.$schema !== "string" && /opencode\.json$/.test(path)) {
235
+ next.$schema = OPENCODE_SCHEMA;
236
+ }
237
+ next[key] = mergeNamedObject(next[key], SUMMER_MCP_SERVER_NAME, mcpEntry(format, server), key);
412
238
  const currentRendered = renderJsonFile(current);
413
239
  const nextRendered = renderJsonFile(next);
414
240
  const changed = currentRendered !== nextRendered;
@@ -417,14 +243,33 @@ async function upsertJsonMcpConfig(path, server, write) {
417
243
  }
418
244
  return { changed };
419
245
  }
420
- function mergeMcpServers(value, server) {
421
- if (value !== undefined && !isJsonObject(value)) {
422
- throw new Error("Existing mcpServers value must be a JSON object.");
246
+ /**
247
+ * Merge one server entry into a YAML config (Goose, Hermes). Uses the yaml
248
+ * Document API so the user's comments and ordering survive; only the
249
+ * summer-engine node is replaced.
250
+ */
251
+ async function upsertYamlConfig(path, keyPath, entry, write) {
252
+ const current = await readTextFileIfExists(path);
253
+ // An empty file starts from a fresh block-style document; parseDocument("{}")
254
+ // would make the root a flow mapping and the whole file would render as {}.
255
+ const doc = current.trim() === "" ? new Document({}) : parseDocument(current);
256
+ if (doc.errors.length > 0) {
257
+ throw new Error(`Could not parse YAML in ${path}: ${doc.errors[0].message}`);
423
258
  }
424
- return {
425
- ...(isJsonObject(value) ? value : {}),
426
- [SUMMER_MCP_SERVER_NAME]: server,
427
- };
259
+ if (!isMap(doc.contents)) {
260
+ throw new Error(`Expected ${path} to contain a YAML mapping.`);
261
+ }
262
+ const parent = doc.getIn(keyPath.slice(0, -1));
263
+ if (parent !== undefined && parent !== null && !isMap(parent)) {
264
+ throw new Error(`Existing ${keyPath[0]} value in ${path} must be a mapping.`);
265
+ }
266
+ doc.setIn(keyPath, doc.createNode(entry));
267
+ const next = doc.toString();
268
+ const changed = current !== next;
269
+ if (write && changed) {
270
+ await writeTextFile(path, next);
271
+ }
272
+ return { changed };
428
273
  }
429
274
  async function readJsonConfig(path) {
430
275
  if (!existsSync(path))
@@ -459,48 +304,67 @@ async function upsertCodexConfig(path, server, write) {
459
304
  }
460
305
  return { changed };
461
306
  }
462
- async function upsertOpencodeConfig(path, server, write) {
463
- const current = await readJsonConfig(path);
464
- const next = copyJsonObject(current);
465
- if (typeof next.$schema !== "string") {
466
- next.$schema = "https://opencode.ai/config.json";
467
- }
468
- const existingMcp = isJsonObject(next.mcp) ? next.mcp : {};
469
- next.mcp = {
470
- ...existingMcp,
471
- [SUMMER_MCP_SERVER_NAME]: opencodeServerEntry(server),
472
- };
473
- const currentRendered = renderJsonFile(current);
474
- const nextRendered = renderJsonFile(next);
475
- const changed = currentRendered !== nextRendered;
307
+ /**
308
+ * Mistral Vibe lists servers as a TOML array of tables:
309
+ * [[mcp_servers]]
310
+ * name = "summer-engine"
311
+ * ...
312
+ * Replace the block whose name is ours, else append one.
313
+ */
314
+ async function upsertTomlArrayConfig(path, server, write) {
315
+ const current = await readTextFileIfExists(path);
316
+ const next = upsertTomlArrayBlock(current, renderTomlArrayEntry(server));
317
+ const changed = current !== next;
476
318
  if (write && changed) {
477
- await writeTextFile(path, nextRendered);
319
+ await writeTextFile(path, next);
478
320
  }
479
321
  return { changed };
480
322
  }
481
- async function upsertCopilotConfig(path, server, write) {
482
- const current = await readJsonConfig(path);
483
- const next = copyJsonObject(current);
484
- next.mcpServers = mergeNamedObject(next.mcpServers, SUMMER_MCP_SERVER_NAME, copilotServerEntry(server), "mcpServers");
485
- const currentRendered = renderJsonFile(current);
486
- const nextRendered = renderJsonFile(next);
487
- const changed = currentRendered !== nextRendered;
488
- if (write && changed) {
489
- await writeTextFile(path, nextRendered);
323
+ export function upsertTomlArrayBlock(content, block) {
324
+ const lines = content.split(/\r?\n/);
325
+ const header = /^\s*\[\[mcp_servers\]\]\s*(?:#.*)?$/;
326
+ const nameLine = new RegExp(`^\\s*name\\s*=\\s*"${SUMMER_MCP_SERVER_NAME}"\\s*(?:#.*)?$`);
327
+ let start = -1;
328
+ let end = lines.length;
329
+ for (let index = 0; index < lines.length; index += 1) {
330
+ if (!header.test(lines[index]))
331
+ continue;
332
+ let blockEnd = lines.length;
333
+ for (let inner = index + 1; inner < lines.length; inner += 1) {
334
+ if (/^\s*\[/.test(lines[inner])) {
335
+ blockEnd = inner;
336
+ break;
337
+ }
338
+ }
339
+ if (lines.slice(index + 1, blockEnd).some((line) => nameLine.test(line))) {
340
+ start = index;
341
+ end = blockEnd;
342
+ break;
343
+ }
490
344
  }
491
- return { changed };
345
+ if (start === -1) {
346
+ const trimmed = content.endsWith("\n") || content === "" ? content : `${content}\n`;
347
+ return `${trimmed}${trimmed === "" ? "" : "\n"}${block}`;
348
+ }
349
+ const replacement = block.trimEnd().split("\n");
350
+ if (lines[end] && lines[end].trim() !== "")
351
+ replacement.push("");
352
+ return ensureTrailingNewline([...lines.slice(0, start), ...replacement, ...lines.slice(end)].join("\n"));
492
353
  }
493
- async function upsertVsCodeMcpConfig(path, server, write) {
494
- const current = await readJsonConfig(path);
495
- const next = copyJsonObject(current);
496
- next.servers = mergeNamedObject(next.servers, SUMMER_MCP_SERVER_NAME, vsCodeServerEntry(server), "servers");
497
- const currentRendered = renderJsonFile(current);
498
- const nextRendered = renderJsonFile(next);
499
- const changed = currentRendered !== nextRendered;
500
- if (write && changed) {
501
- await writeTextFile(path, nextRendered);
354
+ function renderTomlArrayEntry(server) {
355
+ const lines = [
356
+ "[[mcp_servers]]",
357
+ `name = ${tomlString(SUMMER_MCP_SERVER_NAME)}`,
358
+ `transport = "stdio"`,
359
+ `command = ${tomlString(server.command)}`,
360
+ `args = [${server.args.map(tomlString).join(", ")}]`,
361
+ ];
362
+ if (server.env && Object.keys(server.env).length > 0) {
363
+ lines.push(`env = { ${Object.entries(server.env)
364
+ .map(([key, value]) => `${key} = ${tomlString(value)}`)
365
+ .join(", ")} }`);
502
366
  }
503
- return { changed };
367
+ return `${lines.join("\n")}\n`;
504
368
  }
505
369
  async function upsertGeminiExtension(path, server, write) {
506
370
  const current = await readJsonConfig(path);
@@ -596,39 +460,6 @@ function geminiExtensionManifest(server, bundled, base = {}) {
596
460
  };
597
461
  return manifest;
598
462
  }
599
- function opencodeServerEntry(server) {
600
- const entry = {
601
- type: "local",
602
- command: [server.command, ...server.args],
603
- };
604
- if (server.env && Object.keys(server.env).length > 0) {
605
- entry.environment = { ...server.env };
606
- }
607
- return entry;
608
- }
609
- function copilotServerEntry(server) {
610
- const entry = {
611
- type: "local",
612
- command: server.command,
613
- args: server.args,
614
- tools: ["*"],
615
- };
616
- if (server.env && Object.keys(server.env).length > 0) {
617
- entry.env = { ...server.env };
618
- }
619
- return entry;
620
- }
621
- function vsCodeServerEntry(server) {
622
- const entry = {
623
- type: "stdio",
624
- command: server.command,
625
- args: server.args,
626
- };
627
- if (server.env && Object.keys(server.env).length > 0) {
628
- entry.env = { ...server.env };
629
- }
630
- return entry;
631
- }
632
463
  async function readTextFileIfExists(path) {
633
464
  if (!existsSync(path))
634
465
  return "";
@@ -706,35 +537,6 @@ async function writeTextFile(path, content) {
706
537
  function ensureTrailingNewline(value) {
707
538
  return value.endsWith("\n") ? value : `${value}\n`;
708
539
  }
709
- function createNextSteps(agent, scope, path) {
710
- const restart = agent === "claude-code"
711
- ? "Restart Claude Code or run /mcp in a new session."
712
- : agent === "codex"
713
- ? "Restart Codex or run /mcp in a new session."
714
- : agent === "cursor"
715
- ? "Restart Cursor and enable the summer-engine MCP server if prompted."
716
- : agent === "cline"
717
- ? "Restart VS Code so Cline reloads its MCP config."
718
- : agent === "roo-code"
719
- ? "Restart VS Code so Roo Code reloads its MCP config."
720
- : agent === "kilo-code"
721
- ? "Restart VS Code so Kilo Code reloads its MCP config."
722
- : agent === "lm-studio"
723
- ? "Open LM Studio, toggle on the summer-engine MCP server in the Program tab, and raise the loaded model's context length to 32k or higher."
724
- : agent === "gemini"
725
- ? "Run `summer skills install --all --agent gemini` if skills were not installed, then restart Gemini CLI (or `gemini extensions enable summer-engine` if it is disabled)."
726
- : agent === "github-copilot"
727
- ? "Restart Copilot CLI, or run /mcp reload and /skills reload in the active session."
728
- : agent === "vscode-copilot"
729
- ? "Restart VS Code or run MCP: List Servers, then start summer-engine in Copilot Agent mode."
730
- : agent === "opencode"
731
- ? "Restart OpenCode so it reloads opencode.json."
732
- : "Restart Devin Desktop (formerly Windsurf) and refresh MCP servers from the agent settings.";
733
- const projectTrust = scope === "project" && agent === "codex"
734
- ? "Codex only loads project .codex/config.toml from trusted projects."
735
- : null;
736
- return [projectTrust, `Updated ${path}.`, restart].filter((step) => Boolean(step));
737
- }
738
540
  function formatError(error) {
739
541
  return error instanceof Error ? error.message : String(error);
740
542
  }