summer-engine 3.1.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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +27 -5
- package/.codex-plugin/plugin.json +28 -6
- package/.cursor-plugin/plugin.json +27 -5
- package/.factory-plugin/plugin.json +27 -5
- package/.opencode/plugins/summer.js +1 -1
- package/CHANGELOG.md +102 -0
- package/README.md +18 -3
- package/assets/audit/scene_audit.gd +4136 -0
- package/assets/seeing/seeing_probe.gd +1873 -0
- package/dist/cli/commands/skills.js +20 -2
- package/dist/core/api-client.d.ts +9 -1
- package/dist/core/api-client.js +21 -4
- package/dist/core/capabilities/agent-playbook.js +46 -0
- package/dist/core/capabilities/audit/accept.d.ts +55 -0
- package/dist/core/capabilities/audit/accept.js +147 -0
- package/dist/core/capabilities/audit/args.d.ts +95 -0
- package/dist/core/capabilities/audit/args.js +89 -0
- package/dist/core/capabilities/audit/audit.d.ts +56 -0
- package/dist/core/capabilities/audit/audit.js +287 -0
- package/dist/core/capabilities/audit/frame.d.ts +14 -0
- package/dist/core/capabilities/audit/frame.js +35 -0
- package/dist/core/capabilities/audit/gaps.d.ts +96 -0
- package/dist/core/capabilities/audit/gaps.js +257 -0
- package/dist/core/capabilities/audit/judge.d.ts +162 -0
- package/dist/core/capabilities/audit/judge.js +1134 -0
- package/dist/core/capabilities/audit/math.d.ts +110 -0
- package/dist/core/capabilities/audit/math.js +263 -0
- package/dist/core/capabilities/audit/summary.d.ts +74 -0
- package/dist/core/capabilities/audit/summary.js +212 -0
- package/dist/core/capabilities/board.d.ts +31 -0
- package/dist/core/capabilities/board.js +43 -0
- package/dist/core/capabilities/camera-view.d.ts +4 -2
- package/dist/core/capabilities/camera-view.js +6 -3
- package/dist/core/capabilities/connect-signal.d.ts +85 -0
- package/dist/core/capabilities/connect-signal.js +285 -0
- package/dist/core/capabilities/engine-fallbacks.d.ts +5 -0
- package/dist/core/capabilities/engine-fallbacks.js +5 -0
- package/dist/core/capabilities/engine-ops.d.ts +5 -1
- package/dist/core/capabilities/engine-ops.js +0 -3
- package/dist/core/capabilities/engine-receipt.d.ts +12 -0
- package/dist/core/capabilities/engine-receipt.js +26 -0
- package/dist/core/capabilities/file-read.d.ts +64 -0
- package/dist/core/capabilities/file-read.js +325 -0
- package/dist/core/capabilities/game-task-plan.js +4 -2
- package/dist/core/capabilities/grep.d.ts +60 -0
- package/dist/core/capabilities/grep.js +190 -0
- package/dist/core/capabilities/inspect-node.d.ts +56 -0
- package/dist/core/capabilities/inspect-node.js +225 -0
- package/dist/core/capabilities/inspect-resource.d.ts +61 -0
- package/dist/core/capabilities/inspect-resource.js +376 -0
- package/dist/core/capabilities/math3d.d.ts +28 -0
- package/dist/core/capabilities/math3d.js +88 -0
- package/dist/core/capabilities/motion-generation.d.ts +62 -0
- package/dist/core/capabilities/motion-generation.js +138 -0
- package/dist/core/capabilities/placement-batch.d.ts +102 -0
- package/dist/core/capabilities/placement-batch.js +483 -0
- package/dist/core/capabilities/placement-math.d.ts +70 -0
- package/dist/core/capabilities/placement-math.js +209 -0
- package/dist/core/capabilities/placement-script.d.ts +42 -0
- package/dist/core/capabilities/placement-script.js +1096 -0
- package/dist/core/capabilities/placement.d.ts +485 -0
- package/dist/core/capabilities/placement.js +1731 -0
- package/dist/core/capabilities/project-context.d.ts +33 -2
- package/dist/core/capabilities/project-context.js +87 -4
- package/dist/core/capabilities/replace-node.d.ts +91 -0
- package/dist/core/capabilities/replace-node.js +423 -0
- package/dist/core/capabilities/runtime-control.d.ts +18 -2
- package/dist/core/capabilities/runtime-control.js +67 -2
- package/dist/core/capabilities/scene-batch.d.ts +63 -0
- package/dist/core/capabilities/scene-batch.js +394 -0
- package/dist/core/capabilities/scene-readback.d.ts +36 -0
- package/dist/core/capabilities/scene-readback.js +54 -0
- package/dist/core/capabilities/seeing/args.d.ts +348 -0
- package/dist/core/capabilities/seeing/args.js +178 -0
- package/dist/core/capabilities/seeing/candidates.d.ts +127 -0
- package/dist/core/capabilities/seeing/candidates.js +282 -0
- package/dist/core/capabilities/seeing/math.d.ts +134 -0
- package/dist/core/capabilities/seeing/math.js +269 -0
- package/dist/core/capabilities/seeing/probe.d.ts +62 -0
- package/dist/core/capabilities/seeing/probe.js +188 -0
- package/dist/core/capabilities/seeing/scoring.d.ts +235 -0
- package/dist/core/capabilities/seeing/scoring.js +639 -0
- package/dist/core/capabilities/seeing/seeing.d.ts +233 -0
- package/dist/core/capabilities/seeing/seeing.js +1341 -0
- package/dist/core/capabilities/seeing/shot-store.d.ts +52 -0
- package/dist/core/capabilities/seeing/shot-store.js +204 -0
- package/dist/core/capabilities/surface-snap-mesh.d.ts +88 -0
- package/dist/core/capabilities/surface-snap-mesh.js +425 -0
- package/dist/core/capabilities/surface-snap.d.ts +77 -0
- package/dist/core/capabilities/surface-snap.js +461 -0
- package/dist/core/capabilities/tool-dispatch.js +231 -72
- package/dist/core/capabilities/tscn.d.ts +85 -0
- package/dist/core/capabilities/tscn.js +391 -0
- package/dist/core/capabilities/world-snapshot.d.ts +58 -0
- package/dist/core/capabilities/world-snapshot.js +150 -0
- package/dist/core/capability-skew.d.ts +5 -5
- package/dist/core/capability-skew.js +14 -6
- package/dist/core/headless/worker-engine-client.d.ts +1 -1
- package/dist/core/headless/worker-engine-client.js +2 -2
- package/dist/core/library-read.d.ts +37 -5
- package/dist/core/library-read.js +264 -33
- package/dist/core/library-search.d.ts +2 -2
- package/dist/installer/agent-config.js +5 -3
- package/dist/installer/agent-table.d.ts +16 -0
- package/dist/installer/agent-table.js +52 -17
- package/dist/mcp/server.js +9 -3
- package/dist/mcp/tools/asset-tools.js +21 -3
- package/dist/mcp/tools/audit-tools.d.ts +23 -0
- package/dist/mcp/tools/audit-tools.js +60 -0
- package/dist/mcp/tools/debug-tools.js +3 -1
- package/dist/mcp/tools/file-tools.js +17 -4
- package/dist/mcp/tools/generate-tools.js +74 -66
- package/dist/mcp/tools/library-tools.js +2 -0
- package/dist/mcp/tools/perception-tools.js +6 -19
- package/dist/mcp/tools/placement-tools.d.ts +24 -0
- package/dist/mcp/tools/placement-tools.js +91 -0
- package/dist/mcp/tools/project-tools.js +18 -15
- package/dist/mcp/tools/scene-tools.js +71 -83
- package/dist/mcp/tools/seeing-tools.d.ts +24 -0
- package/dist/mcp/tools/seeing-tools.js +64 -0
- package/dist/mcp/tools/spatial-tools.js +17 -9
- package/dist/mcp/tools/visual-tools.js +59 -7
- package/gemini-extension.json +26 -4
- package/integrations/amp/README.md +1 -1
- package/integrations/crush/README.md +1 -1
- package/integrations/grok-build/README.md +1 -1
- package/integrations/hermes/README.md +1 -1
- package/integrations/kimi-code/README.md +1 -1
- package/integrations/mistral-vibe/README.md +1 -1
- package/integrations/opencode/README.md +1 -1
- package/integrations/rovo-dev/README.md +1 -1
- package/integrations/vscode-copilot/README.md +1 -1
- package/integrations/warp/README.md +1 -1
- package/integrations/windsurf/README.md +1 -1
- package/library/references/mcp-tools-reference/mcp-tools-reference.md +59 -15
- package/library/references/mcp-tools-reference/resource.yaml +1 -1
- package/library/references/summer-folder/resource.yaml +1 -1
- package/library/references/summer-folder/summer-folder.md +1 -1
- package/library/skills/3d-lighting/SKILL.md +1 -1
- package/library/skills/README.md +36 -14
- package/library/skills/adaptive-music/SKILL.md +1 -1
- package/library/skills/agent-playtesting/SKILL.md +1 -1
- package/library/skills/ai-characters-in-games/SKILL.md +220 -0
- package/library/skills/ai-characters-in-games/resource.yaml +30 -0
- package/library/skills/ambient-bed/SKILL.md +1 -1
- package/library/skills/animated-loop/SKILL.md +1 -1
- package/library/skills/animation-tree/SKILL.md +1 -1
- package/library/skills/art-direction/SKILL.md +1 -1
- package/library/skills/asset-strategy/SKILL.md +2 -1
- package/library/skills/asset-strategy/resource.yaml +2 -1
- package/library/skills/audio-direction/SKILL.md +1 -1
- package/library/skills/auto-fire-targeting/SKILL.md +1 -1
- package/library/skills/brainstorm-game/SKILL.md +1 -1
- package/library/skills/brainstorming/SKILL.md +1 -1
- package/library/skills/browse-templates/SKILL.md +3 -3
- package/library/skills/browse-templates/resource.yaml +1 -1
- package/library/skills/camera-rigs/SKILL.md +128 -0
- package/library/skills/camera-rigs/resource.yaml +29 -0
- package/library/skills/celeste-momentum-platforming/SKILL.md +1 -1
- package/library/skills/character-animation-wiring/SKILL.md +1 -1
- package/library/skills/character-model/SKILL.md +1 -1
- package/library/skills/character-movement/SKILL.md +326 -0
- package/library/skills/character-movement/references/default-third-person-controller.gd +201 -0
- package/library/skills/character-movement/references/default-third-person-verification-probe.gd +154 -0
- package/library/skills/character-movement/references/movement-3d.md +136 -0
- package/library/skills/character-movement/references/platformer-feel.md +83 -0
- package/library/skills/character-movement/resource.yaml +40 -0
- package/library/skills/character-portrait/SKILL.md +1 -1
- package/library/skills/cinematic-cutscene/SKILL.md +1 -1
- package/library/skills/combat-basics/SKILL.md +159 -0
- package/library/skills/combat-basics/references/projectiles-and-aoe.md +100 -0
- package/library/skills/combat-basics/resource.yaml +34 -0
- package/library/skills/concept-art/SKILL.md +1 -1
- package/library/skills/create-asset-sheet/SKILL.md +1 -1
- package/library/skills/debug/SKILL.md +1 -1
- package/library/skills/debugging-game-feel/SKILL.md +1 -1
- package/library/skills/design-level/SKILL.md +1 -1
- package/library/skills/design-mechanic/SKILL.md +1 -1
- package/library/skills/design-npc/SKILL.md +1 -1
- package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
- package/library/skills/dispatching-parallel-agents/SKILL.md +1 -1
- package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
- package/library/skills/environment-kit/SKILL.md +1 -1
- package/library/skills/export-and-ship/SKILL.md +1 -1
- package/library/skills/fabricating-assets/SKILL.md +1 -1
- package/library/skills/facial-and-lipsync/SKILL.md +1 -1
- package/library/skills/fps-controller/SKILL.md +9 -7
- package/library/skills/fps-controller/resource.yaml +4 -1
- package/library/skills/game-feel/SKILL.md +1 -1
- package/library/skills/gameskill/SKILL.md +1 -1
- package/library/skills/gdscript-patterns/SKILL.md +1 -1
- package/library/skills/generate-motion/SKILL.md +9 -9
- package/library/skills/generate-motion/resource.yaml +2 -1
- package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
- package/library/skills/headless-scripting/SKILL.md +1 -1
- package/library/skills/in-game-purchases/SKILL.md +254 -0
- package/library/skills/in-game-purchases/resource.yaml +29 -0
- package/library/skills/instantiate-asset-pack/SKILL.md +1 -1
- package/library/skills/investigating-bugs/SKILL.md +1 -1
- package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +1 -1
- package/library/skills/make-game/SKILL.md +25 -3
- package/library/skills/make-game/references/2d-platformer-polish.md +93 -0
- package/library/skills/make-game/references/2d-platformer.md +117 -0
- package/library/skills/make-game/references/2d-rpg-content.md +234 -0
- package/library/skills/make-game/references/2d-rpg.md +241 -0
- package/library/skills/make-game/references/2d-survivors-progression.md +201 -0
- package/library/skills/make-game/references/2d-survivors.md +237 -0
- package/library/skills/make-game/references/3d-fps-systems.md +216 -0
- package/library/skills/make-game/references/3d-fps.md +177 -0
- package/library/skills/make-game/references/3d-horror-systems.md +186 -0
- package/library/skills/make-game/references/3d-horror.md +201 -0
- package/library/skills/make-game/references/3d-third-person-systems.md +220 -0
- package/library/skills/make-game/references/3d-third-person.md +215 -0
- package/library/skills/make-game/resource.yaml +6 -1
- package/library/skills/multiplayer/SKILL.md +150 -0
- package/library/skills/multiplayer/resource.yaml +33 -0
- package/library/skills/multiplayer-movement/SKILL.md +510 -0
- package/library/skills/multiplayer-movement/files.md +501 -0
- package/library/skills/multiplayer-movement/resource.yaml +30 -0
- package/library/skills/multiplayer-project/SKILL.md +521 -0
- package/library/skills/multiplayer-project/files.md +448 -0
- package/library/skills/multiplayer-project/resource.yaml +36 -0
- package/library/skills/multiplayer-publish/SKILL.md +229 -0
- package/library/skills/multiplayer-publish/export-errors.md +89 -0
- package/library/skills/multiplayer-publish/resource.yaml +28 -0
- package/library/skills/multiplayer-state/SKILL.md +438 -0
- package/library/skills/multiplayer-state/files.md +592 -0
- package/library/skills/multiplayer-state/resource.yaml +35 -0
- package/library/skills/multiplayer-testing/SKILL.md +236 -0
- package/library/skills/multiplayer-testing/resource.yaml +39 -0
- package/library/skills/music-track/SKILL.md +1 -1
- package/library/skills/navigate-summer/SKILL.md +1 -1
- package/library/skills/new-project/SKILL.md +1 -1
- package/library/skills/organic-model/SKILL.md +1 -1
- package/library/skills/pixel-art/SKILL.md +1 -1
- package/library/skills/play/SKILL.md +1 -1
- package/library/skills/playtesting-a-feature/SKILL.md +1 -1
- package/library/skills/procedural-animation/SKILL.md +2 -2
- package/library/skills/procedural-animation/resource.yaml +1 -1
- package/library/skills/prop-model/SKILL.md +1 -1
- package/library/skills/psx-retro-rendering/SKILL.md +1 -1
- package/library/skills/realtime-wet-surfaces/SKILL.md +2 -2
- package/library/skills/remote-deploy/SKILL.md +1 -1
- package/library/skills/retarget/SKILL.md +1 -1
- package/library/skills/running-in-the-cloud/SKILL.md +1 -1
- package/library/skills/save-load/SKILL.md +156 -0
- package/library/skills/save-load/resource.yaml +27 -0
- package/library/skills/scene-composition/SKILL.md +1 -1
- package/library/skills/scene-hierarchy-design/SKILL.md +1 -1
- package/library/skills/scene-scripting/SKILL.md +1 -1
- package/library/skills/scene-to-level/SKILL.md +1 -1
- package/library/skills/skill-create/SKILL.md +1 -1
- package/library/skills/skill-improve/SKILL.md +1 -1
- package/library/skills/skill-test/SKILL.md +1 -1
- package/library/skills/skintokens-auto-rigging/SKILL.md +1 -1
- package/library/skills/skybox-panorama/SKILL.md +1 -1
- package/library/skills/sound-effect/SKILL.md +1 -1
- package/library/skills/spatial-placement/SKILL.md +134 -3
- package/library/skills/spatial-placement/references/kit-placement-tools.md +364 -0
- package/library/skills/spatial-placement/resource.yaml +16 -2
- package/library/skills/sprite-sheet/SKILL.md +1 -1
- package/library/skills/summer-analytics/SKILL.md +147 -0
- package/library/skills/summer-analytics/resource.yaml +28 -0
- package/library/skills/summer-friends/SKILL.md +226 -0
- package/library/skills/summer-friends/resource.yaml +28 -0
- package/library/skills/summer-leaderboards/SKILL.md +231 -0
- package/library/skills/summer-leaderboards/resource.yaml +30 -0
- package/library/skills/summer-match-results/SKILL.md +286 -0
- package/library/skills/summer-match-results/resource.yaml +32 -0
- package/library/skills/summer-matchmaking/SKILL.md +301 -0
- package/library/skills/summer-matchmaking/resource.yaml +32 -0
- package/library/skills/summer-parties/SKILL.md +253 -0
- package/library/skills/summer-parties/resource.yaml +30 -0
- package/library/skills/summer-player-data/SKILL.md +322 -0
- package/library/skills/summer-player-data/resource.yaml +30 -0
- package/library/skills/summer-store/SKILL.md +271 -0
- package/library/skills/summer-store/resource.yaml +29 -0
- package/library/skills/summer-world-chat/SKILL.md +195 -0
- package/library/skills/summer-world-chat/resource.yaml +30 -0
- package/library/skills/summer-world-saves/SKILL.md +284 -0
- package/library/skills/summer-world-saves/resource.yaml +29 -0
- package/library/skills/text-to-motion/SKILL.md +99 -0
- package/library/skills/text-to-motion/prompts-and-controls.md +34 -0
- package/library/skills/text-to-motion/resource.yaml +41 -0
- package/library/skills/text-to-motion/rigging-for-text-motion.md +54 -0
- package/library/skills/tileable-texture/SKILL.md +1 -1
- package/library/skills/trailer-shot/SKILL.md +1 -1
- package/library/skills/tune-performance/SKILL.md +1 -1
- package/library/skills/ui-basics/SKILL.md +10 -1
- package/library/skills/ui-graphics/SKILL.md +1 -1
- package/library/skills/use-widget-asset/SKILL.md +1 -1
- package/library/skills/using-summer/SKILL.md +2 -2
- package/library/skills/using-summer/resource.yaml +2 -2
- package/library/skills/vehicle-model/SKILL.md +1 -1
- package/library/skills/verification-before-completion/SKILL.md +1 -1
- package/library/skills/verifying-scenes/SKILL.md +76 -2
- package/library/skills/verifying-scenes/resource.yaml +13 -2
- package/library/skills/vfx-dissolve/SKILL.md +1 -1
- package/library/skills/vfx-fire/SKILL.md +1 -1
- package/library/skills/vfx-hit-spark/SKILL.md +1 -1
- package/library/skills/vfx-lightning/SKILL.md +1 -1
- package/library/skills/vfx-magic-glow/SKILL.md +1 -1
- package/library/skills/vfx-muzzle-flash/SKILL.md +1 -1
- package/library/skills/vfx-smoke/SKILL.md +1 -1
- package/library/skills/vfx-water-ripple/SKILL.md +1 -1
- package/library/skills/voice-line/SKILL.md +1 -1
- package/library/skills/web-and-touch-input/SKILL.md +38 -0
- package/library/skills/web-and-touch-input/resource.yaml +28 -0
- package/library/skills/web-compatibility-look/SKILL.md +62 -0
- package/library/skills/web-compatibility-look/resource.yaml +30 -0
- package/library/skills/world-building-3d/SKILL.md +8 -1
- package/library/skills/world-building-3d/references/spatial-tools.md +1 -1
- package/library/skills/world-building-3d/resource.yaml +2 -1
- package/library/skills/writing-plans/SKILL.md +1 -1
- package/library/skills/writing-skills/SKILL.md +1 -1
- package/library/templates/3d-lan-multiplayer-starter/resource.yaml +2 -2
- package/library/tools/attach-to-surface/resource.yaml +142 -0
- package/library/tools/batch/resource.yaml +9 -3
- package/library/tools/connect-ports/resource.yaml +120 -0
- package/library/tools/connect-signal/resource.yaml +3 -2
- package/library/tools/debug-views/resource.yaml +94 -0
- package/library/tools/frame-nodes/resource.yaml +104 -0
- package/library/tools/frame-shot/resource.yaml +134 -0
- package/library/tools/generate-motion/resource.yaml +44 -9
- package/library/tools/get-board/resource.yaml +50 -0
- package/library/tools/get-project-context/resource.yaml +13 -2
- package/library/tools/grep/resource.yaml +77 -0
- package/library/tools/inspect-asset/resource.yaml +71 -0
- package/library/tools/inspect-node/resource.yaml +9 -2
- package/library/tools/inspect-resource/resource.yaml +16 -5
- package/library/tools/instantiate-scene/resource.yaml +27 -2
- package/library/tools/measure/resource.yaml +96 -0
- package/library/tools/place-adjacent/resource.yaml +113 -0
- package/library/tools/play/resource.yaml +15 -2
- package/library/tools/raycast/resource.yaml +101 -0
- package/library/tools/read-file/resource.yaml +36 -2
- package/library/tools/read-library/resource.yaml +2 -2
- package/library/tools/repeat-along/resource.yaml +129 -0
- package/library/tools/replace-node/resource.yaml +11 -5
- package/library/tools/scene-audit/resource.yaml +144 -0
- package/library/tools/screenshot/resource.yaml +13 -2
- package/library/tools/search-assets/resource.yaml +18 -0
- package/library/tools/shot-sheet/resource.yaml +110 -0
- package/library/tools/snap-to-surface/resource.yaml +4 -1
- package/library/tools/world-snapshot/resource.yaml +24 -3
- package/library/tools/zoom/resource.yaml +105 -0
- package/package.json +1 -1
- package/registry/generated/aliases.json +17 -3
- package/registry/generated/counts.json +3 -3
- package/registry/generated/gemini-extension.json +26 -4
- package/registry/generated/index.json +2154 -469
- package/registry/generated/marketplace.claude.json +2 -2
- package/registry/generated/plugin.claude.json +27 -5
- package/registry/generated/plugin.codex.json +28 -6
- package/registry/generated/plugin.cursor.json +27 -5
- package/registry/generated/plugin.factory.json +27 -5
- package/registry/generated/skills-index.md +36 -14
- package/registry/generated/skills-registry.json +421 -124
- package/registry/generated/templates-registry.json +2 -2
- package/library/skills/host-authoritative-state/SKILL.md +0 -332
- package/library/skills/host-authoritative-state/resource.yaml +0 -28
- package/library/skills/peer-to-peer-multiplayer/SKILL.md +0 -373
- package/library/skills/peer-to-peer-multiplayer/resource.yaml +0 -28
- package/library/skills/setup-multiplayer/SKILL.md +0 -336
- package/library/skills/setup-multiplayer/resource.yaml +0 -28
|
@@ -76,6 +76,25 @@ function vsCodeGlobalStorage(ctx, extensionId, fileName) {
|
|
|
76
76
|
}
|
|
77
77
|
const home = (...parts) => (ctx) => join(ctx.home, ...parts);
|
|
78
78
|
const project = (...parts) => (ctx) => join(ctx.cwd, ...parts);
|
|
79
|
+
/**
|
|
80
|
+
* The agentskills.io shared folder: `~/.agents/skills` and `<project>/.agents/skills`.
|
|
81
|
+
* Every agent whose docs say it reads this folder installs here, so one
|
|
82
|
+
* install serves them all and "where are the skills" has one answer.
|
|
83
|
+
*/
|
|
84
|
+
const SHARED_SKILLS_USER = home(".agents", "skills");
|
|
85
|
+
const SHARED_SKILLS_PROJECT = project(".agents", "skills");
|
|
86
|
+
function sharedSkills(extra = {}) {
|
|
87
|
+
return { kind: "skill-dir", user: SHARED_SKILLS_USER, project: SHARED_SKILLS_PROJECT, ...extra };
|
|
88
|
+
}
|
|
89
|
+
/** True when this location is the shared agentskills.io folder. */
|
|
90
|
+
export function isSharedSkillsPath(path) {
|
|
91
|
+
return /[\\/]\.agents[\\/]skills$/.test(path);
|
|
92
|
+
}
|
|
93
|
+
/** Agents that read the shared folder at the given scope (for the install summary). */
|
|
94
|
+
export function agentsSharingSkills(scope, ctx) {
|
|
95
|
+
const shared = (scope === "user" ? SHARED_SKILLS_USER : SHARED_SKILLS_PROJECT)(ctx);
|
|
96
|
+
return SPECS.filter((spec) => resolveSkillPath(spec, scope, ctx)?.path === shared);
|
|
97
|
+
}
|
|
79
98
|
/** agentskills.io layout (`<dir>/<skill>/SKILL.md`) under a user dir and a project dir. */
|
|
80
99
|
function skillDirs(user, proj, extra = {}) {
|
|
81
100
|
return { kind: "skill-dir", user, project: proj, ...extra };
|
|
@@ -121,7 +140,7 @@ const SPECS = [
|
|
|
121
140
|
projectNote: "Codex only loads project .codex/config.toml from trusted projects.",
|
|
122
141
|
},
|
|
123
142
|
restart: "Restart Codex or run /mcp in a new session.",
|
|
124
|
-
skills:
|
|
143
|
+
skills: sharedSkills(),
|
|
125
144
|
},
|
|
126
145
|
{
|
|
127
146
|
id: "cursor",
|
|
@@ -132,9 +151,10 @@ const SPECS = [
|
|
|
132
151
|
format: "json-stdio",
|
|
133
152
|
mcp: { user: home(".cursor", "mcp.json"), project: project(".cursor", "mcp.json") },
|
|
134
153
|
restart: "Restart Cursor and enable the summer-engine MCP server if prompted.",
|
|
135
|
-
skills:
|
|
136
|
-
reloadHint: "Cursor loads skills in the next chat. Summer 3.0
|
|
154
|
+
skills: sharedSkills({
|
|
155
|
+
reloadHint: "Cursor loads skills in the next chat. Summer 3.0 wrote rule files to .cursor/rules and 3.1.0 wrote .cursor/skills; `--force` removes both.",
|
|
137
156
|
legacyRules: { user: home(".cursor", "rules"), project: project(".cursor", "rules"), suffix: ".mdc" },
|
|
157
|
+
legacyDirs: { user: home(".cursor", "skills"), project: project(".cursor", "skills") },
|
|
138
158
|
}),
|
|
139
159
|
},
|
|
140
160
|
{
|
|
@@ -149,7 +169,7 @@ const SPECS = [
|
|
|
149
169
|
project: null,
|
|
150
170
|
},
|
|
151
171
|
restart: "Restart Devin Desktop (formerly Windsurf) and refresh MCP servers from the agent settings. Devin's docs say mcp_config.json configures the Cascade agent; for the Devin agent add the server in the app's MCP settings with the same command.",
|
|
152
|
-
skills:
|
|
172
|
+
skills: sharedSkills({ legacyDirs: { user: home(".codeium", "windsurf", "skills"), project: project(".windsurf", "skills") } }),
|
|
153
173
|
},
|
|
154
174
|
{
|
|
155
175
|
id: "antigravity",
|
|
@@ -259,7 +279,7 @@ const SPECS = [
|
|
|
259
279
|
format: "json-vscode",
|
|
260
280
|
mcp: { user: (ctx) => join(vsCodeUserDir(ctx), "mcp.json"), project: project(".vscode", "mcp.json") },
|
|
261
281
|
restart: "Restart VS Code or run MCP: List Servers, then start summer-engine in Copilot Agent mode.",
|
|
262
|
-
skills:
|
|
282
|
+
skills: sharedSkills({ legacyDirs: { user: home(".copilot", "skills"), project: project(".github", "skills") } }),
|
|
263
283
|
},
|
|
264
284
|
{
|
|
265
285
|
id: "visual-studio",
|
|
@@ -300,9 +320,10 @@ const SPECS = [
|
|
|
300
320
|
project: project("opencode.json"),
|
|
301
321
|
},
|
|
302
322
|
restart: "Restart OpenCode so it reloads opencode.json.",
|
|
303
|
-
skills:
|
|
304
|
-
reloadHint: "OpenCode loads skills from this folder on the next session. Summer 3.0
|
|
323
|
+
skills: sharedSkills({
|
|
324
|
+
reloadHint: "OpenCode loads skills from this folder on the next session. Summer 3.0 wrote markdown under agents/summer and 3.1.0 wrote opencode/skills; `--force` removes both.",
|
|
305
325
|
legacyRules: { user: (ctx) => join(xdgOrAppData(ctx), "opencode", "agents", "summer"), project: project(".opencode", "agents", "summer"), suffix: ".md" },
|
|
326
|
+
legacyDirs: { user: (ctx) => join(xdgOrAppData(ctx), "opencode", "skills"), project: project(".opencode", "skills") },
|
|
306
327
|
}),
|
|
307
328
|
},
|
|
308
329
|
{
|
|
@@ -317,7 +338,7 @@ const SPECS = [
|
|
|
317
338
|
project: null,
|
|
318
339
|
},
|
|
319
340
|
restart: "Zed reloads settings.json live; open the Agent panel and check summer-engine under MCP servers.",
|
|
320
|
-
skills:
|
|
341
|
+
skills: sharedSkills(),
|
|
321
342
|
},
|
|
322
343
|
{
|
|
323
344
|
id: "kiro",
|
|
@@ -355,8 +376,9 @@ const SPECS = [
|
|
|
355
376
|
format: "yaml-hermes",
|
|
356
377
|
mcp: { user: home(".hermes", "config.yaml"), project: null },
|
|
357
378
|
restart: "Run /reload-mcp in Hermes Agent (or restart it).",
|
|
358
|
-
skills: skillDirs(home(".hermes", "skills"),
|
|
379
|
+
skills: skillDirs(home(".hermes", "skills"), SHARED_SKILLS_PROJECT, {
|
|
359
380
|
reloadHint: "Project skills need `hermes skills trust` before Hermes loads them.",
|
|
381
|
+
legacyDirs: { user: home(".hermes", "skills"), project: project(".hermes", "skills") },
|
|
360
382
|
}),
|
|
361
383
|
},
|
|
362
384
|
{
|
|
@@ -395,7 +417,7 @@ const SPECS = [
|
|
|
395
417
|
format: "json",
|
|
396
418
|
mcp: { user: home(".kimi-code", "mcp.json"), project: project(".kimi-code", "mcp.json") },
|
|
397
419
|
restart: "Restart Kimi Code CLI so it reconnects its MCP servers.",
|
|
398
|
-
skills:
|
|
420
|
+
skills: sharedSkills({ legacyDirs: { user: home(".kimi-code", "skills"), project: project(".kimi-code", "skills") } }),
|
|
399
421
|
},
|
|
400
422
|
{
|
|
401
423
|
id: "crush",
|
|
@@ -409,7 +431,7 @@ const SPECS = [
|
|
|
409
431
|
project: project(".crushrc"),
|
|
410
432
|
},
|
|
411
433
|
restart: "Restart Crush so it reloads crushrc.",
|
|
412
|
-
skills:
|
|
434
|
+
skills: sharedSkills({ legacyDirs: { user: home(".config", "crush", "skills"), project: project(".crush", "skills") } }),
|
|
413
435
|
},
|
|
414
436
|
{
|
|
415
437
|
id: "amp",
|
|
@@ -420,7 +442,7 @@ const SPECS = [
|
|
|
420
442
|
format: "json-amp",
|
|
421
443
|
mcp: { user: (ctx) => join(xdgOrAppData(ctx), "amp", "settings.json"), project: null },
|
|
422
444
|
restart: "Restart Amp so it reloads settings.json.",
|
|
423
|
-
skills:
|
|
445
|
+
skills: sharedSkills({ legacyDirs: { user: (ctx) => join(xdgOrAppData(ctx), "amp", "skills"), project: null } }),
|
|
424
446
|
},
|
|
425
447
|
{
|
|
426
448
|
id: "factory",
|
|
@@ -431,7 +453,7 @@ const SPECS = [
|
|
|
431
453
|
format: "json-stdio",
|
|
432
454
|
mcp: { user: home(".factory", "mcp.json"), project: project(".factory", "mcp.json") },
|
|
433
455
|
restart: "Restart droid or run /mcp in the active session.",
|
|
434
|
-
skills:
|
|
456
|
+
skills: sharedSkills({ legacyDirs: { user: home(".factory", "skills"), project: project(".factory", "skills") } }),
|
|
435
457
|
},
|
|
436
458
|
{
|
|
437
459
|
id: "junie",
|
|
@@ -454,7 +476,7 @@ const SPECS = [
|
|
|
454
476
|
format: "json",
|
|
455
477
|
mcp: { user: home(".warp", ".mcp.json"), project: project(".warp", ".mcp.json") },
|
|
456
478
|
restart: "Warp detects the file and spawns the server; check Settings > AI > MCP servers.",
|
|
457
|
-
skills:
|
|
479
|
+
skills: sharedSkills({ legacyDirs: { user: home(".warp", "skills"), project: project(".warp", "skills") } }),
|
|
458
480
|
},
|
|
459
481
|
{
|
|
460
482
|
id: "rovo-dev",
|
|
@@ -465,7 +487,7 @@ const SPECS = [
|
|
|
465
487
|
format: "json-transport",
|
|
466
488
|
mcp: { user: home(".rovodev", "mcp.json"), project: null },
|
|
467
489
|
restart: "Restart Rovo Dev CLI so it reconnects its MCP servers.",
|
|
468
|
-
skills:
|
|
490
|
+
skills: sharedSkills({ legacyDirs: { user: home(".rovodev", "skills"), project: project(".rovodev", "skills") } }),
|
|
469
491
|
},
|
|
470
492
|
{
|
|
471
493
|
id: "qoder",
|
|
@@ -487,7 +509,7 @@ const SPECS = [
|
|
|
487
509
|
format: "toml",
|
|
488
510
|
mcp: { user: home(".grok", "config.toml"), project: project(".grok", "config.toml") },
|
|
489
511
|
restart: "Restart Grok Build so it reloads config.toml (it also reads ~/.claude.json and .cursor/mcp.json).",
|
|
490
|
-
skills:
|
|
512
|
+
skills: sharedSkills({ legacyDirs: { user: home(".grok", "skills"), project: project(".grok", "skills") } }),
|
|
491
513
|
},
|
|
492
514
|
{
|
|
493
515
|
id: "mistral-vibe",
|
|
@@ -498,7 +520,7 @@ const SPECS = [
|
|
|
498
520
|
format: "toml-array",
|
|
499
521
|
mcp: { user: home(".vibe", "config.toml"), project: project(".vibe", "config.toml") },
|
|
500
522
|
restart: "Restart Vibe so it reloads config.toml.",
|
|
501
|
-
skills: skillDirs(home(".vibe", "skills"), project(".vibe", "skills")),
|
|
523
|
+
skills: skillDirs(home(".vibe", "skills"), SHARED_SKILLS_PROJECT, { legacyDirs: { user: home(".vibe", "skills"), project: project(".vibe", "skills") } }),
|
|
502
524
|
},
|
|
503
525
|
{
|
|
504
526
|
id: "lm-studio",
|
|
@@ -573,6 +595,19 @@ export function legacyRuleFiles(spec, scope, ctx, skillNames) {
|
|
|
573
595
|
const prefix = spec.id === "opencode" ? "" : "summer-";
|
|
574
596
|
return [...skillNames].map((name) => join(dir, `${prefix}${name}${legacy.suffix}`));
|
|
575
597
|
}
|
|
598
|
+
/** Skill dirs a Summer 3.1.0 install may have written at this agent's old native location; `null` when it never moved. */
|
|
599
|
+
export function legacySkillDirs(spec, scope, ctx, skillNames) {
|
|
600
|
+
const legacy = spec.skills?.legacyDirs;
|
|
601
|
+
if (!legacy)
|
|
602
|
+
return null;
|
|
603
|
+
const dir = scope === "project" ? (legacy.project ? legacy.project(ctx) : null) : legacy.user(ctx);
|
|
604
|
+
if (!dir)
|
|
605
|
+
return [];
|
|
606
|
+
const current = resolveSkillPath(spec, scope, ctx)?.path;
|
|
607
|
+
if (current === dir)
|
|
608
|
+
return [];
|
|
609
|
+
return [...skillNames].map((name) => join(dir, name));
|
|
610
|
+
}
|
|
576
611
|
/** Where skills go for an agent with a skills home. */
|
|
577
612
|
export function resolveSkillPath(spec, scope, ctx) {
|
|
578
613
|
if (!spec.skills)
|
package/dist/mcp/server.js
CHANGED
|
@@ -4,10 +4,13 @@ import { EngineApiClient } from "../core/api-client.js";
|
|
|
4
4
|
import { registerSceneTools } from "./tools/scene-tools.js";
|
|
5
5
|
import { registerDebugTools } from "./tools/debug-tools.js";
|
|
6
6
|
import { registerVisualTools } from "./tools/visual-tools.js";
|
|
7
|
+
import { registerSeeingTools } from "./tools/seeing-tools.js";
|
|
8
|
+
import { registerAuditTools } from "./tools/audit-tools.js";
|
|
7
9
|
import { WITH_ENGINE_META } from "./tools/with-engine.js";
|
|
8
10
|
import { registerPlaybookPrompt, registerProjectTools, } from "./tools/project-tools.js";
|
|
9
11
|
import { registerPerceptionTools } from "./tools/perception-tools.js";
|
|
10
12
|
import { registerSpatialTools } from "./tools/spatial-tools.js";
|
|
13
|
+
import { registerPlacementTools } from "./tools/placement-tools.js";
|
|
11
14
|
import { registerScriptTools } from "./tools/script-tools.js";
|
|
12
15
|
import { registerEventTools } from "./tools/event-tools.js";
|
|
13
16
|
import { registerFabricateTools } from "./tools/fabricate-tools.js";
|
|
@@ -36,10 +39,10 @@ export const getCachedBootDriftNotice = getCachedNotice;
|
|
|
36
39
|
* it costs a few hundred tokens once; the full operating guide stays in the
|
|
37
40
|
* summer_agent_playbook prompt / summer_get_agent_playbook tool.
|
|
38
41
|
*/
|
|
39
|
-
export const SUMMER_MCP_INSTRUCTIONS = "Summer Engine MCP. Call summer_get_project_context first: it binds this session to the open project and returns mainScene, projectMemory (GameSoul, template pin) and any capabilitySkewWarning. " +
|
|
40
|
-
"Before building or fixing, summer_search_library then summer_read_library the hit
|
|
42
|
+
export const SUMMER_MCP_INSTRUCTIONS = "Summer Engine MCP. Call summer_get_project_context first: it binds this session to the open project and returns mainScene, projectMemory (GameSoul, template pin) and any capabilitySkewWarning, compactly. " +
|
|
43
|
+
"Before building or fixing, summer_search_library then summer_read_library the hit: skills, examples, templates live there. " +
|
|
41
44
|
"After a playthrough read summer_get_diagnostics, not summer_get_console alone (runtime errors live in the debugger). " +
|
|
42
|
-
"
|
|
45
|
+
"An all-black screenshot means the viewport had not redrawn — recapture before concluding. " +
|
|
43
46
|
"Report entries you verified in-engine via summer_library_feedback.";
|
|
44
47
|
/**
|
|
45
48
|
* Fire-and-forget probe of the npm registry on MCP boot. Caches the result for
|
|
@@ -302,6 +305,8 @@ export function createMcpServer() {
|
|
|
302
305
|
registerSceneTools(server);
|
|
303
306
|
registerDebugTools(server);
|
|
304
307
|
registerVisualTools(server);
|
|
308
|
+
registerSeeingTools(server);
|
|
309
|
+
registerAuditTools(server);
|
|
305
310
|
registerProjectTools(server);
|
|
306
311
|
registerFileTools(server);
|
|
307
312
|
registerAssetTools(server);
|
|
@@ -311,6 +316,7 @@ export function createMcpServer() {
|
|
|
311
316
|
registerScriptTools(server);
|
|
312
317
|
registerPerceptionTools(server);
|
|
313
318
|
registerSpatialTools(server);
|
|
319
|
+
registerPlacementTools(server);
|
|
314
320
|
registerNavigationTools(server);
|
|
315
321
|
registerLibraryTools(server);
|
|
316
322
|
registerEventTools(server);
|
|
@@ -23,6 +23,12 @@ async function searchAssetsApi(params) {
|
|
|
23
23
|
if (params.source) {
|
|
24
24
|
searchParams.set("source", params.source);
|
|
25
25
|
}
|
|
26
|
+
if (params.style)
|
|
27
|
+
searchParams.set("style", params.style);
|
|
28
|
+
if (params.includeCommunity)
|
|
29
|
+
searchParams.set("includeCommunity", "true");
|
|
30
|
+
if (params.preview)
|
|
31
|
+
searchParams.set("contactSheet", "true");
|
|
26
32
|
const gatewayUrl = await resolveGatewayUrl();
|
|
27
33
|
const res = await fetch(`${gatewayUrl}/api/mcp/assets?${searchParams}`, {
|
|
28
34
|
headers: { Authorization: `Bearer ${token}` },
|
|
@@ -120,7 +126,10 @@ Sources:
|
|
|
120
126
|
- "all" — Search both library and your assets.
|
|
121
127
|
|
|
122
128
|
Uses hybrid search: keywords + semantic similarity. Finds assets by name AND by meaning.
|
|
123
|
-
Returns asset names, types, preview URLs, and import-ready file URLs.
|
|
129
|
+
Returns asset names, types, each asset's art style, preview URLs, and import-ready file URLs.
|
|
130
|
+
Keep a game in ONE art direction: pass style (the game's chosen family) so clashing styles are
|
|
131
|
+
left out, and set preview to see the first results as one numbered picture before importing.
|
|
132
|
+
Curated, open-source and Summer packs come first; people's own public generations only with includeCommunity.
|
|
124
133
|
|
|
125
134
|
Cloud tool — works WITHOUT the Summer Engine app open.
|
|
126
135
|
Requires authentication (so we can attribute usage and apply per-user rate limits): run 'npx -y summer-engine@latest login' first.`, {
|
|
@@ -128,8 +137,14 @@ Requires authentication (so we can attribute usage and apply per-user rate limit
|
|
|
128
137
|
assetType: z.enum(["2d_image", "animation", "3d_model", "audio", "music", "all"]).default("all").describe("Filter by asset type"),
|
|
129
138
|
limit: z.number().default(10).describe("Max results (1-20)"),
|
|
130
139
|
source: z.enum(["library", "my_assets", "all"]).default("library").describe("Where to search: library (public 25k+), my_assets (your generated assets), all"),
|
|
131
|
-
|
|
132
|
-
|
|
140
|
+
style: z
|
|
141
|
+
.enum(["realistic", "stylized-lowpoly", "toon", "pixel", "hand-painted", "voxel"])
|
|
142
|
+
.optional()
|
|
143
|
+
.describe("The game's one art direction: clashing styles are left out, matches come first"),
|
|
144
|
+
preview: z.boolean().default(false).describe("Also return one picture of the first 9 results, numbered in order, to see them before importing"),
|
|
145
|
+
includeCommunity: z.boolean().default(false).describe("Also include people's own public AI generations"),
|
|
146
|
+
}, async ({ query, assetType, limit, source, style, preview, includeCommunity }) => {
|
|
147
|
+
const result = await searchAssetsApi({ query, assetType, limit: Math.min(limit, 20), source, style, preview, includeCommunity });
|
|
133
148
|
if (result.error) {
|
|
134
149
|
return {
|
|
135
150
|
content: [
|
|
@@ -141,6 +156,7 @@ Requires authentication (so we can attribute usage and apply per-user rate limit
|
|
|
141
156
|
isError: true,
|
|
142
157
|
};
|
|
143
158
|
}
|
|
159
|
+
const sheet = result.contactSheet?.match(/^data:(image\/[a-z]+);base64,(.+)$/);
|
|
144
160
|
return {
|
|
145
161
|
content: [
|
|
146
162
|
{
|
|
@@ -150,8 +166,10 @@ Requires authentication (so we can attribute usage and apply per-user rate limit
|
|
|
150
166
|
count: result.count,
|
|
151
167
|
summary: result.summary,
|
|
152
168
|
message: result.message,
|
|
169
|
+
...(sheet ? { preview: "attached: the first results, numbered in this order" } : {}),
|
|
153
170
|
}, null, 2),
|
|
154
171
|
},
|
|
172
|
+
...(sheet ? [{ type: "image", data: sheet[2], mimeType: sheet[1] }] : []),
|
|
155
173
|
],
|
|
156
174
|
};
|
|
157
175
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type AuditResult } from "../../core/capabilities/audit/audit.js";
|
|
3
|
+
/**
|
|
4
|
+
* summer_scene_audit: one read-only call that walks every node of a 3D scene
|
|
5
|
+
* and lists likely visual and placement problems, so a build agent knows
|
|
6
|
+
* exactly where to look. Implementation and the in-engine kernel:
|
|
7
|
+
* src/core/capabilities/audit/ and assets/audit/scene_audit.gd.
|
|
8
|
+
*/
|
|
9
|
+
type ToolResultContent = {
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
} | {
|
|
13
|
+
type: "image";
|
|
14
|
+
data: string;
|
|
15
|
+
mimeType: string;
|
|
16
|
+
};
|
|
17
|
+
type ToolResult = {
|
|
18
|
+
content: ToolResultContent[];
|
|
19
|
+
isError?: boolean;
|
|
20
|
+
};
|
|
21
|
+
export declare function auditContent(result: AuditResult): ToolResult;
|
|
22
|
+
export declare function registerAuditTools(server: McpServer): void;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { withEngine } from "./with-engine.js";
|
|
2
|
+
import { sceneAudit } from "../../core/capabilities/audit/audit.js";
|
|
3
|
+
import { sceneAuditShape } from "../../core/capabilities/audit/args.js";
|
|
4
|
+
export function auditContent(result) {
|
|
5
|
+
if (!result.ok) {
|
|
6
|
+
return {
|
|
7
|
+
isError: true,
|
|
8
|
+
content: [
|
|
9
|
+
{
|
|
10
|
+
type: "text",
|
|
11
|
+
text: JSON.stringify({
|
|
12
|
+
ok: false,
|
|
13
|
+
tool: "summer_scene_audit",
|
|
14
|
+
failure_reason: result.failure_reason,
|
|
15
|
+
error: result.error,
|
|
16
|
+
...(result.hint ? { hint: result.hint } : {}),
|
|
17
|
+
...(result.detail ? { detail: result.detail } : {}),
|
|
18
|
+
}),
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const content = [];
|
|
24
|
+
if (result.image)
|
|
25
|
+
content.push({ type: "image", data: result.image.base64, mimeType: result.image.mime || "image/jpeg" });
|
|
26
|
+
content.push({ type: "text", text: JSON.stringify(result.summary) });
|
|
27
|
+
return { content };
|
|
28
|
+
}
|
|
29
|
+
export function registerAuditTools(server) {
|
|
30
|
+
server.tool("summer_scene_audit", `Audit a 3D scene in one fast, read-only call: every node and subnode is walked and likely visual and placement problems come back as a short list, sorted by severity, so you know exactly where to look. Each issue is a flag to LOOK at, never an auto-fix.
|
|
31
|
+
|
|
32
|
+
Checks (each can be picked with checks):
|
|
33
|
+
- through_hole: capped ray grids through every facade line (coplanar wall fronts); clusters of rays that pass the wall AND reach the far side of the building (a door insert narrower than its frame, a missing module, a seam). Walls, structure and inserts close an opening; props do not.
|
|
34
|
+
- exposed_edge: open outline edges of walls and facade members (bands, piers, corner blocks; cached per mesh) that nothing covers within 4-7 mm, seen from walkable space (eye points over open-sky floor cells, flood-filled from the scene's cameras and characters, sight lines not through a building), with a 2-60 cm reveal behind them, or a coplanar sheet continuing within 4 cm (seam) or 35 cm (gap). Warn on band pieces and when depth_step agrees, look otherwise; repeats group per piece type.
|
|
35
|
+
- open_fixture_end: open ends of run pieces (a mesh with two or more open rims of one size: pipe, duct or gutter sections, elbows, tees) that nothing joins within 2.5 cm (sleeve tolerance), seen from walkable space: a missing elbow, coupler, section or end piece (warn). A piece with one rim or rims of different sizes (a cap, a funnel, an outlet) is open by design.
|
|
36
|
+
- depth_step (look): ray rows across each visible facade side at its band levels and every 1.25 m: band recesses and missing runs, seams, modules standing proud, holes with something behind them; a hole next to a through_hole confirms it (warn -> error); runs a door-like opening covers are skipped.
|
|
37
|
+
- floor_gap: down rays over the floor tiles, along their seams, and from each tile edge to a wall within 1 m (bare strips at wall bases), classified by the FIRST surface hit: the void (error); an underlay over the floor's own lower surface such as a drain channel ("covers the floor", warn, not a hole); an underlay through a hole or strip. Areas are the missed rays' own footprints with the strip's size; a tile whose own mesh has holes is one issue for the piece.
|
|
38
|
+
- floating / sunken: support under each prop's footprint; gap over 2 cm, embed over 3 cm, measured against the first surface from above (the tile it is buried in, not the underlay under it); structure and pieces touching a wall well off the ground excluded.
|
|
39
|
+
- interpenetration: each prop's convex hulls against props, walls, structure and inserts; a deepest overlap over 3 cm, then every partner it cuts (up to 3).
|
|
40
|
+
- orientation (look): long props within 1.2 m of a wall more than 15 deg off parallel. It never says which way a piece should face.
|
|
41
|
+
- uv_stretch: per mesh resource, large triangles whose UV-to-world mapping is stretched over 8:1 or collapsed to a line, where an instance shows them (a reveal that inserts normally cover = warn).
|
|
42
|
+
- duplicate: the same scene at the same transform.
|
|
43
|
+
- z_fight: coplanar overlapping faces anywhere, from each mesh's planar face groups: between any two pieces (props, roofs, ledges, side walls, inserts against hosts, decals; opposite-facing only when both are double-sided) and between two surfaces of one mesh (once per mesh), plus the ray samples. Coplanar = a gap under twice the 24-bit depth step at the view distance (the nearest walkable eye point, camera or bookmark; 30 m without one) for the main camera's near/far; ev carries the overlap, gap, tolerance, surfaces, the plane's normal and the axis to nudge (nudge.world, nudge.local: a window can share its head or a jamb with its host, not its front). Warn over 0.05 m2 seen from a viewpoint; the material decides what is demoted to look, with the reason: render_priority, depth or normal offsets, a see-through (alpha) material, no depth test or depth writes.
|
|
44
|
+
- lights: meshes paired with more than the per-object limit of omni or spot lights (Compatibility: 8 each; light cuts off at seams), spot lights with spot_angle_attenuation under 3; shadowed light counts.
|
|
45
|
+
- transform: NaN, negative or non-uniform scale, a piece far out of bounds, and pieces left at the origin: an identity LOCAL transform under an identity parent, touching nothing and not one of a row of siblings (several sharing it warn, one alone is look; a module whose corner is the world origin is placed).
|
|
46
|
+
- resource: missing dependency files, MeshInstance3D without a mesh, surfaces without a material.
|
|
47
|
+
|
|
48
|
+
budget_ms (default 3000) bounds the editor time: each check gets a weighted share of it, and a check past its share stops and is marked counts.<check>.partial (the share it covered), never clean. The three gap detectors (exposed_edge, open_fixture_end, depth_step) run last on the time the other checks leave (band pieces and band rows first); rerun them alone when partial.
|
|
49
|
+
|
|
50
|
+
accept:[{key, reason}] (keys from issues[].key) records look and warn items you judged fine in res://.summer/audit-accept.json (the only file the audit writes); later audits count them (counts.<check>.accepted) but hide them until their evidence changes materially (severity rises, or the measured size moves by over 25%: shown again with accept_stale). Errors cannot be accepted; show_accepted lists them.
|
|
51
|
+
|
|
52
|
+
Returns at most 5 KB of JSON: counts per check, time per check (editor ms), the scene size, and ONE page of issues {n, check, sev (error|warn|look), path, pos (world), why, ev (evidence numbers: sizes, distances, angles, the ray to reproduce), next (the tool to use next), key (for accept)}. Page with offset/limit (next_offset names the next page); filter with checks, root (a subtree) and min_severity. render:"sheet" adds ONE inline image of the page's first 6 issues framed up close from their open side (a camera never behind a wall), each tile labelled #n.
|
|
53
|
+
|
|
54
|
+
Every check works on any scene from geometry, the engine's node and resource data and materials alone: never node or file names, never kit metadata. Each piece's role comes from its shape: see-through cards (every material alpha) are dressing; thin upright sheets are walls (facing their side with more face area); flat slabs whose tops cover their footprint are floors (raised ones with walls under them are roofs, a large one below the rest is the underlay); a piece inside a wall's rectangle that reaches through the wall where it is open is an insert; bands, piers and corner blocks touching a facade wall are structure; the rest are props up to 3.5 m.
|
|
55
|
+
|
|
56
|
+
Read-only: it audits the SAVED file in a private offscreen copy (ScenePreview), so the open tab never becomes unsaved, undo is untouched and nothing is saved (accept writes only its own file). Save the scene first. Failures are structured (failure_reason), never a silent fallback.`, sceneAuditShape, async (args) => withEngine(async (client) => {
|
|
57
|
+
const audit = await sceneAudit(client, args);
|
|
58
|
+
return audit.ok ? { audit } : { audit, failure_reason: audit.failure_reason };
|
|
59
|
+
}, { onResult: (wrapped) => auditContent(wrapped.audit) }));
|
|
60
|
+
}
|
|
@@ -200,7 +200,9 @@ After starting, confirm boot with summer_is_running (boot time varies — never
|
|
|
200
200
|
|
|
201
201
|
DETERMINISTIC RUNS (newer engines): seed / fixed_fps / time_scale pin THIS launch only (nothing is persisted). seed pins the game's GLOBAL RNG (randi/randf/randi_range/randf_range/randfn, Array.shuffle/pick_random) — it does NOT pin RandomNumberGenerator instances, scripts that call randomize(), rand_from_seed, wall-clock reads, or thread/IO/audio timing. fixed_fps decouples scene time from the wall clock so frame-count-derived state lands on the same frame run to run. The result's \`determinism\` block says whether the pins were applied (applied:false carries a reason: already_running, editor_run_args_override, launch_not_started) and restates seed_scope. If the result has NO determinism block although you sent a pin, the engine predates the params and the run is NOT reproducible — the tool says so; do not claim otherwise. Omitting every pin and instance parameter is exactly the v1 launch.
|
|
202
202
|
|
|
203
|
-
PLAYTEST LAUNCH (engine runtime-control build): instance + mode:'offscreen' spawn a disposable hidden instance (at most 3) that summer_game_probe / summer_game_input / summer_game_control / summer_runtime_* address by name — run two variants side by side for an A/B. deterministic:true (offscreen only) launches with --fixed-fps 60 --summer-seed --audio-driver Dummy and is what lets summer_game_input action:'replay' accept a seed; speed sets the user time scale on session start. The instance result reports session_attached; poll summer_game_control action:'instances' until attached:true before addressing it. Then: probe -> act -> step/probe -> assert (the agent-playtesting skill). Failure reasons: too_many_instances, instance_exists, session_timeout (child never attached — check summer_get_console), unsupported_mode, main_scene_not_configured. A game already running answers playing:true with determinism.applied:false — summer_stop first to apply seed/fixed_fps
|
|
203
|
+
PLAYTEST LAUNCH (engine runtime-control build): instance + mode:'offscreen' spawn a disposable hidden instance (at most 3) that summer_game_probe / summer_game_input / summer_game_control / summer_runtime_* address by name — run two variants side by side for an A/B. deterministic:true (offscreen only) launches with --fixed-fps 60 --summer-seed --audio-driver Dummy and is what lets summer_game_input action:'replay' accept a seed; speed sets the user time scale on session start. The instance result reports session_attached; poll summer_game_control action:'instances' until attached:true before addressing it. Then: probe -> act -> step/probe -> assert (the agent-playtesting skill). Failure reasons: too_many_instances, instance_exists, session_timeout (child never attached — check summer_get_console), unsupported_mode, main_scene_not_configured. A game already running answers playing:true with determinism.applied:false — summer_stop first to apply seed/fixed_fps.
|
|
204
|
+
|
|
205
|
+
MULTIPLAYER — LOCAL PLAY (Summer multiplayer games; engine with Local Play): players:N starts the game's authority headless plus N clients on this machine, each joining through the game's OWN Summer.client.join(SummerJoinTarget.queue(...)) — no account, login, Docker, CLI or local-only game code. The scenes and queue come from the project's summer.build.json and its WorldDefinition (client_entry_point + the headless_engine component entry_point); queue picks another declared queue — pass queue WITHOUT players to start that queue's minPlayers (a 4-player queue starts 4), or players to choose; spectators adds spectator clients. local_play.warnings flags a roster outside the queue's minPlayers..maxPlayers. The result's local_play block lists every process (label, role, persona) and the port; failure_reason local_play_unavailable says exactly what to declare. Every process attaches to the editor debugger: screenshots, input and summer_game_* go to the FIRST client, the authority's output is in summer_get_console, and summer_stop stops them all. A join for a different queue fails with a message naming both queues. It is not a proof of sign-in, matchmaking or hosted admission (staging). No local_play block although you sent players means the engine predates Local Play and ran ONE client — the tool says so.`, {
|
|
204
206
|
scene: z.string().optional().describe("Scene to run instead of main scene, e.g. 'res://levels/test_level.tscn'"),
|
|
205
207
|
...playGameExtensionSchema,
|
|
206
208
|
}, async (args) => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { withEngine, ToolInputError } from "./with-engine.js";
|
|
3
3
|
import { occurrenceCount, readTextPayload, safeProjectPath, validSha256, } from "../../core/capabilities/engine-ops.js";
|
|
4
|
+
import { readFileInputShape, readProjectFileWindow } from "../../core/capabilities/file-read.js";
|
|
5
|
+
import { GREP_DEFAULT_MAX_RESULTS, GREP_MAX_RESULTS, grepInputShape, grepProject, } from "../../core/capabilities/grep.js";
|
|
4
6
|
// MCP clients may issue tool calls concurrently. Keep the complete read->write
|
|
5
7
|
// transaction ordered for one project file while allowing unrelated files to
|
|
6
8
|
// proceed in parallel. The tail is always released in `finally`, so a rejected
|
|
@@ -32,10 +34,21 @@ async function withFileMutationTurn(projectIdHash, path, fn) {
|
|
|
32
34
|
export function registerFileTools(server) {
|
|
33
35
|
server.tool("summer_read_file", `Read a text file from the engine-bound project and return its full-file sha256 receipt.
|
|
34
36
|
|
|
35
|
-
Use the returned sha256 as expected_sha256 when overwriting an existing file. Paths must begin with res
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
Use the returned sha256 as expected_sha256 when overwriting an existing file. Paths must begin with res://.
|
|
38
|
+
|
|
39
|
+
READ BIG FILES IN PARTS instead of all at once:
|
|
40
|
+
- offset + limit page the file: lines by default (unit:'bytes' for a byte range on UTF-8 boundaries). The result's data.window gives start_line/end_line, total_lines, next_offset (null at the end) and eof.
|
|
41
|
+
- For JSON: json_path picks one value ('pieces.wall_a', 'items[3]'); keys keeps matching object keys (['wall_*']); keys_only lists key names only. data.json says what matched. offset/limit then page the selection.
|
|
42
|
+
The sha256 always covers the WHOLE file, so a windowed read still guards a later overwrite. Files over 1 MB can be paged only within their first 1 MB.`, readFileInputShape, async (args) => withEngine(async (client) => readProjectFileWindow(client, args)));
|
|
43
|
+
server.tool("summer_grep", `Search project files with a regular expression (ripgrep, through the engine) and get file + line + text per match, optionally with context lines around each.
|
|
44
|
+
|
|
45
|
+
Use it to find things in big files without reading them whole: every '"fits_into"' in a kit manifest, the scenes of a kit (glob '*.tscn'), where a signal handler is defined. Then read exactly the part you need with summer_read_file (offset/limit, or json_path for JSON).
|
|
46
|
+
|
|
47
|
+
- path: a res:// directory or file (default: the whole project; .godot/ and .import/ are never searched).
|
|
48
|
+
- glob: ripgrep --glob filter ('*.gd', '**/*.json', '!addons/**'). Ripgrep skips files ignored by .gitignore unless a glob names them.
|
|
49
|
+
- context_lines (0-10): lines before/after each match, as before[] / after[].
|
|
50
|
+
- max_results (default ${GREP_DEFAULT_MAX_RESULTS}, max ${GREP_MAX_RESULTS}) caps the matches; truncated:true says there were more. Lines are clipped to max_line_chars.
|
|
51
|
+
Case-insensitive unless case_sensitive:true. Read-only.`, grepInputShape, async (args) => withEngine(async (client) => grepProject(client, args)));
|
|
39
52
|
server.tool("summer_write_file", `Create or safely overwrite a complete text file through the identity-bound engine.
|
|
40
53
|
|
|
41
54
|
For a new file, set create_only:true. For an existing file, first call summer_read_file and pass its sha256 as expected_sha256. Exactly one guard is required; unguarded writes fail closed. Supports scripts, .tscn scenes, .tres resources, JSON, docs, and project config.`, {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { BOARD_ENDPOINT, boardArgsSchema, boardContent, boardQuery } from "../../core/capabilities/board.js";
|
|
2
3
|
import { imageGenerationArgsSchema } from "../../core/capabilities/image-generation.js";
|
|
4
|
+
import { buildMotionRequestBody, motionErrorHint, motionGenerationArgsSchema, motionJobFailureHint, } from "../../core/capabilities/motion-generation.js";
|
|
3
5
|
import { writeFile, mkdir } from "fs/promises";
|
|
4
6
|
import { tmpdir } from "os";
|
|
5
7
|
import { join } from "path";
|
|
@@ -16,6 +18,7 @@ const TOOL_BY_ENDPOINT = {
|
|
|
16
18
|
"/api/mcp/generate/motion": "summer_generate_motion",
|
|
17
19
|
"/api/mcp/generate/slice-asset-sheet": "summer_slice_asset_sheet",
|
|
18
20
|
"/api/mcp/workflows": "summer_get_studio_workflow",
|
|
21
|
+
[BOARD_ENDPOINT]: "summer_get_board",
|
|
19
22
|
};
|
|
20
23
|
// ---------------------------------------------------------------------------
|
|
21
24
|
// Shared helpers
|
|
@@ -253,6 +256,26 @@ handoff that MCP cannot perform automatically; do not pretend that stage ran.`,
|
|
|
253
256
|
return successResult(result.data);
|
|
254
257
|
});
|
|
255
258
|
// ========================================================================
|
|
259
|
+
// summer_get_board
|
|
260
|
+
// ========================================================================
|
|
261
|
+
server.tool("summer_get_board", `Read the person's approved planning board for this game: the look (palette,
|
|
262
|
+
description, picture), the characters, the place, the first-minute storyboard
|
|
263
|
+
and the cards they picked, with a version that changes when the board does.
|
|
264
|
+
|
|
265
|
+
The look and the picked cards come back as images you can see. Read the board at
|
|
266
|
+
the start of each build step and compare your screenshot against its images
|
|
267
|
+
(palette, shapes and proportions, camera angle, composition); fix the biggest
|
|
268
|
+
difference. Use the picked card pictures as referenceImageUrl for
|
|
269
|
+
summer_generate_image to make sprites and backgrounds in the same look.
|
|
270
|
+
|
|
271
|
+
Cloud tool — runs on Summer's servers and works WITHOUT the Summer Engine app open.
|
|
272
|
+
Requires authentication: run 'npx -y summer-engine@latest login' first.`, boardArgsSchema.shape, async (args) => {
|
|
273
|
+
const result = await mcpGet(BOARD_ENDPOINT, boardQuery(args), 45_000);
|
|
274
|
+
if (result.error)
|
|
275
|
+
return errorResult(result.error, result.data);
|
|
276
|
+
return { content: boardContent(result.data ?? {}) };
|
|
277
|
+
});
|
|
278
|
+
// ========================================================================
|
|
256
279
|
// summer_generate_image
|
|
257
280
|
// ========================================================================
|
|
258
281
|
server.tool("summer_generate_image", `Generate an image using AI models via Summer Engine Studio.
|
|
@@ -651,89 +674,74 @@ Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
|
|
|
651
674
|
// ========================================================================
|
|
652
675
|
// summer_generate_motion
|
|
653
676
|
//
|
|
654
|
-
//
|
|
655
|
-
//
|
|
656
|
-
//
|
|
657
|
-
//
|
|
658
|
-
//
|
|
659
|
-
//
|
|
660
|
-
//
|
|
677
|
+
// Backends exposed: "meshy-library" (curated humanoid mocap by name) and
|
|
678
|
+
// "text-to-motion" (Summer-hosted model, any of the caller's own rigs, from
|
|
679
|
+
// text prompts; default-off on the server until enabled, which answers 400
|
|
680
|
+
// backend_unavailable). The Studio route's "hunyuan-custom" stays hidden: it
|
|
681
|
+
// returns a generic skeleton FBX that is not retargeted onto the caller's
|
|
682
|
+
// rig. The shared zod shape + body builder live in
|
|
683
|
+
// core/capabilities/motion-generation.ts so `summer tool generate-motion`
|
|
684
|
+
// validates identically.
|
|
661
685
|
// ========================================================================
|
|
662
|
-
server.tool("summer_generate_motion", `Generate
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
- "meshy-library" —
|
|
666
|
-
|
|
667
|
-
real mocap quality.
|
|
686
|
+
server.tool("summer_generate_motion", `Generate animation clips for a rigged 3D model via Summer Engine Studio.
|
|
687
|
+
|
|
688
|
+
Backends (pick one):
|
|
689
|
+
- "meshy-library" (default) — a curated mocap clip by motionName on a
|
|
690
|
+
Summer-rigged humanoid (rigAssetId from summer_generate_3d with
|
|
691
|
+
options.rig=true). Fast (~30s), cheap (~$0.10), real mocap quality.
|
|
692
|
+
Names that always work: idle, walk, run, jump, attack; anything else must
|
|
693
|
+
be an exact library name.
|
|
694
|
+
- "text-to-motion" — custom 2-second clips (60 frames) from text prompts on
|
|
695
|
+
ANY of your own rigged models: humanoid, animal, creature, cartoon plant,
|
|
696
|
+
prop (GLB/FBX 3d_model, one skinned armature, 5-70 bones). Use it for
|
|
697
|
+
actions the library lacks (nod, bow, shrug, wave with the right arm) and
|
|
698
|
+
for non-humanoid rigs. Pass prompt or prompts (1-8), optional takes (1-4),
|
|
699
|
+
cfgScale (1.5-8, default 3; 5 for clearer gestures), and lockJoints for
|
|
700
|
+
rooted characters (e.g. ["Hips","Spine"] on a plant; never on characters
|
|
701
|
+
that walk). Human-style bone names (Hips, Spine, LeftArm...) animate far
|
|
702
|
+
better, even on non-humans. Jobs take ~1-2 min; result.assets lists one
|
|
703
|
+
animation asset per prompt x take.
|
|
704
|
+
|
|
705
|
+
Each clip (meshy: each motion; text-to-motion: each prompt x take) is billed.
|
|
706
|
+
State the clip list and estimated cost and confirm with the user before
|
|
707
|
+
spending.
|
|
668
708
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
By default, waits for completion (up to 5 min) and returns the result directly.
|
|
673
|
-
Set wait=false to get the jobId immediately and poll manually with summer_check_job.
|
|
674
|
-
|
|
675
|
-
Common motion names:
|
|
676
|
-
Locomotion: idle, idle_alert, idle_combat, walk, walk_back, run, sprint,
|
|
677
|
-
crouch_idle, crouch_walk, jump, jump_loop, jump_land
|
|
678
|
-
Combat: attack_sword, attack_punch, attack_kick, attack_bow, attack_cast,
|
|
679
|
-
block, dodge_left, dodge_right, hit_react, death
|
|
680
|
-
Social: wave, dance, sit_idle
|
|
681
|
-
|
|
682
|
-
Cost: ~$0.10 per clip. Confirm with user before spending.
|
|
709
|
+
By default, waits for completion (up to 10 min) and returns the result directly.
|
|
710
|
+
Set wait=false to get the jobId immediately and poll with summer_check_job.
|
|
711
|
+
Import finished clips with summer_import_asset_by_id.
|
|
683
712
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
713
|
+
Errors: backend_unavailable means text-to-motion is not enabled on this server
|
|
714
|
+
yet — use meshy-library for humanoids and do not retry. Job failures starting
|
|
715
|
+
"text_motion:" (no skinned armature, too many/few joints, unknown joint) are
|
|
716
|
+
input problems and are refunded; fix the rig or request instead of retrying.
|
|
687
717
|
|
|
688
718
|
Cloud tool — runs on Summer's servers and works WITHOUT the Summer Engine app open.
|
|
689
|
-
Requires authentication: run 'npx -y summer-engine@latest login' first.`, {
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
.enum(["meshy-library"])
|
|
695
|
-
.default("meshy-library")
|
|
696
|
-
.describe("Backend: meshy-library (only option today)"),
|
|
697
|
-
motionName: z
|
|
698
|
-
.string()
|
|
699
|
-
.describe("Curated motion name: walk, run, attack_sword, idle, jump, etc."),
|
|
700
|
-
// prompt + durationSeconds reserved for the hunyuan-custom backend (not
|
|
701
|
-
// shipped yet — see header comment).
|
|
702
|
-
wait: z
|
|
703
|
-
.boolean()
|
|
704
|
-
.default(true)
|
|
705
|
-
.describe("Wait for completion (default true, up to 5 min). Set false to get jobId immediately."),
|
|
706
|
-
options: z
|
|
707
|
-
.record(z.any())
|
|
708
|
-
.optional()
|
|
709
|
-
.describe("Backend-specific passthrough"),
|
|
710
|
-
}, async ({ rigAssetId, backend, motionName, wait, options }) => {
|
|
711
|
-
// Client-side validation
|
|
712
|
-
if (!motionName) {
|
|
713
|
-
return errorResult("motionName is required (e.g. 'walk', 'run', 'attack_sword'). See the tool description for the curated list.");
|
|
719
|
+
Requires authentication: run 'npx -y summer-engine@latest login' first.`, motionGenerationArgsSchema.shape, async (args) => {
|
|
720
|
+
// Client-side validation of the backend-specific rules.
|
|
721
|
+
const built = buildMotionRequestBody(args);
|
|
722
|
+
if ("error" in built) {
|
|
723
|
+
return errorResult(built.error);
|
|
714
724
|
}
|
|
715
|
-
const
|
|
716
|
-
rigAssetId,
|
|
717
|
-
backend,
|
|
718
|
-
motionName,
|
|
719
|
-
options,
|
|
720
|
-
};
|
|
721
|
-
const result = await mcpGenerate("/api/mcp/generate/motion", body);
|
|
725
|
+
const result = await mcpGenerate("/api/mcp/generate/motion", built.body);
|
|
722
726
|
if (result.error) {
|
|
723
|
-
|
|
727
|
+
const hint = motionErrorHint(result.data?.error);
|
|
728
|
+
return errorResult(result.error, hint ? { ...result.data, hint } : result.data);
|
|
724
729
|
}
|
|
725
730
|
const jobId = result.data?.jobId;
|
|
726
|
-
if (!wait || !jobId) {
|
|
731
|
+
if (!args.wait || !jobId) {
|
|
727
732
|
return successResult(result.data);
|
|
728
733
|
}
|
|
729
734
|
const pollResult = await pollJob(jobId);
|
|
730
735
|
if (pollResult.error) {
|
|
731
|
-
|
|
736
|
+
const hint = motionJobFailureHint(pollResult.error);
|
|
737
|
+
return errorResult(pollResult.error, { ...pollResult.data, jobId, ...(hint ? { hint } : {}) });
|
|
732
738
|
}
|
|
733
739
|
return successResult({
|
|
734
740
|
...pollResult.data,
|
|
735
741
|
jobId,
|
|
736
|
-
message:
|
|
742
|
+
message: args.backend === "text-to-motion"
|
|
743
|
+
? "Motion generation complete. result.assets lists one animation asset per prompt x take; import with summer_import_asset_by_id."
|
|
744
|
+
: "Motion generation complete. animationAssetId is in result.",
|
|
737
745
|
});
|
|
738
746
|
});
|
|
739
747
|
}
|