summer-engine 3.7.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -13
- package/.claude-plugin/plugin.json +25 -22
- package/.codex-plugin/plugin.json +8 -14
- package/.cursor-plugin/plugin.json +7 -13
- package/.factory-plugin/plugin.json +7 -13
- package/AGENTS.md +19 -12
- package/CHANGELOG.md +112 -0
- package/GEMINI.md +3 -3
- package/README.md +111 -31
- package/assets/icon.png +0 -0
- package/commands/start.md +71 -0
- package/commands/summer.md +5 -3
- package/dist/cli/banner.js +3 -0
- package/dist/cli/commands/login.d.ts +27 -0
- package/dist/cli/commands/login.js +58 -12
- package/dist/cli/commands/ops.d.ts +47 -0
- package/dist/cli/commands/ops.js +301 -0
- package/dist/cli/commands/setup.d.ts +2 -0
- package/dist/cli/commands/setup.js +37 -12
- package/dist/cli/commands/skills.js +11 -7
- package/dist/cli/index.js +7 -0
- package/dist/core/agent-host.d.ts +65 -0
- package/dist/core/agent-host.js +193 -0
- package/dist/core/capabilities/agent-playbook.d.ts +3 -0
- package/dist/core/capabilities/agent-playbook.js +54 -2
- package/dist/core/capabilities/apps.d.ts +341 -0
- package/dist/core/capabilities/apps.js +353 -0
- package/dist/core/capabilities/doctor.d.ts +3 -0
- package/dist/core/capabilities/doctor.js +20 -15
- package/dist/core/capabilities/enable-plugin.d.ts +27 -0
- package/dist/core/capabilities/enable-plugin.js +75 -0
- package/dist/core/capabilities/fabricate-mesh.d.ts +2 -2
- package/dist/core/capabilities/game-task-plan.d.ts +12 -6
- package/dist/core/capabilities/game-task-plan.js +80 -5
- package/dist/core/capabilities/motion-generation.js +2 -2
- package/dist/core/capabilities/navigation/open.d.ts +6 -2
- package/dist/core/capabilities/navigation/open.js +3 -0
- package/dist/core/capabilities/publish-build.js +2 -0
- package/dist/core/capabilities/runtime-control.d.ts +4 -4
- package/dist/core/capabilities/scene-script-target.d.ts +17 -0
- package/dist/core/capabilities/scene-script-target.js +70 -0
- package/dist/core/capabilities/sfx-choices.d.ts +4 -0
- package/dist/core/capabilities/sfx-choices.js +13 -6
- package/dist/core/capabilities/tool-dispatch.d.ts +12 -3
- package/dist/core/capabilities/tool-dispatch.js +130 -46
- package/dist/core/capability-skew.js +4 -0
- package/dist/core/embeddings.d.ts +2 -0
- package/dist/core/embeddings.js +1 -1
- package/dist/core/error-codes.d.ts +62 -0
- package/dist/core/error-codes.js +97 -0
- package/dist/core/format.d.ts +2 -0
- package/dist/core/format.js +2 -1
- package/dist/core/hosted-mcp.d.ts +22 -0
- package/dist/core/hosted-mcp.js +56 -1
- package/dist/core/library-read.js +5 -0
- package/dist/core/library-search.js +2 -1
- package/dist/core/oauth.js +4 -0
- package/dist/core/ops/catalog.d.ts +41 -0
- package/dist/core/ops/catalog.js +145 -0
- package/dist/core/ops/cloud.d.ts +56 -0
- package/dist/core/ops/cloud.js +175 -0
- package/dist/core/ops/contract.d.ts +119 -0
- package/dist/core/ops/contract.js +142 -0
- package/dist/core/ops/engine-answer.d.ts +25 -0
- package/dist/core/ops/engine-answer.js +117 -0
- package/dist/core/ops/engine.d.ts +55 -0
- package/dist/core/ops/engine.js +649 -0
- package/dist/core/ops/save-files.d.ts +78 -0
- package/dist/core/ops/save-files.js +419 -0
- package/dist/core/ops/search.d.ts +9 -0
- package/dist/core/ops/search.js +55 -0
- package/dist/core/skills-registry.d.ts +16 -1
- package/dist/core/skills-registry.js +35 -2
- package/dist/core/telemetry.d.ts +32 -0
- package/dist/core/telemetry.js +38 -10
- package/dist/core/tool-profiles.d.ts +25 -0
- package/dist/core/tool-profiles.js +41 -0
- package/dist/installer/agent-config.d.ts +17 -4
- package/dist/installer/agent-config.js +22 -6
- package/dist/installer/agent-table.d.ts +3 -0
- package/dist/installer/agent-table.js +10 -7
- package/dist/installer/setup.d.ts +2 -0
- package/dist/installer/setup.js +9 -4
- package/dist/installer/version-check.d.ts +29 -9
- package/dist/installer/version-check.js +81 -28
- package/dist/mcp/command.js +7 -0
- package/dist/mcp/hosted-mount.d.ts +27 -2
- package/dist/mcp/hosted-mount.js +66 -24
- package/dist/mcp/legacy-toolset.d.ts +27 -0
- package/dist/mcp/legacy-toolset.js +43 -0
- package/dist/mcp/ops-surface.d.ts +59 -0
- package/dist/mcp/ops-surface.js +443 -0
- package/dist/mcp/server.d.ts +35 -11
- package/dist/mcp/server.js +236 -89
- package/dist/mcp/tool-results.d.ts +26 -0
- package/dist/mcp/tool-results.js +81 -0
- package/dist/mcp/tool-surface.d.ts +65 -0
- package/dist/mcp/tool-surface.js +317 -0
- package/dist/mcp/tools/app-tools.d.ts +2 -0
- package/dist/mcp/tools/app-tools.js +71 -0
- package/dist/mcp/tools/asset-tools.js +55 -53
- package/dist/mcp/tools/audit-tools.js +21 -21
- package/dist/mcp/tools/debug-tools.js +6 -6
- package/dist/mcp/tools/fabricate-tools.js +6 -6
- package/dist/mcp/tools/generate-tools.js +76 -70
- package/dist/mcp/tools/project-tools.d.ts +9 -4
- package/dist/mcp/tools/project-tools.js +16 -10
- package/dist/mcp/tools/scene-tools.js +12 -23
- package/dist/mcp/tools/script-tools.js +9 -5
- package/dist/mcp/tools/with-engine.d.ts +6 -0
- package/dist/mcp/tools/with-engine.js +19 -0
- package/gemini-extension.json +6 -12
- package/hooks/pre-commit-doctor.sh +5 -4
- package/hooks/session-start.sh +24 -28
- package/integrations/claude-desktop/README.md +1 -1
- package/integrations/copilot-jetbrains/README.md +1 -1
- package/integrations/junie/README.md +1 -1
- package/integrations/lm-studio/README.md +1 -1
- package/integrations/trae/README.md +1 -1
- package/integrations/visual-studio/README.md +1 -1
- package/library/references/mcp-tools-reference/mcp-tools-reference.md +85 -35
- package/library/references/mcp-tools-reference/resource.yaml +1 -1
- package/library/references/product-map/resource.yaml +2 -2
- package/library/skills/3d-lighting/SKILL.md +53 -28
- package/library/skills/3d-lighting/resource.yaml +1 -1
- package/library/skills/README.md +126 -116
- package/library/skills/adaptive-music/SKILL.md +19 -23
- package/library/skills/adaptive-music/resource.yaml +1 -1
- package/library/skills/agent-playtesting/SKILL.md +1 -1
- package/library/skills/agent-playtesting/resource.yaml +1 -1
- package/library/skills/ai-characters-in-games/SKILL.md +1 -1
- package/library/skills/ai-characters-in-games/resource.yaml +1 -1
- package/library/skills/ambient-bed/SKILL.md +22 -13
- package/library/skills/ambient-bed/resource.yaml +1 -1
- package/library/skills/animated-loop/SKILL.md +41 -32
- package/library/skills/animated-loop/resource.yaml +1 -1
- package/library/skills/animation-tree/SKILL.md +1 -1
- package/library/skills/animation-tree/resource.yaml +1 -1
- package/library/skills/art-direction/SKILL.md +3 -3
- package/library/skills/art-direction/resource.yaml +1 -1
- package/library/skills/asset-strategy/SKILL.md +21 -4
- package/library/skills/asset-strategy/resource.yaml +2 -1
- package/library/skills/audio-direction/SKILL.md +10 -10
- package/library/skills/audio-direction/resource.yaml +1 -1
- package/library/skills/auto-fire-targeting/SKILL.md +1 -1
- package/library/skills/auto-fire-targeting/resource.yaml +1 -1
- package/library/skills/bounded-engine-runs/SKILL.md +1 -1
- package/library/skills/bounded-engine-runs/resource.yaml +1 -1
- package/library/skills/brainstorm-game/SKILL.md +1 -1
- package/library/skills/brainstorm-game/resource.yaml +1 -1
- package/library/skills/brainstorming/SKILL.md +1 -1
- package/library/skills/brainstorming/resource.yaml +1 -1
- package/library/skills/browse-templates/SKILL.md +1 -1
- package/library/skills/browse-templates/resource.yaml +1 -1
- package/library/skills/camera-rigs/SKILL.md +2 -2
- package/library/skills/camera-rigs/resource.yaml +1 -1
- package/library/skills/celeste-momentum-platforming/resource.yaml +1 -0
- package/library/skills/character-animation-wiring/SKILL.md +4 -4
- package/library/skills/character-animation-wiring/resource.yaml +1 -1
- package/library/skills/character-model/SKILL.md +55 -47
- package/library/skills/character-model/resource.yaml +1 -1
- package/library/skills/character-movement/SKILL.md +3 -3
- package/library/skills/character-movement/resource.yaml +1 -1
- package/library/skills/character-portrait/SKILL.md +24 -19
- package/library/skills/character-portrait/resource.yaml +1 -1
- package/library/skills/cinematic-cutscene/SKILL.md +58 -46
- package/library/skills/cinematic-cutscene/resource.yaml +1 -1
- package/library/skills/combat-basics/SKILL.md +1 -1
- package/library/skills/combat-basics/resource.yaml +1 -1
- package/library/skills/compatibility-renderer-traps/SKILL.md +1 -1
- package/library/skills/compatibility-renderer-traps/resource.yaml +1 -1
- package/library/skills/concept-art/SKILL.md +16 -12
- package/library/skills/concept-art/resource.yaml +1 -1
- package/library/skills/concept-to-level/SKILL.md +239 -0
- package/library/skills/concept-to-level/references/technical-rules.md +150 -0
- package/library/skills/concept-to-level/resource.yaml +44 -0
- package/library/skills/create-asset-sheet/SKILL.md +19 -13
- package/library/skills/create-asset-sheet/resource.yaml +1 -1
- package/library/skills/debug/SKILL.md +2 -2
- package/library/skills/debug/resource.yaml +1 -1
- package/library/skills/debugging-game-feel/SKILL.md +1 -1
- package/library/skills/debugging-game-feel/resource.yaml +1 -1
- package/library/skills/design-level/SKILL.md +23 -35
- package/library/skills/design-level/resource.yaml +1 -1
- package/library/skills/design-mechanic/SKILL.md +1 -1
- package/library/skills/design-mechanic/resource.yaml +1 -1
- package/library/skills/design-npc/SKILL.md +22 -24
- package/library/skills/design-npc/resource.yaml +1 -1
- package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
- package/library/skills/diagnosing-perf-regressions/resource.yaml +1 -1
- package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
- package/library/skills/driving-the-editor-ui/resource.yaml +1 -1
- package/library/skills/environment-kit/SKILL.md +20 -16
- package/library/skills/environment-kit/resource.yaml +1 -1
- package/library/skills/export-and-ship/SKILL.md +6 -6
- package/library/skills/export-and-ship/resource.yaml +1 -1
- package/library/skills/fabricating-assets/SKILL.md +7 -7
- package/library/skills/fabricating-assets/resource.yaml +3 -3
- package/library/skills/facial-and-lipsync/SKILL.md +14 -15
- package/library/skills/facial-and-lipsync/resource.yaml +1 -1
- package/library/skills/fps-controller/SKILL.md +33 -41
- package/library/skills/fps-controller/resource.yaml +1 -1
- package/library/skills/game-feel/SKILL.md +8 -8
- package/library/skills/game-feel/resource.yaml +1 -1
- package/library/skills/gameskill/SKILL.md +4 -4
- package/library/skills/gameskill/resource.yaml +1 -1
- package/library/skills/gdscript-patterns/SKILL.md +1 -1
- package/library/skills/gdscript-patterns/resource.yaml +1 -1
- package/library/skills/generate-motion/SKILL.md +30 -21
- package/library/skills/generate-motion/resource.yaml +1 -1
- package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
- package/library/skills/godogen-visual-proof-game-generation/resource.yaml +1 -0
- package/library/skills/grow-analytics/SKILL.md +3 -3
- package/library/skills/grow-analytics/resource.yaml +1 -1
- package/library/skills/headless-scripting/SKILL.md +1 -1
- package/library/skills/headless-scripting/resource.yaml +1 -1
- package/library/skills/in-game-purchases/SKILL.md +1 -1
- package/library/skills/in-game-purchases/resource.yaml +1 -1
- package/library/skills/instantiate-asset-pack/SKILL.md +2 -2
- package/library/skills/instantiate-asset-pack/resource.yaml +1 -1
- package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +1 -0
- package/library/skills/make-game/SKILL.md +4 -4
- package/library/skills/make-game/references/2d-platformer.md +1 -1
- package/library/skills/make-game/references/3d-fps.md +1 -1
- package/library/skills/make-game/references/3d-horror.md +1 -1
- package/library/skills/make-game/references/3d-third-person.md +2 -2
- package/library/skills/make-game/resource.yaml +1 -1
- package/library/skills/multiplayer/SKILL.md +1 -1
- package/library/skills/multiplayer/resource.yaml +1 -1
- package/library/skills/multiplayer-movement/SKILL.md +1 -1
- package/library/skills/multiplayer-movement/resource.yaml +1 -1
- package/library/skills/multiplayer-project/SKILL.md +1 -1
- package/library/skills/multiplayer-project/resource.yaml +1 -1
- package/library/skills/multiplayer-publish/SKILL.md +8 -7
- package/library/skills/multiplayer-publish/resource.yaml +3 -3
- package/library/skills/multiplayer-state/SKILL.md +1 -1
- package/library/skills/multiplayer-state/resource.yaml +1 -1
- package/library/skills/multiplayer-testing/SKILL.md +1 -1
- package/library/skills/multiplayer-testing/resource.yaml +1 -1
- package/library/skills/music-track/SKILL.md +22 -13
- package/library/skills/music-track/resource.yaml +1 -1
- package/library/skills/navigate-summer/SKILL.md +11 -9
- package/library/skills/navigate-summer/resource.yaml +1 -1
- package/library/skills/new-project/SKILL.md +1 -1
- package/library/skills/new-project/resource.yaml +1 -1
- package/library/skills/organic-model/SKILL.md +24 -18
- package/library/skills/organic-model/resource.yaml +1 -1
- package/library/skills/pixel-art/SKILL.md +27 -23
- package/library/skills/pixel-art/resource.yaml +1 -1
- package/library/skills/play/SKILL.md +1 -1
- package/library/skills/play/resource.yaml +1 -1
- package/library/skills/playtesting-a-feature/SKILL.md +1 -1
- package/library/skills/playtesting-a-feature/resource.yaml +1 -1
- package/library/skills/procedural-animation/SKILL.md +20 -16
- package/library/skills/procedural-animation/resource.yaml +1 -1
- package/library/skills/prop-model/SKILL.md +25 -19
- package/library/skills/prop-model/resource.yaml +1 -1
- package/library/skills/psx-retro-rendering/resource.yaml +1 -0
- package/library/skills/publish-your-game/SKILL.md +16 -6
- package/library/skills/publish-your-game/resource.yaml +3 -3
- package/library/skills/realtime-wet-surfaces/resource.yaml +1 -0
- package/library/skills/release-readiness/SKILL.md +1 -1
- package/library/skills/release-readiness/resource.yaml +1 -1
- package/library/skills/remote-deploy/SKILL.md +1 -1
- package/library/skills/remote-deploy/resource.yaml +1 -1
- package/library/skills/retarget/SKILL.md +23 -20
- package/library/skills/retarget/resource.yaml +1 -1
- package/library/skills/running-in-the-cloud/SKILL.md +1 -1
- package/library/skills/running-in-the-cloud/resource.yaml +1 -1
- package/library/skills/save-load/SKILL.md +1 -1
- package/library/skills/save-load/resource.yaml +1 -1
- package/library/skills/scene-composition/SKILL.md +1 -1
- package/library/skills/scene-composition/resource.yaml +1 -1
- package/library/skills/scene-hierarchy-design/SKILL.md +2 -2
- package/library/skills/scene-hierarchy-design/resource.yaml +1 -1
- package/library/skills/scene-scripting/SKILL.md +66 -636
- package/library/skills/scene-scripting/references/ctx-api.md +184 -0
- package/library/skills/scene-scripting/references/recipes-2d-ui.md +193 -0
- package/library/skills/scene-scripting/references/recipes-3d.md +280 -0
- package/library/skills/scene-scripting/resource.yaml +4 -4
- package/library/skills/scene-to-level/SKILL.md +2 -2
- package/library/skills/scene-to-level/resource.yaml +1 -1
- package/library/skills/skill-create/resource.yaml +1 -0
- package/library/skills/skill-improve/resource.yaml +1 -0
- package/library/skills/skill-test/SKILL.md +2 -2
- package/library/skills/skill-test/resource.yaml +1 -0
- package/library/skills/skintokens-auto-rigging/resource.yaml +1 -0
- package/library/skills/skybox-panorama/SKILL.md +27 -21
- package/library/skills/skybox-panorama/resource.yaml +1 -1
- package/library/skills/sound-effect/SKILL.md +31 -20
- package/library/skills/sound-effect/resource.yaml +1 -1
- package/library/skills/spatial-placement/SKILL.md +14 -9
- package/library/skills/spatial-placement/resource.yaml +1 -1
- package/library/skills/sprite-sheet/SKILL.md +32 -27
- package/library/skills/sprite-sheet/resource.yaml +1 -1
- package/library/skills/store-art/SKILL.md +3 -3
- package/library/skills/store-art/resource.yaml +2 -2
- package/library/skills/store-listing/SKILL.md +3 -3
- package/library/skills/store-listing/resource.yaml +2 -2
- package/library/skills/summer-analytics/SKILL.md +7 -5
- package/library/skills/summer-analytics/resource.yaml +2 -2
- package/library/skills/summer-apps/SKILL.md +168 -0
- package/library/skills/summer-apps/manifest.md +57 -0
- package/library/skills/summer-apps/minimal-app.md +183 -0
- package/library/skills/summer-apps/resource.yaml +36 -0
- package/library/skills/summer-apps/sdk-reference.md +135 -0
- package/library/skills/summer-apps-design/SKILL.md +197 -0
- package/library/skills/summer-apps-design/resource.yaml +23 -0
- package/library/skills/summer-assets/SKILL.md +56 -0
- package/library/skills/summer-assets/resource.yaml +34 -0
- package/library/skills/summer-store/SKILL.md +1 -1
- package/library/skills/text-to-motion/SKILL.md +30 -23
- package/library/skills/text-to-motion/prompts-and-controls.md +5 -5
- package/library/skills/text-to-motion/resource.yaml +1 -1
- package/library/skills/text-to-motion/rigging-for-text-motion.md +2 -2
- package/library/skills/tileable-texture/SKILL.md +19 -15
- package/library/skills/tileable-texture/resource.yaml +1 -1
- package/library/skills/trailer-shot/SKILL.md +28 -24
- package/library/skills/trailer-shot/resource.yaml +1 -1
- package/library/skills/tune-performance/SKILL.md +6 -6
- package/library/skills/tune-performance/resource.yaml +1 -1
- package/library/skills/ui-basics/SKILL.md +41 -36
- package/library/skills/ui-basics/resource.yaml +1 -1
- package/library/skills/ui-graphics/SKILL.md +47 -38
- package/library/skills/ui-graphics/resource.yaml +1 -1
- package/library/skills/use-widget-asset/SKILL.md +1 -1
- package/library/skills/use-widget-asset/resource.yaml +1 -1
- package/library/skills/using-summer/SKILL.md +7 -5
- package/library/skills/using-summer/resource.yaml +1 -1
- package/library/skills/vehicle-model/SKILL.md +65 -57
- package/library/skills/vehicle-model/resource.yaml +1 -1
- package/library/skills/verification-before-completion/SKILL.md +1 -1
- package/library/skills/verification-before-completion/resource.yaml +1 -1
- package/library/skills/verifying-scenes/SKILL.md +2 -2
- package/library/skills/verifying-scenes/resource.yaml +1 -1
- package/library/skills/vfx-dissolve/SKILL.md +2 -2
- package/library/skills/vfx-dissolve/resource.yaml +1 -1
- package/library/skills/vfx-fire/SKILL.md +15 -41
- package/library/skills/vfx-fire/resource.yaml +1 -1
- package/library/skills/vfx-hit-spark/SKILL.md +1 -1
- package/library/skills/vfx-hit-spark/resource.yaml +1 -1
- package/library/skills/vfx-lightning/SKILL.md +7 -16
- package/library/skills/vfx-lightning/resource.yaml +1 -1
- package/library/skills/vfx-magic-glow/SKILL.md +23 -32
- package/library/skills/vfx-magic-glow/resource.yaml +1 -1
- package/library/skills/vfx-muzzle-flash/SKILL.md +20 -35
- package/library/skills/vfx-muzzle-flash/resource.yaml +1 -1
- package/library/skills/vfx-smoke/SKILL.md +13 -31
- package/library/skills/vfx-smoke/resource.yaml +1 -1
- package/library/skills/vfx-water-ripple/SKILL.md +12 -31
- package/library/skills/vfx-water-ripple/resource.yaml +1 -1
- package/library/skills/voice-line/SKILL.md +71 -40
- package/library/skills/voice-line/resource.yaml +1 -1
- package/library/skills/web-and-touch-input/SKILL.md +1 -1
- package/library/skills/web-and-touch-input/resource.yaml +1 -1
- package/library/skills/web-compatibility-look/SKILL.md +1 -1
- package/library/skills/web-compatibility-look/resource.yaml +1 -1
- package/library/skills/world-building-3d/SKILL.md +1 -1
- package/library/skills/world-building-3d/resource.yaml +1 -1
- package/library/skills/writing-skills/resource.yaml +1 -0
- package/library/tools/add-node/GUIDE.md +14 -0
- package/library/tools/align-distribute-3d/GUIDE.md +7 -0
- package/library/tools/app-call/resource.yaml +59 -0
- package/library/tools/app-create/resource.yaml +67 -0
- package/library/tools/app-data/resource.yaml +74 -0
- package/library/tools/app-dock/resource.yaml +59 -0
- package/library/tools/app-events/resource.yaml +68 -0
- package/library/tools/app-get/resource.yaml +46 -0
- package/library/tools/app-guide/resource.yaml +55 -0
- package/library/tools/app-list/resource.yaml +48 -0
- package/library/tools/app-page/resource.yaml +74 -0
- package/library/tools/app-publish/resource.yaml +90 -0
- package/library/tools/app-report-gap/resource.yaml +58 -0
- package/library/tools/app-screenshot/resource.yaml +103 -0
- package/library/tools/app-tools/resource.yaml +46 -0
- package/library/tools/app-update/resource.yaml +68 -0
- package/library/tools/attach-to-surface/GUIDE.md +15 -0
- package/library/tools/batch/GUIDE.md +27 -0
- package/library/tools/camera-bookmark/GUIDE.md +12 -0
- package/library/tools/capture-gameplay/GUIDE.md +3 -0
- package/library/tools/capture-gameplay/resource.yaml +3 -3
- package/library/tools/check-job/resource.yaml +1 -1
- package/library/tools/clear-console/GUIDE.md +3 -0
- package/library/tools/connect-ports/GUIDE.md +9 -0
- package/library/tools/connect-signal/GUIDE.md +14 -0
- package/library/tools/create-debug-report/GUIDE.md +10 -0
- package/library/tools/create-scene/GUIDE.md +10 -0
- package/library/tools/debug-views/GUIDE.md +7 -0
- package/library/tools/enable-plugin/GUIDE.md +3 -0
- package/library/tools/enable-plugin/resource.yaml +53 -0
- package/library/tools/export-game/GUIDE.md +3 -0
- package/library/tools/export-game/resource.yaml +3 -3
- package/library/tools/export-templates/GUIDE.md +3 -0
- package/library/tools/fabricate-3d/GUIDE.md +19 -0
- package/library/tools/frame-nodes/GUIDE.md +9 -0
- package/library/tools/frame-shot/GUIDE.md +9 -0
- package/library/tools/game-control/GUIDE.md +9 -0
- package/library/tools/game-input/GUIDE.md +9 -0
- package/library/tools/game-probe/GUIDE.md +9 -0
- package/library/tools/generate-3d/resource.yaml +3 -3
- package/library/tools/generate-motion/resource.yaml +2 -2
- package/library/tools/get-console/GUIDE.md +9 -0
- package/library/tools/get-console/resource.yaml +5 -0
- package/library/tools/get-debugger-errors/GUIDE.md +7 -0
- package/library/tools/get-debugger-errors/resource.yaml +5 -0
- package/library/tools/get-debugger-warnings/GUIDE.md +7 -0
- package/library/tools/get-debugger-warnings/resource.yaml +5 -0
- package/library/tools/get-diagnostics/GUIDE.md +13 -0
- package/library/tools/get-project-context/GUIDE.md +25 -0
- package/library/tools/get-runtime-tree/GUIDE.md +7 -0
- package/library/tools/get-runtime-tree/resource.yaml +5 -0
- package/library/tools/get-scene-tree/GUIDE.md +11 -0
- package/library/tools/get-scene-tree/resource.yaml +5 -0
- package/library/tools/get-script-errors/GUIDE.md +5 -0
- package/library/tools/grep/GUIDE.md +11 -0
- package/library/tools/import-asset/GUIDE.md +8 -0
- package/library/tools/import-asset-by-id/GUIDE.md +12 -0
- package/library/tools/import-from-url/GUIDE.md +10 -0
- package/library/tools/import-from-url-batch/GUIDE.md +3 -0
- package/library/tools/import-hdri/GUIDE.md +16 -0
- package/library/tools/input-map-bind/GUIDE.md +11 -0
- package/library/tools/inspect-asset/GUIDE.md +14 -0
- package/library/tools/inspect-asset/resource.yaml +5 -0
- package/library/tools/inspect-node/GUIDE.md +11 -0
- package/library/tools/inspect-node/resource.yaml +5 -0
- package/library/tools/inspect-resource/GUIDE.md +7 -0
- package/library/tools/inspect-resource/resource.yaml +5 -0
- package/library/tools/inspect-runtime-node/GUIDE.md +7 -0
- package/library/tools/inspect-runtime-node/resource.yaml +5 -0
- package/library/tools/instantiate-scene/GUIDE.md +12 -0
- package/library/tools/is-running/GUIDE.md +3 -0
- package/library/tools/measure/GUIDE.md +8 -0
- package/library/tools/navigation-probe/GUIDE.md +9 -0
- package/library/tools/open/resource.yaml +2 -2
- package/library/tools/open-main-scene/GUIDE.md +6 -0
- package/library/tools/open-scene/GUIDE.md +8 -0
- package/library/tools/place-adjacent/GUIDE.md +7 -0
- package/library/tools/play/GUIDE.md +13 -0
- package/library/tools/project-setting/GUIDE.md +9 -0
- package/library/tools/publish-build/resource.yaml +6 -6
- package/library/tools/raycast/GUIDE.md +7 -0
- package/library/tools/read-file/GUIDE.md +10 -0
- package/library/tools/read-library/resource.yaml +5 -0
- package/library/tools/recent-events/GUIDE.md +7 -0
- package/library/tools/remove-node/GUIDE.md +3 -0
- package/library/tools/repeat-along/GUIDE.md +5 -0
- package/library/tools/replace-node/GUIDE.md +9 -0
- package/library/tools/replace-text/GUIDE.md +5 -0
- package/library/tools/run-editor-script/GUIDE.md +16 -0
- package/library/tools/run-script/GUIDE.md +30 -0
- package/library/tools/run-script/resource.yaml +6 -3
- package/library/tools/runtime-animate/GUIDE.md +7 -0
- package/library/tools/runtime-call/GUIDE.md +7 -0
- package/library/tools/runtime-set/GUIDE.md +9 -0
- package/library/tools/runtime-spawn/GUIDE.md +9 -0
- package/library/tools/save-scene/GUIDE.md +3 -0
- package/library/tools/scene-audit/GUIDE.md +29 -0
- package/library/tools/screenshot/GUIDE.md +17 -0
- package/library/tools/select-node/GUIDE.md +3 -0
- package/library/tools/set-prop/GUIDE.md +23 -0
- package/library/tools/set-resource-property/GUIDE.md +8 -0
- package/library/tools/shot-sheet/GUIDE.md +7 -0
- package/library/tools/snap-to-surface/GUIDE.md +17 -0
- package/library/tools/snapshot-diff/GUIDE.md +7 -0
- package/library/tools/starcast/GUIDE.md +12 -0
- package/library/tools/stop/GUIDE.md +3 -0
- package/library/tools/test-placement/GUIDE.md +7 -0
- package/library/tools/ui-actions/GUIDE.md +12 -0
- package/library/tools/ui-activate/GUIDE.md +11 -0
- package/library/tools/ui-screenshot/GUIDE.md +9 -0
- package/library/tools/ui-tree/GUIDE.md +10 -0
- package/library/tools/wait-for-event/GUIDE.md +11 -0
- package/library/tools/world-snapshot/GUIDE.md +9 -0
- package/library/tools/write-file/GUIDE.md +5 -0
- package/library/tools/zoom/GUIDE.md +5 -0
- package/package.json +6 -4
- package/registry/generated/aliases.json +15 -0
- package/registry/generated/counts.json +3 -3
- package/registry/generated/gemini-extension.json +6 -12
- package/registry/generated/index.json +1155 -408
- package/registry/generated/marketplace.claude.json +2 -13
- package/registry/generated/plugin.claude.json +25 -22
- package/registry/generated/plugin.codex.json +8 -14
- package/registry/generated/plugin.cursor.json +7 -13
- package/registry/generated/plugin.factory.json +7 -13
- package/registry/generated/server.json +34 -0
- package/registry/generated/skills-index.md +126 -116
- package/registry/generated/skills-registry.json +178 -113
- package/registry/operations/fixtures/invalid-deprecated-without-replacement.json +60 -0
- package/registry/operations/fixtures/invalid-name.json +60 -0
- package/registry/operations/fixtures/invalid-publish-without-owner.json +82 -0
- package/registry/operations/fixtures/invalid-spend-without-estimate.json +42 -0
- package/registry/operations/fixtures/invalid-unknown-field.json +61 -0
- package/registry/operations/fixtures/valid-player-facing.json +82 -0
- package/registry/operations/fixtures/valid-read.json +60 -0
- package/registry/operations/fixtures/valid-spend.json +43 -0
- package/registry/operations/legacy-names.json +1206 -0
- package/registry/schemas/allowed-hosts.json +4 -2
- package/registry/schemas/operation.schema.json +318 -0
- package/registry/schemas/skill.schema.json +4 -0
- package/CLAUDE.md +0 -7
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { loadLibraryIndex } from "../core/library-search.js";
|
|
3
|
+
import { PROFILES, TOOLSETS, parseProfile } from "../core/tool-profiles.js";
|
|
4
|
+
/**
|
|
5
|
+
* The shape of the MCP tool surface: which toolset each tool belongs to, each
|
|
6
|
+
* local tool's annotations, which results are capped, and which calls count
|
|
7
|
+
* as single scene edits. Read by server.ts (registration, results) and, with
|
|
8
|
+
* the profiles in core/tool-profiles.ts, by hosted-mount.ts (which hosted
|
|
9
|
+
* tools a profile mounts).
|
|
10
|
+
*
|
|
11
|
+
* Tool names never change here: a profile only leaves tools out.
|
|
12
|
+
*/
|
|
13
|
+
export { TOOLSETS, PROFILES, PROFILE_TOOL_LIMIT } from "../core/tool-profiles.js";
|
|
14
|
+
const LOCAL_TOOLSETS = {
|
|
15
|
+
core: [
|
|
16
|
+
"summer_search_library",
|
|
17
|
+
"summer_read_library",
|
|
18
|
+
"summer_library_feedback",
|
|
19
|
+
"summer_get_agent_playbook",
|
|
20
|
+
"summer_start_game_task",
|
|
21
|
+
"summer_open",
|
|
22
|
+
],
|
|
23
|
+
assets: [
|
|
24
|
+
"summer_generate_3d",
|
|
25
|
+
"summer_generate_audio",
|
|
26
|
+
"summer_generate_image",
|
|
27
|
+
"summer_generate_motion",
|
|
28
|
+
"summer_generate_sfx_choices",
|
|
29
|
+
"summer_generate_video",
|
|
30
|
+
"summer_check_job",
|
|
31
|
+
"summer_get_choices",
|
|
32
|
+
"summer_slice_asset_sheet",
|
|
33
|
+
"summer_get_studio_workflow",
|
|
34
|
+
"summer_search_assets",
|
|
35
|
+
"summer_list_my_assets",
|
|
36
|
+
"summer_get_asset",
|
|
37
|
+
"summer_get_asset_download_url",
|
|
38
|
+
],
|
|
39
|
+
ship: ["summer_export_game", "summer_export_templates", "summer_publish_build", "summer_capture_gameplay"],
|
|
40
|
+
ui: ["summer_ui_actions", "summer_ui_activate", "summer_ui_screenshot", "summer_ui_tree"],
|
|
41
|
+
};
|
|
42
|
+
const localToolset = new Map(Object.entries(LOCAL_TOOLSETS).flatMap(([set, names]) => names.map((name) => [name, set])));
|
|
43
|
+
/** Hosted tool names by pattern, first match wins. Unknown names land in `other` (full only). */
|
|
44
|
+
const HOSTED_TOOLSETS = [
|
|
45
|
+
[/^summer_(account|team)$/, "core"],
|
|
46
|
+
[/^summer_(remove_background|update_asset|delete_asset|upload_image_\w+)$/, "assets"],
|
|
47
|
+
[/^summer_tool_\w+$/, "tools"],
|
|
48
|
+
[/^summer_(store_version_(begin_upload|sign_parts|complete)|build_(begin_upload|sign_parts|complete_upload))$/, "uploads"],
|
|
49
|
+
[/^summer_(store_\w+|list_games)$/, "ship"],
|
|
50
|
+
[/^summer_board_\w+$/, "board"],
|
|
51
|
+
[/^summer_grow_\w+$/, "grow"],
|
|
52
|
+
[/^summer_studio_\w+$/, "studio"],
|
|
53
|
+
[/^summer_app_\w+$/, "apps"],
|
|
54
|
+
[/^summer_(build_\w+|make_game|game|game_\w+|list_projects|get_project)$/, "cloud"],
|
|
55
|
+
];
|
|
56
|
+
/** The toolset a tool belongs to: local tools by the table above, hosted ones by name. */
|
|
57
|
+
export function toolsetOf(name, local) {
|
|
58
|
+
if (local) {
|
|
59
|
+
if (localToolset.has(name))
|
|
60
|
+
return localToolset.get(name);
|
|
61
|
+
return name.startsWith("summer_app_") ? "apps" : "engine";
|
|
62
|
+
}
|
|
63
|
+
if (localToolset.has(name))
|
|
64
|
+
return localToolset.get(name);
|
|
65
|
+
return HOSTED_TOOLSETS.find(([pattern]) => pattern.test(name))?.[1] ?? "other";
|
|
66
|
+
}
|
|
67
|
+
const splitList = (value) => (value ?? "")
|
|
68
|
+
.split(",")
|
|
69
|
+
.map((part) => part.trim().toLowerCase())
|
|
70
|
+
.filter(Boolean);
|
|
71
|
+
/**
|
|
72
|
+
* `summer mcp --profile <p> --toolsets <a,b>` (env SUMMER_PROFILE,
|
|
73
|
+
* SUMMER_TOOLSETS). Without either: the full profile. `--toolsets` alone
|
|
74
|
+
* selects those toolsets plus core; with a profile it adds to it. `all` is
|
|
75
|
+
* every toolset. Unknown names are ignored and reported, never fatal: a
|
|
76
|
+
* typo must not stop an agent's MCP server from starting.
|
|
77
|
+
*/
|
|
78
|
+
export function resolveToolSelection(options = {}, env = process.env) {
|
|
79
|
+
const ignored = [];
|
|
80
|
+
const profileName = (options.profile ?? env.SUMMER_PROFILE ?? "").trim().toLowerCase();
|
|
81
|
+
const requested = splitList(options.toolsets ?? env.SUMMER_TOOLSETS);
|
|
82
|
+
const profile = parseProfile(profileName);
|
|
83
|
+
if (profileName && !profile)
|
|
84
|
+
ignored.push(profileName);
|
|
85
|
+
const extra = new Set();
|
|
86
|
+
let all = false;
|
|
87
|
+
for (const name of requested) {
|
|
88
|
+
if (name === "all")
|
|
89
|
+
all = true;
|
|
90
|
+
else if (TOOLSETS.includes(name))
|
|
91
|
+
extra.add(name);
|
|
92
|
+
else
|
|
93
|
+
ignored.push(name);
|
|
94
|
+
}
|
|
95
|
+
if (all || profile === "full" || (profile === null && extra.size === 0)) {
|
|
96
|
+
return { profile: "full", toolsets: null, ignored };
|
|
97
|
+
}
|
|
98
|
+
if (profile === null)
|
|
99
|
+
return { profile: "custom", toolsets: new Set(["core", ...extra]), ignored };
|
|
100
|
+
return { profile, toolsets: new Set([...PROFILES[profile], ...extra]), ignored };
|
|
101
|
+
}
|
|
102
|
+
/** True when the selection keeps this tool. */
|
|
103
|
+
export function selectionIncludes(selection, name, local) {
|
|
104
|
+
return selection.toolsets === null || selection.toolsets.has(toolsetOf(name, local));
|
|
105
|
+
}
|
|
106
|
+
// ── Annotations ──────────────────────────────────────────────────────────────
|
|
107
|
+
/**
|
|
108
|
+
* Local tools carry the registry's five `authority` booleans
|
|
109
|
+
* (library/tools/<slug>/resource.yaml). They say what a tool may touch, not
|
|
110
|
+
* whether it only reads, so a few sets refine them; the result is the MCP
|
|
111
|
+
* effect hints clients use for approvals.
|
|
112
|
+
*/
|
|
113
|
+
/** Tools whose only file output is an image or render for the agent; they never change the game. */
|
|
114
|
+
const EVIDENCE_ONLY = new Set([
|
|
115
|
+
"summer_screenshot",
|
|
116
|
+
"summer_debug_views",
|
|
117
|
+
"summer_shot_sheet",
|
|
118
|
+
"summer_zoom",
|
|
119
|
+
"summer_scene_audit",
|
|
120
|
+
"summer_game_probe",
|
|
121
|
+
"summer_capture_gameplay",
|
|
122
|
+
"summer_app_screenshot",
|
|
123
|
+
]);
|
|
124
|
+
/** Generation on Summer's servers: costs credits, creates new assets. */
|
|
125
|
+
const SPENDS_CREDITS = new Set([
|
|
126
|
+
"summer_generate_3d",
|
|
127
|
+
"summer_generate_audio",
|
|
128
|
+
"summer_generate_image",
|
|
129
|
+
"summer_generate_motion",
|
|
130
|
+
"summer_generate_sfx_choices",
|
|
131
|
+
"summer_generate_video",
|
|
132
|
+
]);
|
|
133
|
+
/** Network-only tools that change the person's Summer data (the rest of the network tools read). */
|
|
134
|
+
const NETWORK_WRITES = new Set([
|
|
135
|
+
"summer_app_create",
|
|
136
|
+
"summer_app_data",
|
|
137
|
+
"summer_app_page",
|
|
138
|
+
"summer_app_call",
|
|
139
|
+
"summer_app_report_gap",
|
|
140
|
+
"summer_app_update",
|
|
141
|
+
"summer_slice_asset_sheet",
|
|
142
|
+
]);
|
|
143
|
+
/** Changes that only add something new, or only touch the editor view or the running game. */
|
|
144
|
+
const ADDITIVE_OR_TRANSIENT = new Set([
|
|
145
|
+
"summer_add_node",
|
|
146
|
+
"summer_create_scene",
|
|
147
|
+
"summer_instantiate_scene",
|
|
148
|
+
"summer_connect_signal",
|
|
149
|
+
"summer_input_map_bind",
|
|
150
|
+
"summer_import_asset",
|
|
151
|
+
"summer_import_asset_by_id",
|
|
152
|
+
"summer_import_from_url",
|
|
153
|
+
"summer_import_from_url_batch",
|
|
154
|
+
"summer_import_hdri",
|
|
155
|
+
"summer_repeat_along",
|
|
156
|
+
"summer_fabricate_3d",
|
|
157
|
+
"summer_frame_nodes",
|
|
158
|
+
"summer_frame_shot",
|
|
159
|
+
"summer_save_scene",
|
|
160
|
+
"summer_enable_plugin",
|
|
161
|
+
"summer_export_game",
|
|
162
|
+
"summer_export_templates",
|
|
163
|
+
"summer_create_debug_report",
|
|
164
|
+
"summer_library_feedback",
|
|
165
|
+
"summer_app_create",
|
|
166
|
+
"summer_app_report_gap",
|
|
167
|
+
"summer_app_dock",
|
|
168
|
+
"summer_slice_asset_sheet",
|
|
169
|
+
"summer_open_scene",
|
|
170
|
+
"summer_open_main_scene",
|
|
171
|
+
"summer_select_node",
|
|
172
|
+
"summer_clear_console",
|
|
173
|
+
"summer_play",
|
|
174
|
+
"summer_stop",
|
|
175
|
+
"summer_game_control",
|
|
176
|
+
"summer_game_input",
|
|
177
|
+
"summer_runtime_animate",
|
|
178
|
+
"summer_runtime_call",
|
|
179
|
+
"summer_runtime_set",
|
|
180
|
+
"summer_runtime_spawn",
|
|
181
|
+
]);
|
|
182
|
+
/** Changes where a second identical call has no further effect. */
|
|
183
|
+
const IDEMPOTENT_WRITES = new Set([
|
|
184
|
+
"summer_set_prop",
|
|
185
|
+
"summer_set_resource_property",
|
|
186
|
+
"summer_project_setting",
|
|
187
|
+
"summer_remove_node",
|
|
188
|
+
"summer_write_file",
|
|
189
|
+
"summer_create_scene",
|
|
190
|
+
"summer_save_scene",
|
|
191
|
+
"summer_open_scene",
|
|
192
|
+
"summer_open_main_scene",
|
|
193
|
+
"summer_select_node",
|
|
194
|
+
"summer_clear_console",
|
|
195
|
+
"summer_stop",
|
|
196
|
+
"summer_enable_plugin",
|
|
197
|
+
"summer_place_adjacent",
|
|
198
|
+
"summer_attach_to_surface",
|
|
199
|
+
"summer_connect_ports",
|
|
200
|
+
"summer_align_distribute_3d",
|
|
201
|
+
"summer_snap_to_surface",
|
|
202
|
+
"summer_camera_bookmark",
|
|
203
|
+
"summer_frame_nodes",
|
|
204
|
+
"summer_runtime_set",
|
|
205
|
+
"summer_export_game",
|
|
206
|
+
"summer_export_templates",
|
|
207
|
+
"summer_app_update",
|
|
208
|
+
"summer_app_dock",
|
|
209
|
+
]);
|
|
210
|
+
/** Every name the refinement sets mention (a test checks each is a real tool). */
|
|
211
|
+
export const ANNOTATION_REFINEMENTS = new Set([
|
|
212
|
+
...EVIDENCE_ONLY,
|
|
213
|
+
...SPENDS_CREDITS,
|
|
214
|
+
...NETWORK_WRITES,
|
|
215
|
+
...ADDITIVE_OR_TRANSIENT,
|
|
216
|
+
...IDEMPOTENT_WRITES,
|
|
217
|
+
]);
|
|
218
|
+
/** MCP annotations for one local tool from its registry authority. */
|
|
219
|
+
export function annotationsFor(name, authority) {
|
|
220
|
+
const openWorldHint = Boolean(authority.network || authority.publish);
|
|
221
|
+
if (authority.publish) {
|
|
222
|
+
return { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true };
|
|
223
|
+
}
|
|
224
|
+
if (SPENDS_CREDITS.has(name)) {
|
|
225
|
+
return { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true };
|
|
226
|
+
}
|
|
227
|
+
const writes = !EVIDENCE_ONLY.has(name) &&
|
|
228
|
+
Boolean(authority.filesystem || authority.editor_mutation || authority.credentials || NETWORK_WRITES.has(name));
|
|
229
|
+
if (!writes) {
|
|
230
|
+
return { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint };
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
readOnlyHint: false,
|
|
234
|
+
destructiveHint: !ADDITIVE_OR_TRANSIENT.has(name),
|
|
235
|
+
idempotentHint: IDEMPOTENT_WRITES.has(name),
|
|
236
|
+
openWorldHint,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
let authorityCache = null;
|
|
240
|
+
/** Registry authority per MCP tool name (registry/generated/index.json). */
|
|
241
|
+
export function registryAuthorities() {
|
|
242
|
+
if (authorityCache)
|
|
243
|
+
return authorityCache;
|
|
244
|
+
const map = new Map();
|
|
245
|
+
try {
|
|
246
|
+
for (const entry of loadLibraryIndex()) {
|
|
247
|
+
if (entry.kind === "tool" && entry.mcp_tool_name && entry.authority)
|
|
248
|
+
map.set(entry.mcp_tool_name, entry.authority);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// A broken install still serves tools; they go out without annotations.
|
|
253
|
+
}
|
|
254
|
+
authorityCache = map;
|
|
255
|
+
return map;
|
|
256
|
+
}
|
|
257
|
+
// ── Output caps ──────────────────────────────────────────────────────────────
|
|
258
|
+
/** Default text cap for tools whose results can be large. */
|
|
259
|
+
export const DEFAULT_MAX_CHARACTERS = 4_000;
|
|
260
|
+
/**
|
|
261
|
+
* Tools whose text results are capped by default, with their default cap.
|
|
262
|
+
* Scene and runtime trees, console and debugger reads, inspect reads and
|
|
263
|
+
* library reads. The scene tree and library reads get more room: a median
|
|
264
|
+
* skill is about 12K characters, and cutting every skill read would double
|
|
265
|
+
* the core search-then-read loop. Writes, job ids and file reads are never
|
|
266
|
+
* capped.
|
|
267
|
+
*/
|
|
268
|
+
export const OUTPUT_CAPS = new Map([
|
|
269
|
+
["summer_get_scene_tree", 8_000],
|
|
270
|
+
["summer_get_runtime_tree", DEFAULT_MAX_CHARACTERS],
|
|
271
|
+
["summer_get_console", DEFAULT_MAX_CHARACTERS],
|
|
272
|
+
["summer_get_debugger_errors", DEFAULT_MAX_CHARACTERS],
|
|
273
|
+
["summer_get_debugger_warnings", DEFAULT_MAX_CHARACTERS],
|
|
274
|
+
["summer_inspect_node", DEFAULT_MAX_CHARACTERS],
|
|
275
|
+
["summer_inspect_resource", DEFAULT_MAX_CHARACTERS],
|
|
276
|
+
["summer_inspect_runtime_node", DEFAULT_MAX_CHARACTERS],
|
|
277
|
+
["summer_inspect_asset", DEFAULT_MAX_CHARACTERS],
|
|
278
|
+
["summer_read_library", 24_000],
|
|
279
|
+
]);
|
|
280
|
+
/**
|
|
281
|
+
* A capped tool's input shape plus `maxCharacters`. server.ts adds it at
|
|
282
|
+
* registration and strips it before the handler runs; the descriptor parity
|
|
283
|
+
* test applies the same function, so library/tools/<slug>/resource.yaml
|
|
284
|
+
* lists the argument too.
|
|
285
|
+
*/
|
|
286
|
+
export function withMaxCharactersArg(name, shape) {
|
|
287
|
+
const cap = OUTPUT_CAPS.get(name);
|
|
288
|
+
if (cap === undefined || "maxCharacters" in shape)
|
|
289
|
+
return shape;
|
|
290
|
+
return {
|
|
291
|
+
...shape,
|
|
292
|
+
maxCharacters: z
|
|
293
|
+
.number()
|
|
294
|
+
.int()
|
|
295
|
+
.min(500)
|
|
296
|
+
.max(1_000_000)
|
|
297
|
+
.optional()
|
|
298
|
+
.describe(`Most characters of text to return (default ${cap}). A longer result is cut and says so.`),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
// ── Single scene edits ───────────────────────────────────────────────────────
|
|
302
|
+
/** One-change scene tools; a run of them is one summer_run_script. */
|
|
303
|
+
export const SINGLE_EDIT_TOOLS = new Set([
|
|
304
|
+
"summer_set_prop",
|
|
305
|
+
"summer_add_node",
|
|
306
|
+
"summer_remove_node",
|
|
307
|
+
"summer_set_resource_property",
|
|
308
|
+
"summer_instantiate_scene",
|
|
309
|
+
"summer_connect_signal",
|
|
310
|
+
"summer_replace_node",
|
|
311
|
+
]);
|
|
312
|
+
/** Calls that already batch edits; they end a run of single edits. */
|
|
313
|
+
export const BATCH_EDIT_TOOLS = new Set([
|
|
314
|
+
"summer_run_script",
|
|
315
|
+
"summer_batch",
|
|
316
|
+
"summer_run_editor_script",
|
|
317
|
+
]);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { MAX_APP_EVENTS_WAIT_SECONDS, APP_DOCK_FALLBACK, appCall, appCallArgsSchema, appCreate, appCreateArgsSchema, appData, appDataArgsSchema, appDockArgsSchema, appDockOp, appEvents, appEventsArgsSchema, appGet, appGetArgsSchema, appGuide, appGuideArgsSchema, appList, appListArgsSchema, appPage, appPageArgsSchema, appPublish, appPublishArgsSchema, appReportGap, appReportGapArgsSchema, appScreenshot, appScreenshotArgsSchema, appUpdate, appUpdateArgsSchema, appsGateway, appTools, appToolsArgsSchema, } from "../../core/capabilities/apps.js";
|
|
2
|
+
import { enablePluginArgsSchema, enablePluginOp, interpretEnablePluginResult } from "../../core/capabilities/enable-plugin.js";
|
|
3
|
+
import { missingEngineOpResult, withEngine } from "./with-engine.js";
|
|
4
|
+
/**
|
|
5
|
+
* Summer Apps over MCP: tools a game team uses inside Summer Studio, built by
|
|
6
|
+
* the agent. Shared implementation: core/capabilities/apps.ts.
|
|
7
|
+
*/
|
|
8
|
+
const CLOUD = "Cloud tool: runs on Summer's servers and works without the Summer Engine app open. Requires sign-in: npx -y summer-engine@latest login.";
|
|
9
|
+
function result(value) {
|
|
10
|
+
return { content: [{ type: "text", text: JSON.stringify(value, null, 2) }], ...(value.ok === false ? { isError: true } : {}) };
|
|
11
|
+
}
|
|
12
|
+
/** The MCP handler of one cloud tool: validate with the shared schema, call the web API. */
|
|
13
|
+
function cloud(name, schema, run) {
|
|
14
|
+
return async (args) => {
|
|
15
|
+
const parsed = schema.safeParse(args ?? {});
|
|
16
|
+
if (!parsed.success)
|
|
17
|
+
return result({ ok: false, code: "invalid", error: parsed.error.issues[0]?.message ?? "Invalid arguments" });
|
|
18
|
+
return result(await run(parsed.data, { request: appsGateway("mcp", name) }));
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function registerAppTools(server) {
|
|
22
|
+
server.tool("summer_app_guide", `Read this before building or changing a Summer App (a tool for the person's team inside Summer Studio). Start with the default section overview (when to build one, Layout vs code, the build loop, the rules), then read what the app needs: examples (a complete working app to copy), sdk, manifest, kit, design, layout, types (exact SDK TypeScript types).\n\n${CLOUD}`, appGuideArgsSchema.shape, async (args) => {
|
|
23
|
+
const parsed = appGuideArgsSchema.safeParse(args ?? {});
|
|
24
|
+
if (!parsed.success)
|
|
25
|
+
return result({ ok: false, code: "invalid", error: parsed.error.issues[0]?.message ?? "Invalid arguments" });
|
|
26
|
+
const guide = await appGuide(parsed.data, { request: appsGateway("mcp", "summer_app_guide") });
|
|
27
|
+
// The guide reads as Markdown, not as one escaped JSON line.
|
|
28
|
+
return guide.ok === true && typeof guide.markdown === "string" ? { content: [{ type: "text", text: guide.markdown }] } : result(guide);
|
|
29
|
+
});
|
|
30
|
+
server.tool("summer_app_list", `The Summer Apps in the person's workspaces: id, name, purpose, folder, status (scratch, kept, archived), version, format.\n\n${CLOUD}`, appListArgsSchema.shape, cloud("summer_app_list", appListArgsSchema, appList));
|
|
31
|
+
server.tool("summer_app_create", `Create a new scratch Summer App; their open Summer Studio tab opens it. Without workspaceId it goes to the person's team (the one their Studio tab is on, else their latest team, else personal); the result's workspace says which: tell the person. Read summer_app_guide first. format code (index.html + JS/CSS) or layout (a JSON layout of kit nodes for a quick decision UI). Then summer_app_publish.\n\n${CLOUD}`, appCreateArgsSchema.shape, cloud("summer_app_create", appCreateArgsSchema, appCreate));
|
|
32
|
+
server.tool("summer_app_publish", `Publish a new immutable version of a Summer App: dir (a local folder with index.html at its root) or files [{path, content, encoding}] for code apps, layout for layout apps, plus the manifest. Limits: 10 MB, 300 files, 5 MB per file. The person's Studio tab boots it. An error names the file or rule to fix: fix it and publish again.\n\n${CLOUD}`, appPublishArgsSchema.shape, cloud("summer_app_publish", appPublishArgsSchema, appPublish));
|
|
33
|
+
server.tool("summer_app_get", `A Summer App's manifest, its current version's files (or layout) and a summary of its shared data. Use it before changing an app.\n\n${CLOUD}`, appGetArgsSchema.shape, cloud("summer_app_get", appGetArgsSchema, appGet));
|
|
34
|
+
server.tool("summer_app_update", `Rename a Summer App, change its purpose or folder, or set its status: kept (the team keeps it), archived (hidden from the app list; restore with scratch or kept), scratch. Archive the scratch apps you made that the person did not keep.\n\n${CLOUD}`, appUpdateArgsSchema.shape, cloud("summer_app_update", appUpdateArgsSchema, appUpdate));
|
|
35
|
+
server.tool("summer_app_events", `Wait for what a Summer App sends you: summer.agent.send events (kind agent), errors in the app (kind error), feedback (kind feedback), agent tool calls (kind tool). Waits up to timeoutSeconds (max ${MAX_APP_EVENTS_WAIT_SECONDS}) for the first event after the cursor; pass the returned cursor as after next time.\n\n${CLOUD}`, appEventsArgsSchema.shape, cloud("summer_app_events", appEventsArgsSchema, appEvents));
|
|
36
|
+
server.tool("summer_app_page", `Read or use the fields and buttons a Summer App declared while it is open in the person's Studio tab or editor dock: no fill and no press reads the page; fill [{field, value}] and press an action id use it. Critical actions (delete, publish, pay, send) are pressed only by the person. app_not_open when the app is not open.\n\n${CLOUD}`, appPageArgsSchema.shape, cloud("summer_app_page", appPageArgsSchema, appPage));
|
|
37
|
+
server.tool("summer_app_screenshot", `See a Summer App without the person: Summer renders its current version (or version) headless with the person's data and returns the picture plus what to fix: console lines, uncaught errors, refused calls, whether the SDK connected and rendered, and the fields, buttons and agent tools it declared. Read-only: writes, sends and paid calls are refused, nothing changes. width 390 for a phone, theme dark, fullPage for the whole scroll, steps to click or press something first (a dialog, a second state); out also saves the PNG. It waits until the app's calls settle. Use it after every publish.\n\n${CLOUD}`, appScreenshotArgsSchema.shape, async (args) => {
|
|
38
|
+
const parsed = appScreenshotArgsSchema.safeParse(args ?? {});
|
|
39
|
+
if (!parsed.success)
|
|
40
|
+
return result({ ok: false, code: "invalid", error: parsed.error.issues[0]?.message ?? "Invalid arguments" });
|
|
41
|
+
const shot = await appScreenshot(parsed.data, { request: appsGateway("mcp", "summer_app_screenshot") });
|
|
42
|
+
if (shot.ok !== true || !("image" in shot))
|
|
43
|
+
return result(shot);
|
|
44
|
+
const { image, ...report } = shot;
|
|
45
|
+
return { content: [{ type: "image", data: image.base64, mimeType: image.mimeType }, { type: "text", text: JSON.stringify(report, null, 2) }] };
|
|
46
|
+
});
|
|
47
|
+
server.tool("summer_app_data", `Read or write a Summer App's shared data, its API: works with no app open, and everyone in the app sees writes live. Without ops it reads records (paged with after) plus declaredCollections, the record shape the app declares; with ops it writes them in one revision: {op: put|patch|remove, collection, recordId, data|patch, ifRevision?}. Writes show as yours (actor kind agent); as: seed writes starter data for the team (kind seed, no author).\n\n${CLOUD}`, appDataArgsSchema.shape, cloud("summer_app_data", appDataArgsSchema, appData));
|
|
48
|
+
server.tool("summer_app_tools", `The agent tools (name, description, input JSON Schema) and the data collections (record fields and types) a Summer App declares. Run a tool with summer_app_call; read or write the collections with summer_app_data.\n\n${CLOUD}`, appToolsArgsSchema.shape, cloud("summer_app_tools", appToolsArgsSchema, appTools));
|
|
49
|
+
server.tool("summer_app_call", `Run one of a Summer App's agent tools inside the person's open app (Studio tab or editor dock) with their rights; waits up to 60 s. app_not_open when the app is not open: use summer_app_data or ask the person to open it. May spend the person's credits when the tool generates.\n\n${CLOUD}`, appCallArgsSchema.shape, cloud("summer_app_call", appCallArgsSchema, appCall));
|
|
50
|
+
server.tool("summer_app_report_gap", `Tell Summer about an SDK capability a Summer App needed and did not have, so it can be built for everyone.\n\n${CLOUD}`, appReportGapArgsSchema.shape, cloud("summer_app_report_gap", appReportGapArgsSchema, appReportGap));
|
|
51
|
+
server.tool("summer_app_dock", `Dock a Summer App as a panel in the running Summer Engine editor (left, right or bottom), close its dock, or list docked apps. Docks persist per project. Engine builds without app docks return engine_lacks_op: open the app in the Summer Studio tab instead.`, appDockArgsSchema.shape, async (args) => {
|
|
52
|
+
const parsed = appDockArgsSchema.safeParse(args ?? {});
|
|
53
|
+
if (!parsed.success)
|
|
54
|
+
return result({ ok: false, code: "invalid", error: parsed.error.issues[0]?.message ?? "Invalid arguments" });
|
|
55
|
+
if (parsed.data.action !== "list" && !parsed.data.appId)
|
|
56
|
+
return result({ ok: false, code: "invalid", error: `${parsed.data.action} needs appId` });
|
|
57
|
+
const op = appDockOp(parsed.data);
|
|
58
|
+
return withEngine(async (client) => {
|
|
59
|
+
const missing = missingEngineOpResult(client, op.op, APP_DOCK_FALLBACK);
|
|
60
|
+
if (missing)
|
|
61
|
+
return missing;
|
|
62
|
+
return client.executeOps([op]);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
server.tool("summer_enable_plugin", `Enable an editor plugin in the open project (res://addons/<name>/, for example one paired with a Summer App) and report the real result: enabled with the autoloads it registered, or why it failed (code SCRIPT_ERROR, NOT_TOOL, NOT_EDITOR_PLUGIN, CFG_MISSING, TIMEOUT, ...). Older Summer Engine builds only queue the enable; then the result says queued: true and enabled: null, and you check summer_get_debugger_errors before relying on the plugin.`, enablePluginArgsSchema.shape, async (args) => {
|
|
66
|
+
const parsed = enablePluginArgsSchema.safeParse(args ?? {});
|
|
67
|
+
if (!parsed.success)
|
|
68
|
+
return result({ ok: false, code: "invalid", error: parsed.error.issues[0]?.message ?? "Invalid arguments" });
|
|
69
|
+
return withEngine(async (client) => interpretEnablePluginResult(await client.executeOps([enablePluginOp(parsed.data)])));
|
|
70
|
+
});
|
|
71
|
+
}
|
|
@@ -4,14 +4,15 @@ import { resolveGatewayUrl } from "../../core/config.js";
|
|
|
4
4
|
import { getClient } from "../server.js";
|
|
5
5
|
import { ImportHdriError, importPolyHavenHdri, } from "../../core/capabilities/hdri-import.js";
|
|
6
6
|
import { importResolvedAsset } from "../../core/capabilities/asset-import.js";
|
|
7
|
+
import { summerRequestHeaders } from "../../core/agent-host.js";
|
|
8
|
+
import { codedFailure, describeNetworkError, EngineNotRunningError, networkDetails, NOT_SIGNED_IN, SIGN_IN_AGAIN_RECOVERY, } from "../../core/error-codes.js";
|
|
9
|
+
import { engineNotRunningResult } from "./with-engine.js";
|
|
10
|
+
/** No Summer account token: the same failure for every asset tool. */
|
|
11
|
+
const notSignedIn = { error: "not_logged_in", message: NOT_SIGNED_IN, code: "not_signed_in" };
|
|
7
12
|
async function searchAssetsApi(params) {
|
|
8
13
|
const token = await getAuthToken();
|
|
9
|
-
if (!token)
|
|
10
|
-
return {
|
|
11
|
-
error: "Not logged in",
|
|
12
|
-
message: "Not signed in. The user needs to run this in their terminal:\n npx -y summer-engine@latest login\nOr open: https://www.summerengine.com/login\nAsset search requires a Summer Engine account (free to create).",
|
|
13
|
-
};
|
|
14
|
-
}
|
|
14
|
+
if (!token)
|
|
15
|
+
return { ...notSignedIn };
|
|
15
16
|
const searchParams = new URLSearchParams();
|
|
16
17
|
searchParams.set("query", params.query);
|
|
17
18
|
if (params.assetType && params.assetType !== "all") {
|
|
@@ -30,17 +31,24 @@ async function searchAssetsApi(params) {
|
|
|
30
31
|
if (params.preview)
|
|
31
32
|
searchParams.set("contactSheet", "true");
|
|
32
33
|
const gatewayUrl = await resolveGatewayUrl();
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
let res;
|
|
35
|
+
try {
|
|
36
|
+
res = await fetch(`${gatewayUrl}/api/mcp/assets?${searchParams}`, {
|
|
37
|
+
headers: { ...summerRequestHeaders({ surface: "mcp" }), Authorization: `Bearer ${token}` },
|
|
38
|
+
signal: AbortSignal.timeout(15000),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
return { error: "network_error", message: `Asset request failed: ${describeNetworkError(err)}`, code: "unavailable", ...networkDetails(err) };
|
|
43
|
+
}
|
|
37
44
|
const data = (await res.json());
|
|
38
45
|
if (!res.ok) {
|
|
39
46
|
if (res.status === 401) {
|
|
40
47
|
return {
|
|
41
48
|
error: "unauthorized",
|
|
42
|
-
message:
|
|
43
|
-
|
|
49
|
+
message: data.message || "Auth token expired.",
|
|
50
|
+
code: "not_signed_in",
|
|
51
|
+
recovery: SIGN_IN_AGAIN_RECOVERY,
|
|
44
52
|
};
|
|
45
53
|
}
|
|
46
54
|
if (res.status === 429) {
|
|
@@ -59,18 +67,19 @@ async function searchAssetsApi(params) {
|
|
|
59
67
|
}
|
|
60
68
|
async function authedGetJson(endpoint, timeoutMs = 15_000) {
|
|
61
69
|
const token = await getAuthToken();
|
|
62
|
-
if (!token)
|
|
63
|
-
return {
|
|
64
|
-
status: 401,
|
|
65
|
-
error: "not_logged_in",
|
|
66
|
-
message: "Not signed in. Run in your terminal:\n npx -y summer-engine@latest login",
|
|
67
|
-
};
|
|
68
|
-
}
|
|
70
|
+
if (!token)
|
|
71
|
+
return { status: 401, ...notSignedIn };
|
|
69
72
|
const gatewayUrl = await resolveGatewayUrl();
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
let res;
|
|
74
|
+
try {
|
|
75
|
+
res = await fetch(`${gatewayUrl}${endpoint}`, {
|
|
76
|
+
headers: { ...summerRequestHeaders({ surface: "mcp" }), Authorization: `Bearer ${token}` },
|
|
77
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
return { status: 0, error: "network_error", message: `Asset request failed: ${describeNetworkError(err)}`, code: "unavailable", ...networkDetails(err) };
|
|
82
|
+
}
|
|
74
83
|
const data = (await res.json());
|
|
75
84
|
if (!res.ok) {
|
|
76
85
|
return {
|
|
@@ -78,6 +87,7 @@ async function authedGetJson(endpoint, timeoutMs = 15_000) {
|
|
|
78
87
|
data,
|
|
79
88
|
error: data?.error || "request_failed",
|
|
80
89
|
message: data?.message || "Request failed",
|
|
90
|
+
...(res.status === 401 ? { code: "not_signed_in", recovery: SIGN_IN_AGAIN_RECOVERY } : {}),
|
|
81
91
|
};
|
|
82
92
|
}
|
|
83
93
|
return { status: res.status, data };
|
|
@@ -85,14 +95,14 @@ async function authedGetJson(endpoint, timeoutMs = 15_000) {
|
|
|
85
95
|
async function getAssetApi(assetId) {
|
|
86
96
|
const result = await authedGetJson(`/api/mcp/assets/${encodeURIComponent(assetId)}`);
|
|
87
97
|
if (result.error) {
|
|
88
|
-
return { error: result.error, message: result.message };
|
|
98
|
+
return { error: result.error, message: result.message, code: result.code, recovery: result.recovery, details: result.details };
|
|
89
99
|
}
|
|
90
100
|
return { asset: result.data?.asset };
|
|
91
101
|
}
|
|
92
102
|
async function getAssetDownloadUrlApi(assetId, role) {
|
|
93
103
|
const result = await authedGetJson(`/api/mcp/assets/${encodeURIComponent(assetId)}/download-url?role=${encodeURIComponent(role)}`);
|
|
94
104
|
if (result.error) {
|
|
95
|
-
return { error: result.error, message: result.message };
|
|
105
|
+
return { error: result.error, message: result.message, code: result.code, recovery: result.recovery, details: result.details };
|
|
96
106
|
}
|
|
97
107
|
return { data: result.data };
|
|
98
108
|
}
|
|
@@ -106,6 +116,14 @@ function jsonSuccess(data) {
|
|
|
106
116
|
],
|
|
107
117
|
};
|
|
108
118
|
}
|
|
119
|
+
/** The body of a failed lookup: `{ok:false, code, error, recovery, message}`
|
|
120
|
+
* for the shared failures, else the older `{error, message}`. */
|
|
121
|
+
function failureBody(result, fallback) {
|
|
122
|
+
const message = result.message || fallback.message;
|
|
123
|
+
return result.code
|
|
124
|
+
? codedFailure(result.code, message, { message, ...(result.details ? { details: result.details } : {}) }, result.recovery)
|
|
125
|
+
: { error: result.error || fallback.error, message };
|
|
126
|
+
}
|
|
109
127
|
function jsonError(data) {
|
|
110
128
|
return {
|
|
111
129
|
content: [
|
|
@@ -146,15 +164,7 @@ Requires authentication (so we can attribute usage and apply per-user rate limit
|
|
|
146
164
|
}, async ({ query, assetType, limit, source, style, preview, includeCommunity }) => {
|
|
147
165
|
const result = await searchAssetsApi({ query, assetType, limit: Math.min(limit, 20), source, style, preview, includeCommunity });
|
|
148
166
|
if (result.error) {
|
|
149
|
-
return {
|
|
150
|
-
content: [
|
|
151
|
-
{
|
|
152
|
-
type: "text",
|
|
153
|
-
text: JSON.stringify({ error: result.error, message: result.message }, null, 2),
|
|
154
|
-
},
|
|
155
|
-
],
|
|
156
|
-
isError: true,
|
|
157
|
-
};
|
|
167
|
+
return jsonError(failureBody(result, { error: "Search failed", message: "Asset search failed" }));
|
|
158
168
|
}
|
|
159
169
|
const sheet = result.contactSheet?.match(/^data:(image\/[a-z]+);base64,(.+)$/);
|
|
160
170
|
return {
|
|
@@ -200,7 +210,7 @@ Cloud tool — works WITHOUT the Summer Engine app open.`, {
|
|
|
200
210
|
source: "my_assets",
|
|
201
211
|
});
|
|
202
212
|
if (result.error) {
|
|
203
|
-
return jsonError({ error:
|
|
213
|
+
return jsonError(failureBody(result, { error: "List failed", message: "Listing your assets failed" }));
|
|
204
214
|
}
|
|
205
215
|
return jsonSuccess({
|
|
206
216
|
assets: result.assets,
|
|
@@ -220,10 +230,7 @@ Cloud tool — works WITHOUT the Summer Engine app open.`, {
|
|
|
220
230
|
}, async ({ assetId }) => {
|
|
221
231
|
const result = await getAssetApi(assetId);
|
|
222
232
|
if (result.error || !result.asset) {
|
|
223
|
-
return jsonError({
|
|
224
|
-
error: result.error || "asset_not_found",
|
|
225
|
-
message: result.message || "Asset not found.",
|
|
226
|
-
});
|
|
233
|
+
return jsonError(failureBody(result, { error: "asset_not_found", message: "Asset not found." }));
|
|
227
234
|
}
|
|
228
235
|
return jsonSuccess({ asset: result.asset });
|
|
229
236
|
});
|
|
@@ -242,7 +249,7 @@ Cloud tool — works WITHOUT the Summer Engine app open.`, {
|
|
|
242
249
|
}, async ({ assetId, role }) => {
|
|
243
250
|
const result = await getAssetDownloadUrlApi(assetId, role);
|
|
244
251
|
if (result.error) {
|
|
245
|
-
return jsonError({ error:
|
|
252
|
+
return jsonError(failureBody(result, { error: "request_failed", message: "Request failed" }));
|
|
246
253
|
}
|
|
247
254
|
return jsonSuccess(result.data);
|
|
248
255
|
});
|
|
@@ -276,10 +283,7 @@ itself does not — only this import step does).`, {
|
|
|
276
283
|
}, async ({ assetId, path, parent, scenePath, name }) => {
|
|
277
284
|
const fetched = await getAssetApi(assetId);
|
|
278
285
|
if (fetched.error || !fetched.asset) {
|
|
279
|
-
return jsonError({
|
|
280
|
-
error: fetched.error || "asset_not_found",
|
|
281
|
-
message: fetched.message || "Asset not found.",
|
|
282
|
-
});
|
|
286
|
+
return jsonError(failureBody(fetched, { error: "asset_not_found", message: "Asset not found." }));
|
|
283
287
|
}
|
|
284
288
|
try {
|
|
285
289
|
const imported = await importResolvedAsset(await getClient(), {
|
|
@@ -297,6 +301,8 @@ itself does not — only this import step does).`, {
|
|
|
297
301
|
});
|
|
298
302
|
}
|
|
299
303
|
catch (err) {
|
|
304
|
+
if (err instanceof EngineNotRunningError)
|
|
305
|
+
return engineNotRunningResult(err);
|
|
300
306
|
const msg = err instanceof Error ? err.message : String(err);
|
|
301
307
|
return jsonError({
|
|
302
308
|
error: "import_failed",
|
|
@@ -319,15 +325,7 @@ Requires authentication. If the user gets an auth error, they need to run 'npx -
|
|
|
319
325
|
}, async ({ query, parent, scenePath, assetType, source }) => {
|
|
320
326
|
const searchResult = await searchAssetsApi({ query, assetType, limit: 5, source });
|
|
321
327
|
if (searchResult.error) {
|
|
322
|
-
return {
|
|
323
|
-
content: [
|
|
324
|
-
{
|
|
325
|
-
type: "text",
|
|
326
|
-
text: JSON.stringify({ error: searchResult.error, message: searchResult.message }, null, 2),
|
|
327
|
-
},
|
|
328
|
-
],
|
|
329
|
-
isError: true,
|
|
330
|
-
};
|
|
328
|
+
return jsonError(failureBody(searchResult, { error: "Search failed", message: "Asset search failed" }));
|
|
331
329
|
}
|
|
332
330
|
const assets = searchResult.assets || [];
|
|
333
331
|
if (assets.length === 0) {
|
|
@@ -378,6 +376,8 @@ Requires authentication. If the user gets an auth error, they need to run 'npx -
|
|
|
378
376
|
};
|
|
379
377
|
}
|
|
380
378
|
catch (err) {
|
|
379
|
+
if (err instanceof EngineNotRunningError)
|
|
380
|
+
return engineNotRunningResult(err);
|
|
381
381
|
const msg = err instanceof Error ? err.message : String(err);
|
|
382
382
|
return {
|
|
383
383
|
content: [
|
|
@@ -433,6 +433,8 @@ runs through the engine). No Summer login needed.`, {
|
|
|
433
433
|
...(err.hint ? { hint: err.hint } : {}),
|
|
434
434
|
});
|
|
435
435
|
}
|
|
436
|
+
if (err instanceof EngineNotRunningError)
|
|
437
|
+
return engineNotRunningResult(err);
|
|
436
438
|
const msg = err instanceof Error ? err.message : String(err);
|
|
437
439
|
return jsonError({
|
|
438
440
|
error: "hdri_import_failed",
|