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
@@ -1,11 +1,15 @@
1
1
  import { z } from "zod";
2
- import { type LibrarySearchDeps } from "./library-search.js";
2
+ import { type LibraryIndexEntry, type LibrarySearchDeps } from "./library-search.js";
3
3
  import { type TemplateEntry } from "./templates.js";
4
4
  export declare const READ_PARTS: readonly ["skill", "resource", "all"];
5
5
  export type ReadPart = (typeof READ_PARTS)[number];
6
6
  /** How many content_hash hex chars the footer's entry_id carries. */
7
7
  export declare const FOOTER_HASH_LENGTH = 12;
8
8
  export declare const FOOTER_SUFFIX = "If this entry is wrong, stale, or you deviate from it, report via summer_library_feedback.";
9
+ /** Text files read_library loads when an entry links them. */
10
+ export declare const LINKED_FILE_EXTENSIONS: ReadonlySet<string>;
11
+ /** A linked file larger than this is refused rather than dumped. */
12
+ export declare const LINKED_FILE_MAX_BYTES: number;
9
13
  export declare const readLibraryInputShape: {
10
14
  id: z.ZodString;
11
15
  part: z.ZodOptional<z.ZodEnum<["skill", "resource", "all"]>>;
@@ -15,10 +19,10 @@ export declare const readLibraryInputSchema: z.ZodObject<{
15
19
  part: z.ZodOptional<z.ZodEnum<["skill", "resource", "all"]>>;
16
20
  }, "strict", z.ZodTypeAny, {
17
21
  id: string;
18
- part?: "all" | "skill" | "resource" | undefined;
22
+ part?: "all" | "resource" | "skill" | undefined;
19
23
  }, {
20
24
  id: string;
21
- part?: "all" | "skill" | "resource" | undefined;
25
+ part?: "all" | "resource" | "skill" | undefined;
22
26
  }>;
23
27
  export type ReadLibraryArgs = z.infer<typeof readLibraryInputSchema>;
24
28
  export interface LibraryReadDeps extends LibrarySearchDeps {
@@ -44,6 +48,15 @@ export interface LibraryReadOk {
44
48
  files: string[];
45
49
  /** The file the body came from, when the body is a file. */
46
50
  body_file?: string;
51
+ /** Set when the load is a file the entry ships rather than the entry body:
52
+ * its path inside the entry directory, e.g. "references/kit-placement-tools.md". */
53
+ linked_file?: string;
54
+ /** Relative links in the body and the summer_read_library id that loads
55
+ * each (null: the target is not shipped with this package). */
56
+ links?: Array<{
57
+ target: string;
58
+ id: string | null;
59
+ }>;
47
60
  /** Tool records: how to reach it. */
48
61
  mcp_tool_name?: string;
49
62
  cli_command?: string;
@@ -67,7 +80,26 @@ export type LibraryReadResult = LibraryReadOk | LibraryReadNotFound;
67
80
  export declare function feedbackFooter(id: string, contentHash: string | undefined): string;
68
81
  export declare function entryIdWithHash(id: string, contentHash: string | undefined): string;
69
82
  /**
70
- * Read one entry. `deps.entries`/`deps.packageRoot`/`deps.templates` let
71
- * tests point at a fixture; production reads the installed package.
83
+ * Relative link targets in a markdown body: markdown links outside code
84
+ * (`[x](references/y.md)`, fragment dropped) and inline code spans that name a
85
+ * library file by a relative path (`../../references/gd-style/gd-style.md`,
86
+ * `references/y.md`; a `./scripts/x.gd` span is a project path and is not
87
+ * one). URLs, anchors, absolute paths and fenced code blocks are skipped.
88
+ * Exported for the every-link-resolves test.
89
+ */
90
+ export declare function relativeLinkTargets(markdown: string): string[];
91
+ /**
92
+ * Where a link written in `fromFile` (a path inside `entry`'s directory, ""
93
+ * or "SKILL.md" for the body) points, as the id summer_read_library loads it
94
+ * by; null when the target is not shipped inside library/.
95
+ */
96
+ export declare function resolveLibraryLink(entry: LibraryIndexEntry, fromFile: string, link: string, deps: {
97
+ entries: LibraryIndexEntry[];
98
+ packageRoot?: string;
99
+ }): string | null;
100
+ /**
101
+ * Read one entry, or a file an entry links. `deps.entries`/`deps.packageRoot`/
102
+ * `deps.templates` let tests point at a fixture; production reads the
103
+ * installed package.
72
104
  */
73
105
  export declare function readLibraryEntry(requestedId: string, part?: ReadPart, deps?: LibraryReadDeps): Promise<LibraryReadResult>;
@@ -23,9 +23,18 @@
23
23
  * Metadata comes from registry/generated/index.json (no YAML parser at
24
24
  * runtime); resource.yaml is returned as text. Unknown id -> not_found with
25
25
  * the three nearest ids from searchLibrary.
26
+ *
27
+ * Linked files: a body links files its entry ships (a skill's
28
+ * `references/kit-placement-tools.md`) and other entries
29
+ * (`../multiplayer-project/SKILL.md`, `../../references/gd-style/gd-style.md`).
30
+ * Each loads by `<entry id>/<link as written>`, resolved inside library/ only
31
+ * and for text files only; by the relative path alone when exactly one entry
32
+ * ships it; and `reference/<slug>` that is no entry falls back to the one
33
+ * `references/<slug>.md` an entry ships. A body render ends with its links and
34
+ * the id that loads each. A linked file's footer names its entry.
26
35
  */
27
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
28
- import { join } from "node:path";
36
+ import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
37
+ import { join, posix, sep } from "node:path";
29
38
  import { z } from "zod";
30
39
  import { LIBRARY_KIND_DIRS, loadLibraryIndex, searchLibrary, } from "./library-search.js";
31
40
  import { PACKAGE_ROOT } from "./package-root.js";
@@ -34,12 +43,30 @@ export const READ_PARTS = ["skill", "resource", "all"];
34
43
  /** How many content_hash hex chars the footer's entry_id carries. */
35
44
  export const FOOTER_HASH_LENGTH = 12;
36
45
  export const FOOTER_SUFFIX = "If this entry is wrong, stale, or you deviate from it, report via summer_library_feedback.";
46
+ /** Text files read_library loads when an entry links them. */
47
+ export const LINKED_FILE_EXTENSIONS = new Set([
48
+ ".md",
49
+ ".markdown",
50
+ ".txt",
51
+ ".yaml",
52
+ ".yml",
53
+ ".json",
54
+ ".gd",
55
+ ".gdshader",
56
+ ".shader",
57
+ ".cfg",
58
+ ".tscn",
59
+ ".tres",
60
+ ".csv",
61
+ ]);
62
+ /** A linked file larger than this is refused rather than dumped. */
63
+ export const LINKED_FILE_MAX_BYTES = 256 * 1024;
37
64
  export const readLibraryInputShape = {
38
65
  id: z
39
66
  .string()
40
67
  .min(1)
41
68
  .max(200)
42
- .describe("The entry id as returned by summer_search_library: <kind>/<slug>, e.g. skill/vfx-water-ripple or tool/screenshot."),
69
+ .describe("The entry id as returned by summer_search_library: <kind>/<slug>, e.g. skill/vfx-water-ripple or tool/screenshot. A file an entry links loads by <entry id>/<link as written>, e.g. skill/spatial-placement/references/kit-placement-tools.md; the 'linked files' list at the end of a body gives each id."),
43
70
  part: z
44
71
  .enum(READ_PARTS)
45
72
  .optional()
@@ -71,6 +98,111 @@ function resolveEntry(requested, entries) {
71
98
  }
72
99
  return null;
73
100
  }
101
+ const KIND_BY_DIR = new Map(Object.entries(LIBRARY_KIND_DIRS).map(([kind, dir]) => [dir, kind]));
102
+ const ENTRY_PATH_ID = /^(tool|skill|example|template|collection|reference)\/([a-z0-9]+(?:-[a-z0-9]+)*)\/(.+)$/;
103
+ function entryDirOf(entry) {
104
+ const kind = entry.kind;
105
+ return `library/${LIBRARY_KIND_DIRS[kind] ?? `${kind}s`}/${entry.id.split("/").pop()}`;
106
+ }
107
+ /** Join a link onto a package-relative directory; null when it is absolute,
108
+ * malformed, or leaves library/. */
109
+ function joinInsideLibrary(baseDir, link) {
110
+ let decoded;
111
+ try {
112
+ decoded = decodeURIComponent(link.trim());
113
+ }
114
+ catch {
115
+ return null;
116
+ }
117
+ if (!decoded || /[\u0000-\u001f\\]/.test(decoded) || decoded.startsWith("/") || /^[a-z][a-z0-9+.-]*:/i.test(decoded))
118
+ return null;
119
+ const joined = posix.normalize(posix.join(baseDir, decoded)).replace(/\/+$/, "");
120
+ return joined === "library" || joined.startsWith("library/") ? joined : null;
121
+ }
122
+ /** library/<dir>/<slug>[/<file>] -> the entry and the file inside it. */
123
+ function targetFromLibraryPath(libPath, entries) {
124
+ const parts = libPath.split("/");
125
+ if (parts.length < 3 || parts[0] !== "library")
126
+ return null;
127
+ const kind = KIND_BY_DIR.get(parts[1]);
128
+ if (!kind)
129
+ return null;
130
+ const entry = entries.find((e) => e.id === `${kind}/${parts[2]}`);
131
+ return entry ? { entry, file: parts.slice(3).join("/") } : null;
132
+ }
133
+ function isFileInsideLibrary(root, libPath) {
134
+ const abs = join(root, ...libPath.split("/"));
135
+ try {
136
+ if (!statSync(abs).isFile())
137
+ return false;
138
+ const libraryRoot = realpathSync(join(root, "library"));
139
+ return realpathSync(abs).startsWith(libraryRoot + sep);
140
+ }
141
+ catch {
142
+ return false;
143
+ }
144
+ }
145
+ /** Resolve an id that names a file an entry ships (see the module comment). */
146
+ function resolveLinkedFile(requested, entries, root) {
147
+ const bare = requested.trim();
148
+ const qualified = ENTRY_PATH_ID.exec(bare);
149
+ if (qualified) {
150
+ const entry = entries.find((e) => e.id === `${qualified[1]}/${qualified[2]}`);
151
+ if (entry) {
152
+ const libPath = joinInsideLibrary(entryDirOf(entry), qualified[3]);
153
+ const target = libPath ? targetFromLibraryPath(libPath, entries) : null;
154
+ if (!target || (target.file !== "" && !isFileInsideLibrary(root, libPath)))
155
+ return null;
156
+ return target;
157
+ }
158
+ }
159
+ const shipping = (relative) => entries
160
+ .map((entry) => ({ entry, libPath: joinInsideLibrary(entryDirOf(entry), relative) }))
161
+ .filter((c) => !!c.libPath && c.libPath.startsWith(`${entryDirOf(c.entry)}/`))
162
+ .filter((c) => isFileInsideLibrary(root, c.libPath))
163
+ .map((c) => ({ entry: c.entry, file: c.libPath.slice(entryDirOf(c.entry).length + 1) }));
164
+ // A relative path alone, when exactly one entry ships that file.
165
+ if ((bare.includes("/") || /\.[a-z0-9]+$/i.test(bare)) && !bare.startsWith("../")) {
166
+ const found = shipping(bare.replace(/^\.\//, ""));
167
+ if (found.length === 1)
168
+ return found[0];
169
+ }
170
+ // reference/<slug> that is no entry: the references/<slug>.md one entry ships.
171
+ const asReference = /^references?\/([a-z0-9]+(?:[-_][a-z0-9]+)*)(?:\.md)?$/.exec(bare);
172
+ if (asReference) {
173
+ const found = shipping(`references/${asReference[1]}.md`);
174
+ if (found.length === 1)
175
+ return found[0];
176
+ }
177
+ return null;
178
+ }
179
+ /**
180
+ * Relative link targets in a markdown body: markdown links outside code
181
+ * (`[x](references/y.md)`, fragment dropped) and inline code spans that name a
182
+ * library file by a relative path (`../../references/gd-style/gd-style.md`,
183
+ * `references/y.md`; a `./scripts/x.gd` span is a project path and is not
184
+ * one). URLs, anchors, absolute paths and fenced code blocks are skipped.
185
+ * Exported for the every-link-resolves test.
186
+ */
187
+ export function relativeLinkTargets(markdown) {
188
+ const out = new Set();
189
+ const text = markdown.replace(/^(```|~~~)[^\n]*\n[\s\S]*?^\1[^\n]*$/gm, "");
190
+ for (const match of text.matchAll(/`([^`\n]+)`/g)) {
191
+ const span = match[1].trim();
192
+ if (/^((\.\.\/)+|(\.\/)?references\/)[^\s*?<>|]+\.[A-Za-z0-9]+$/.test(span))
193
+ out.add(span);
194
+ }
195
+ const prose = text.replace(/`[^`\n]*`/g, "");
196
+ for (const match of prose.matchAll(/\]\(\s*<?([^)\s>]+)>?(?:\s+"[^"]*")?\s*\)/g)) {
197
+ const target = match[1];
198
+ if (target.startsWith("#") || target.startsWith("/") || /^[a-z][a-z0-9+.-]*:/i.test(target))
199
+ continue;
200
+ const path = target.split("#")[0];
201
+ if (path)
202
+ out.add(path);
203
+ }
204
+ return [...out];
205
+ }
74
206
  // ── Rendering ──────────────────────────────────────────────────────────────
75
207
  function readText(file) {
76
208
  try {
@@ -109,6 +241,41 @@ function pickBodyFile(kind, slug, dir) {
109
241
  return null;
110
242
  }
111
243
  }
244
+ /** The summer_read_library id that loads a target: the entry id for the
245
+ * entry itself or its body file, else <entry id>/<file>. */
246
+ function canonicalId(target, root) {
247
+ if (target.file === "")
248
+ return target.entry.id;
249
+ const slug = target.entry.id.split("/").pop();
250
+ const body = pickBodyFile(target.entry.kind, slug, join(root, ...entryDirOf(target.entry).split("/")));
251
+ return target.file === body ? target.entry.id : `${target.entry.id}/${target.file}`;
252
+ }
253
+ /**
254
+ * Where a link written in `fromFile` (a path inside `entry`'s directory, ""
255
+ * or "SKILL.md" for the body) points, as the id summer_read_library loads it
256
+ * by; null when the target is not shipped inside library/.
257
+ */
258
+ export function resolveLibraryLink(entry, fromFile, link, deps) {
259
+ const root = deps.packageRoot ?? PACKAGE_ROOT;
260
+ const libPath = joinInsideLibrary(posix.dirname(posix.join(entryDirOf(entry), fromFile || "_")), link);
261
+ if (!libPath)
262
+ return null;
263
+ const target = targetFromLibraryPath(libPath, deps.entries);
264
+ if (!target)
265
+ return null;
266
+ if (target.file !== "" && !isFileInsideLibrary(root, libPath))
267
+ return null;
268
+ return canonicalId(target, root);
269
+ }
270
+ function linksOf(body, entry, fromFile, entries, root) {
271
+ return relativeLinkTargets(body).map((target) => ({ target, id: resolveLibraryLink(entry, fromFile, target, { entries, packageRoot: root }) }));
272
+ }
273
+ function linksSection(links) {
274
+ const lines = ["--- linked files (load each with summer_read_library and the id after the arrow) ---"];
275
+ for (const link of links)
276
+ lines.push(`${link.target} -> ${link.id ?? "(not shipped with this package)"}`);
277
+ return lines.join("\n");
278
+ }
112
279
  function toolBody(entry, slug) {
113
280
  const lines = [];
114
281
  const mcpName = entry.mcp_tool_name ?? `summer_${slug.replace(/-/g, "_")}`;
@@ -179,36 +346,112 @@ function header(entry, slug, related) {
179
346
  }
180
347
  // ── Entry point ────────────────────────────────────────────────────────────
181
348
  /**
182
- * Read one entry. `deps.entries`/`deps.packageRoot`/`deps.templates` let
183
- * tests point at a fixture; production reads the installed package.
349
+ * Read one entry, or a file an entry links. `deps.entries`/`deps.packageRoot`/
350
+ * `deps.templates` let tests point at a fixture; production reads the
351
+ * installed package.
184
352
  */
185
353
  export async function readLibraryEntry(requestedId, part = "all", deps = {}) {
186
354
  const entries = deps.entries ?? loadLibraryIndex();
187
355
  const root = deps.packageRoot ?? PACKAGE_ROOT;
188
- const entry = resolveEntry(requestedId, entries);
356
+ let entry = resolveEntry(requestedId, entries);
357
+ let linkedFile;
189
358
  if (!entry) {
190
- const query = requestedId.replace(/[/@_-]+/g, " ").replace(/[a-f0-9]{8,}/gi, " ").trim() || requestedId;
359
+ const target = resolveLinkedFile(requestedId, entries, root);
360
+ if (target) {
361
+ entry = target.entry;
362
+ const canonical = canonicalId(target, root);
363
+ // The entry's own body file and resource.yaml render as the entry.
364
+ if (target.file === "resource.yaml")
365
+ part = "resource";
366
+ else if (canonical !== entry.id)
367
+ linkedFile = target.file;
368
+ }
369
+ }
370
+ if (!entry) {
371
+ const query = requestedId.replace(/[/@_.-]+/g, " ").replace(/[a-f0-9]{8,}/gi, " ").replace(/\bmd\b/g, " ").trim() || requestedId;
191
372
  const nearest = (await searchLibrary(query, { limit: 3 }, deps)).map((hit) => hit.id);
192
373
  return {
193
374
  ok: false,
194
375
  error: "not_found",
195
376
  id: requestedId,
196
377
  nearest,
197
- hint: nearest.length > 0
378
+ hint: (nearest.length > 0
198
379
  ? `No library entry has id "${requestedId}". Nearest by search: ${nearest.join(", ")}. Ids are <kind>/<slug>; use summer_search_library to find the right one.`
199
- : `No library entry has id "${requestedId}" and nothing similar was found. Ids are <kind>/<slug>; use summer_search_library.`,
380
+ : `No library entry has id "${requestedId}" and nothing similar was found. Ids are <kind>/<slug>; use summer_search_library.`) +
381
+ " A file an entry links loads by <entry id>/<link as written> (inside library/ only).",
200
382
  };
201
383
  }
202
384
  const kind = entry.kind;
203
385
  const slug = entry.id.split("/").pop();
204
- const kindDir = LIBRARY_KIND_DIRS[kind] ?? `${kind}s`;
205
- const relPath = `library/${kindDir}/${slug}`;
206
- const dir = join(root, "library", kindDir, slug);
386
+ const relPath = entryDirOf(entry);
387
+ const dir = join(root, ...relPath.split("/"));
207
388
  const files = listFiles(dir);
208
389
  const related = relatedMap(entry);
390
+ const footer = feedbackFooter(entry.id, entry.content_hash);
391
+ const resourceYaml = readText(join(dir, "resource.yaml"))?.replace(/\s+$/, "") ?? "(resource.yaml not found in this install)";
392
+ const base = {
393
+ ok: true,
394
+ id: entry.id,
395
+ kind: entry.kind,
396
+ slug,
397
+ version: entry.version ?? "",
398
+ status: entry.status ?? "stable",
399
+ content_hash: entry.content_hash ?? "",
400
+ summary: entry.summary ?? "",
401
+ use_when: Array.isArray(entry.use_when) ? entry.use_when : [],
402
+ related,
403
+ part,
404
+ path: relPath,
405
+ files,
406
+ entry_id: entryIdWithHash(entry.id, entry.content_hash),
407
+ footer,
408
+ };
409
+ if (linkedFile !== undefined) {
410
+ const libPath = `${relPath}/${linkedFile}`;
411
+ const extension = posix.extname(linkedFile).toLowerCase();
412
+ const size = (() => {
413
+ try {
414
+ return statSync(join(root, ...libPath.split("/"))).size;
415
+ }
416
+ catch {
417
+ return Number.POSITIVE_INFINITY;
418
+ }
419
+ })();
420
+ const sections = [
421
+ `${entry.id}/${linkedFile} — a file shipped with ${entry.id} (${entry.kind} v${entry.version ?? "?"}, ${entry.status ?? "stable"}). The entry itself: summer_read_library id "${entry.id}".`,
422
+ ];
423
+ let links = [];
424
+ if (part === "resource") {
425
+ sections.push(`--- ${relPath}/resource.yaml ---\n${resourceYaml}`);
426
+ }
427
+ else if (!LINKED_FILE_EXTENSIONS.has(extension)) {
428
+ sections.push(`--- ${libPath} ---\n(not a text file read_library loads: ${extension || "no extension"}; it ships at ${libPath} in the package)`);
429
+ }
430
+ else if (size > LINKED_FILE_MAX_BYTES) {
431
+ sections.push(`--- ${libPath} ---\n(${size} bytes, over the ${LINKED_FILE_MAX_BYTES}-byte limit for a linked file; it ships at ${libPath} in the package)`);
432
+ }
433
+ else {
434
+ const text = readText(join(root, ...libPath.split("/")))?.replace(/\s+$/, "") ?? "(file could not be read)";
435
+ sections.push(`--- ${libPath} ---\n${text}`);
436
+ if (extension === ".md" || extension === ".markdown") {
437
+ links = linksOf(text, entry, linkedFile, entries, root);
438
+ if (links.length > 0)
439
+ sections.push(linksSection(links));
440
+ }
441
+ }
442
+ sections.push(footer);
443
+ return {
444
+ ...base,
445
+ body_file: linkedFile,
446
+ linked_file: linkedFile,
447
+ ...(links.length > 0 ? { links } : {}),
448
+ text: sections.join("\n\n"),
449
+ };
450
+ }
209
451
  let bodyFile;
210
452
  let bodyTitle;
211
453
  let body;
454
+ let links = [];
212
455
  if (kind === "tool") {
213
456
  bodyTitle = "how to call";
214
457
  body = toolBody(entry, slug);
@@ -224,40 +467,28 @@ export async function readLibraryEntry(requestedId, part = "all", deps = {}) {
224
467
  bodyFile = picked;
225
468
  bodyTitle = `${relPath}/${picked}`;
226
469
  body = text.replace(/\s+$/, "");
470
+ if (picked.toLowerCase().endsWith(".md"))
471
+ links = linksOf(body, entry, picked, entries, root);
227
472
  }
228
473
  else {
229
474
  bodyTitle = "body";
230
475
  body = `(no body file shipped for this ${kind}; the descriptor below is all there is)`;
231
476
  }
232
477
  }
233
- const resourceYaml = readText(join(dir, "resource.yaml"))?.replace(/\s+$/, "") ?? "(resource.yaml not found in this install)";
234
- const footer = feedbackFooter(entry.id, entry.content_hash);
235
478
  const sections = [header(entry, slug, related)];
236
- if (part === "skill" || part === "all")
479
+ if (part === "skill" || part === "all") {
237
480
  sections.push(`--- ${bodyTitle} ---\n${body}`);
481
+ if (links.length > 0)
482
+ sections.push(linksSection(links));
483
+ }
238
484
  if (part === "resource" || part === "all")
239
485
  sections.push(`--- ${relPath}/resource.yaml ---\n${resourceYaml}`);
240
486
  sections.push(footer);
241
- const result = {
242
- ok: true,
243
- id: entry.id,
244
- kind: entry.kind,
245
- slug,
246
- version: entry.version ?? "",
247
- status: entry.status ?? "stable",
248
- content_hash: entry.content_hash ?? "",
249
- summary: entry.summary ?? "",
250
- use_when: Array.isArray(entry.use_when) ? entry.use_when : [],
251
- related,
252
- part,
253
- path: relPath,
254
- files,
255
- entry_id: entryIdWithHash(entry.id, entry.content_hash),
256
- footer,
257
- text: sections.join("\n\n"),
258
- };
487
+ const result = { ...base, text: sections.join("\n\n") };
259
488
  if (bodyFile)
260
489
  result.body_file = bodyFile;
490
+ if (links.length > 0 && part !== "resource")
491
+ result.links = links;
261
492
  if (kind === "tool") {
262
493
  if (entry.mcp_tool_name)
263
494
  result.mcp_tool_name = entry.mcp_tool_name;
@@ -96,12 +96,12 @@ export declare const searchLibraryInputSchema: z.ZodObject<{
96
96
  include_preview: z.ZodOptional<z.ZodBoolean>;
97
97
  }, "strict", z.ZodTypeAny, {
98
98
  query: string;
99
- kinds?: ("template" | "tool" | "skill" | "reference" | "example" | "collection")[] | undefined;
99
+ kinds?: ("template" | "tool" | "reference" | "skill" | "example" | "collection")[] | undefined;
100
100
  limit?: number | undefined;
101
101
  include_preview?: boolean | undefined;
102
102
  }, {
103
103
  query: string;
104
- kinds?: ("template" | "tool" | "skill" | "reference" | "example" | "collection")[] | undefined;
104
+ kinds?: ("template" | "tool" | "reference" | "skill" | "example" | "collection")[] | undefined;
105
105
  limit?: number | undefined;
106
106
  include_preview?: boolean | undefined;
107
107
  }>;
@@ -1,4 +1,10 @@
1
- export declare const AGENT_CLIENTS: readonly ["summer", "codex", "claude-code", "cursor", "windsurf", "cline", "roo-code", "kilo-code", "gemini", "github-copilot", "vscode-copilot", "opencode"];
1
+ /**
2
+ * Clients `summer skills install --agent` accepts: "summer" (the toolkit's
3
+ * own ~/.summer/skills) plus every agent in the installer's agent table that
4
+ * has a skills or rules folder. core/ cannot import installer/, so this list
5
+ * is written out; agent-table.test.ts fails if the two drift.
6
+ */
7
+ export declare const AGENT_CLIENTS: readonly ["summer", "claude-code", "codex", "cursor", "windsurf", "antigravity", "gemini", "cline", "cline-cli", "roo-code", "kilo-code", "github-copilot", "vscode-copilot", "opencode", "zed", "kiro", "goose", "hermes", "qwen-code", "kimi-code", "crush", "amp", "factory", "warp", "rovo-dev", "qoder", "grok-build", "mistral-vibe"];
2
8
  export type AgentClient = (typeof AGENT_CLIENTS)[number];
3
9
  /** resource.yaml `status` (registry/schemas/skill.schema.json). */
4
10
  export type SkillStatus = "stable" | "preview" | "deprecated";
@@ -17,6 +23,8 @@ export interface SkillRegistryEntry {
17
23
  status: SkillStatus;
18
24
  /** Package-root-relative skill dir, e.g. "library/skills/3d-lighting/". */
19
25
  path: string;
26
+ /** facets.domains from resource.yaml; the first is the primary domain. Empty on old registries. */
27
+ domains: string[];
20
28
  }
21
29
  /**
22
30
  * Load the generated skill registry (cached after first read).
@@ -11,19 +11,41 @@
11
11
  import { readFileSync } from "node:fs";
12
12
  import { join } from "node:path";
13
13
  import { PACKAGE_ROOT } from "./package-root.js";
14
+ /**
15
+ * Clients `summer skills install --agent` accepts: "summer" (the toolkit's
16
+ * own ~/.summer/skills) plus every agent in the installer's agent table that
17
+ * has a skills or rules folder. core/ cannot import installer/, so this list
18
+ * is written out; agent-table.test.ts fails if the two drift.
19
+ */
14
20
  export const AGENT_CLIENTS = [
15
21
  "summer",
16
- "codex",
17
22
  "claude-code",
23
+ "codex",
18
24
  "cursor",
19
25
  "windsurf",
26
+ "antigravity",
27
+ "gemini",
20
28
  "cline",
29
+ "cline-cli",
21
30
  "roo-code",
22
31
  "kilo-code",
23
- "gemini",
24
32
  "github-copilot",
25
33
  "vscode-copilot",
26
34
  "opencode",
35
+ "zed",
36
+ "kiro",
37
+ "goose",
38
+ "hermes",
39
+ "qwen-code",
40
+ "kimi-code",
41
+ "crush",
42
+ "amp",
43
+ "factory",
44
+ "warp",
45
+ "rovo-dev",
46
+ "qoder",
47
+ "grok-build",
48
+ "mistral-vibe",
27
49
  ];
28
50
  const packageRoot = PACKAGE_ROOT;
29
51
  const REGISTRY_RELPATH = join("registry", "generated", "skills-registry.json");
@@ -55,6 +77,7 @@ export function parseSkillRegistry(json) {
55
77
  recommended: s.recommended === true,
56
78
  status: s.status === "preview" || s.status === "deprecated" ? s.status : "stable",
57
79
  path: s.path,
80
+ domains: Array.isArray(s.domains) ? s.domains.filter((d) => typeof d === "string") : [],
58
81
  }));
59
82
  }
60
83
  /**
@@ -1,7 +1,6 @@
1
+ import { type ConfigScope, type McpFormat, type SupportedAgent } from "./agent-table.js";
2
+ export { supportedAgents, type ConfigScope, type SupportedAgent } from "./agent-table.js";
1
3
  export declare const SUMMER_MCP_SERVER_NAME = "summer-engine";
2
- export declare const supportedAgents: readonly ["codex", "claude-code", "cursor", "windsurf", "cline", "roo-code", "kilo-code", "gemini", "github-copilot", "vscode-copilot", "opencode", "lm-studio"];
3
- export type SupportedAgent = (typeof supportedAgents)[number];
4
- export type ConfigScope = "user" | "project";
5
4
  export interface StdioMcpServerConfig {
6
5
  command: string;
7
6
  args: string[];
@@ -25,7 +24,7 @@ export interface AgentConfigResult {
25
24
  path: string;
26
25
  serverName: string;
27
26
  server: StdioMcpServerConfig;
28
- format: "json" | "toml" | "json-opencode" | "json-copilot" | "json-vscode";
27
+ format: McpFormat;
29
28
  snippet: string;
30
29
  changed: boolean;
31
30
  wrote: boolean;
@@ -37,6 +36,7 @@ export interface AgentConfigResult {
37
36
  warnings: string[];
38
37
  nextSteps: string[];
39
38
  }
39
+ type JsonObject = Record<string, unknown>;
40
40
  export declare function parseAgent(value: string | undefined): SupportedAgent | null;
41
41
  export declare function parseScope(value: string | undefined): ConfigScope | null;
42
42
  /** `summer setup [agent] --agent <agent>`: positional and option must agree;
@@ -52,7 +52,12 @@ export declare const DEFAULT_CHANNEL = "latest";
52
52
  export declare function normalizeChannel(channel: string | undefined): string;
53
53
  export declare function createSummerMcpServerConfig(localDev: boolean, platform?: NodeJS.Platform, channel?: string): StdioMcpServerConfig;
54
54
  export declare function renderConfigSnippet(agent: SupportedAgent, server: StdioMcpServerConfig): string;
55
+ /** The key under which the file lists MCP servers (see McpFormat in agent-table.ts). */
56
+ export declare function topLevelKey(format: McpFormat): string;
57
+ /** One server entry in the shape the agent's file expects. */
58
+ export declare function mcpEntry(format: McpFormat, server: StdioMcpServerConfig): JsonObject;
55
59
  /** Installed package root (dist/ and src/ alike). */
56
60
  export declare function resolvePackageRoot(): string;
57
61
  /** Directory name Gemini expects the extension under; the manifest `name` must match it. */
58
62
  export declare const GEMINI_EXTENSION_DIR_NAME = "summer-engine";
63
+ export declare function upsertTomlArrayBlock(content: string, block: string): string;