summer-engine 2.8.1 → 3.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 +27 -7
- package/.claude-plugin/plugin.json +99 -83
- package/.codex-plugin/plugin.json +112 -82
- package/.cursor-plugin/plugin.json +119 -83
- package/.factory-plugin/plugin.json +100 -3
- package/.mcp.json +6 -1
- package/.opencode/INSTALL.md +7 -4
- package/.opencode/plugins/summer.js +31 -18
- package/AGENTS.md +107 -34
- package/CHANGELOG.md +134 -41
- package/CLAUDE.md +4 -2
- package/GEMINI.md +7 -53
- package/NOTICE +31 -0
- package/README.md +159 -391
- package/assets/api-docs.json.gz +0 -0
- package/assets/autopilot/README.md +20 -6
- package/assets/autopilot/autopilot.gd +80 -26
- package/assets/autopilot/run.sh +132 -7
- package/assets/navigation/web-routes.json +719 -0
- package/commands/gameskill.md +10 -108
- package/commands/summer.md +72 -4
- package/dist/bin/summer.js +6 -87
- package/dist/cli/banner.d.ts +1 -0
- package/dist/cli/banner.js +33 -0
- package/dist/{commands → cli/commands}/config.js +1 -1
- package/dist/cli/commands/create.d.ts +30 -0
- package/dist/cli/commands/create.js +212 -0
- package/dist/{commands → cli/commands}/debug.js +2 -2
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.js +18 -0
- package/dist/cli/commands/events.d.ts +57 -0
- package/dist/cli/commands/events.js +158 -0
- package/dist/cli/commands/install.d.ts +50 -0
- package/dist/cli/commands/install.js +447 -0
- package/dist/cli/commands/list.js +72 -0
- package/dist/{commands → cli/commands}/login.js +33 -17
- package/dist/{commands → cli/commands}/logout.d.ts +1 -0
- package/dist/cli/commands/logout.js +19 -0
- package/dist/{commands → cli/commands}/memory.d.ts +1 -8
- package/dist/{commands → cli/commands}/memory.js +20 -11
- package/dist/cli/commands/open.d.ts +45 -0
- package/dist/cli/commands/open.js +216 -0
- package/dist/{commands → cli/commands}/plan.js +2 -2
- package/dist/{commands → cli/commands}/publish.js +1 -1
- package/dist/{commands → cli/commands}/releases.js +1 -1
- package/dist/cli/commands/run.d.ts +19 -0
- package/dist/cli/commands/run.js +255 -0
- package/dist/{commands → cli/commands}/setup.js +43 -89
- package/dist/{commands → cli/commands}/skills.js +85 -222
- package/dist/{commands → cli/commands}/status.d.ts +1 -0
- package/dist/cli/commands/status.js +62 -0
- package/dist/cli/commands/tool.d.ts +11 -0
- package/dist/cli/commands/tool.js +121 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +89 -0
- package/dist/cli/root-action.d.ts +7 -0
- package/dist/cli/root-action.js +15 -0
- package/dist/{lib → core}/api-client.d.ts +106 -15
- package/dist/{lib → core}/api-client.js +267 -75
- package/dist/{lib → core}/async-op-lifecycle.d.ts +3 -4
- package/dist/{lib → core}/async-op-lifecycle.js +3 -4
- package/dist/{lib → core}/auth.d.ts +14 -6
- package/dist/{lib → core}/auth.js +56 -40
- package/dist/core/capabilities/agent-playbook.d.ts +20 -0
- package/dist/core/capabilities/agent-playbook.js +218 -0
- package/dist/core/capabilities/api-docs.d.ts +36 -0
- package/dist/core/capabilities/api-docs.js +118 -0
- package/dist/core/capabilities/asset-import.d.ts +49 -0
- package/dist/core/capabilities/asset-import.js +134 -0
- package/dist/core/capabilities/camera-view.d.ts +98 -0
- package/dist/core/capabilities/camera-view.js +222 -0
- package/dist/core/capabilities/capture.d.ts +63 -0
- package/dist/core/capabilities/capture.js +67 -0
- package/dist/core/capabilities/console-read.d.ts +17 -0
- package/dist/core/capabilities/console-read.js +21 -0
- package/dist/{lib → core/capabilities}/creator.d.ts +1 -29
- package/dist/{lib → core/capabilities}/creator.js +14 -33
- package/dist/{lib → core/capabilities}/debug-report.d.ts +1 -1
- package/dist/{lib → core/capabilities}/debug-report.js +12 -31
- package/dist/{commands → core/capabilities}/doctor.d.ts +7 -2
- package/dist/{commands → core/capabilities}/doctor.js +47 -73
- package/dist/core/capabilities/engine-fallbacks.d.ts +26 -0
- package/dist/core/capabilities/engine-fallbacks.js +36 -0
- package/dist/core/capabilities/engine-ops.d.ts +33 -0
- package/dist/core/capabilities/engine-ops.js +145 -0
- package/dist/core/capabilities/engine-receipt.d.ts +53 -0
- package/dist/core/capabilities/engine-receipt.js +134 -0
- package/dist/core/capabilities/events.d.ts +200 -0
- package/dist/core/capabilities/events.js +383 -0
- package/dist/core/capabilities/fabricate-mesh.d.ts +111 -0
- package/dist/core/capabilities/fabricate-mesh.js +165 -0
- package/dist/core/capabilities/frame-quality.d.ts +71 -0
- package/dist/core/capabilities/frame-quality.js +449 -0
- package/dist/core/capabilities/game-task-plan.d.ts +66 -0
- package/dist/{lib → core/capabilities}/game-task-plan.js +59 -8
- package/dist/core/capabilities/hdri-import.d.ts +90 -0
- package/dist/core/capabilities/hdri-import.js +250 -0
- package/dist/core/capabilities/image-generation.d.ts +24 -0
- package/dist/core/capabilities/image-generation.js +22 -0
- package/dist/core/capabilities/navigation/open.d.ts +156 -0
- package/dist/core/capabilities/navigation/open.js +567 -0
- package/dist/core/capabilities/navigation/render-product-map.d.ts +1 -0
- package/dist/core/capabilities/navigation/render-product-map.js +84 -0
- package/dist/core/capabilities/navigation/targets.d.ts +87 -0
- package/dist/core/capabilities/navigation/targets.js +250 -0
- package/dist/core/capabilities/play-determinism.d.ts +35 -0
- package/dist/core/capabilities/play-determinism.js +86 -0
- package/dist/core/capabilities/project-context.d.ts +114 -0
- package/dist/core/capabilities/project-context.js +249 -0
- package/dist/core/capabilities/runtime-control.d.ts +540 -0
- package/dist/core/capabilities/runtime-control.js +1011 -0
- package/dist/core/capabilities/scene-kind.d.ts +19 -0
- package/dist/core/capabilities/scene-kind.js +137 -0
- package/dist/core/capabilities/scene-script.d.ts +38 -0
- package/dist/core/capabilities/scene-script.js +45 -0
- package/dist/core/capabilities/tool-dispatch.d.ts +42 -0
- package/dist/core/capabilities/tool-dispatch.js +1490 -0
- package/dist/core/capabilities/ui-control.d.ts +179 -0
- package/dist/core/capabilities/ui-control.js +423 -0
- package/dist/core/capabilities/variant-types.d.ts +22 -0
- package/dist/core/capabilities/variant-types.js +101 -0
- package/dist/core/capability-skew.d.ts +205 -0
- package/dist/core/capability-skew.js +386 -0
- package/dist/{lib → core}/config.d.ts +11 -1
- package/dist/{lib → core}/config.js +13 -2
- package/dist/core/embeddings.d.ts +78 -0
- package/dist/core/embeddings.js +166 -0
- package/dist/core/engine-install.d.ts +105 -0
- package/dist/core/engine-install.js +190 -0
- package/dist/core/engine.d.ts +94 -0
- package/dist/{lib → core}/engine.js +74 -28
- package/dist/core/feedback/client.d.ts +88 -0
- package/dist/core/feedback/client.js +182 -0
- package/dist/{lib → core}/format.d.ts +0 -1
- package/dist/{lib → core}/format.js +1 -1
- package/dist/core/headless/connection.d.ts +86 -0
- package/dist/core/headless/connection.js +97 -0
- package/dist/core/headless/editor-connection.d.ts +26 -0
- package/dist/core/headless/editor-connection.js +81 -0
- package/dist/core/headless/mcp-routing.d.ts +38 -0
- package/dist/core/headless/mcp-routing.js +83 -0
- package/dist/core/headless/registry.d.ts +91 -0
- package/dist/core/headless/registry.js +226 -0
- package/dist/core/headless/resolve.d.ts +46 -0
- package/dist/core/headless/resolve.js +75 -0
- package/dist/core/headless/spawn.d.ts +46 -0
- package/dist/core/headless/spawn.js +205 -0
- package/dist/core/headless/worker-connection.d.ts +96 -0
- package/dist/core/headless/worker-connection.js +353 -0
- package/dist/core/headless/worker-engine-client.d.ts +58 -0
- package/dist/core/headless/worker-engine-client.js +246 -0
- package/dist/core/launch-posture.d.ts +170 -0
- package/dist/core/launch-posture.js +317 -0
- package/dist/core/library-read.d.ts +73 -0
- package/dist/core/library-read.js +279 -0
- package/dist/core/library-search.d.ts +143 -0
- package/dist/core/library-search.js +301 -0
- package/dist/{lib → core}/log-filters.js +4 -2
- package/dist/{lib → core}/mcp-log.js +2 -17
- package/dist/core/package-root.d.ts +9 -0
- package/dist/core/package-root.js +11 -0
- package/dist/core/redact.d.ts +20 -0
- package/dist/core/redact.js +64 -0
- package/dist/core/registry-search.d.ts +167 -0
- package/dist/core/registry-search.js +358 -0
- package/dist/core/skills-registry.d.ts +47 -0
- package/dist/core/skills-registry.js +83 -0
- package/dist/{lib → core}/store.js +11 -7
- package/dist/{lib → core}/summer-compatibility.js +3 -3
- package/dist/{lib → core}/telemetry.js +5 -2
- package/dist/core/templates.d.ts +98 -0
- package/dist/core/templates.js +241 -0
- package/dist/core/tool-errors.d.ts +30 -0
- package/dist/core/tool-errors.js +40 -0
- package/dist/core/trajectory.d.ts +80 -0
- package/dist/core/trajectory.js +307 -0
- package/dist/core/util/http.d.ts +13 -0
- package/dist/core/util/http.js +28 -0
- package/dist/core/util/json.d.ts +12 -0
- package/dist/core/util/json.js +21 -0
- package/dist/core/util/process.d.ts +3 -0
- package/dist/core/util/process.js +13 -0
- package/dist/core/util/sleep.d.ts +1 -0
- package/dist/core/util/sleep.js +3 -0
- package/dist/core/version.d.ts +3 -0
- package/dist/core/version.js +5 -0
- package/dist/{lib → installer}/agent-config.d.ts +20 -1
- package/dist/{lib → installer}/agent-config.js +148 -23
- package/dist/installer/legacy-skills.d.ts +26 -0
- package/dist/installer/legacy-skills.js +53 -0
- package/dist/installer/setup.d.ts +76 -0
- package/dist/installer/setup.js +146 -0
- package/dist/installer/skill-locations.d.ts +45 -0
- package/dist/installer/skill-locations.js +170 -0
- package/dist/installer/version-check.d.ts +174 -0
- package/dist/{lib → installer}/version-check.js +173 -42
- package/dist/{lib/mcp-boot-notice.d.ts → mcp/boot-notice.d.ts} +1 -1
- package/dist/{commands/mcp.js → mcp/command.js} +18 -6
- package/dist/mcp/server.d.ts +23 -3
- package/dist/mcp/server.js +122 -28
- package/dist/mcp/tools/asset-tools.js +62 -142
- package/dist/mcp/tools/creator-tools.js +5 -23
- package/dist/mcp/tools/debug-tools.js +61 -18
- package/dist/mcp/tools/event-tools.d.ts +14 -0
- package/dist/mcp/tools/event-tools.js +41 -0
- package/dist/mcp/tools/fabricate-tools.d.ts +2 -0
- package/dist/mcp/tools/fabricate-tools.js +28 -0
- package/dist/mcp/tools/feedback-tools.d.ts +77 -0
- package/dist/mcp/tools/feedback-tools.js +88 -0
- package/dist/mcp/tools/file-tools.js +6 -53
- package/dist/mcp/tools/generate-tools.js +37 -63
- package/dist/mcp/tools/library-tools.d.ts +11 -0
- package/dist/mcp/tools/library-tools.js +42 -0
- package/dist/mcp/tools/navigation-tools.d.ts +7 -0
- package/dist/mcp/tools/navigation-tools.js +37 -0
- package/dist/mcp/tools/perception-tools.d.ts +20 -0
- package/dist/mcp/tools/perception-tools.js +146 -0
- package/dist/mcp/tools/project-tools.d.ts +14 -0
- package/dist/mcp/tools/project-tools.js +72 -281
- package/dist/mcp/tools/runtime-tools.d.ts +2 -0
- package/dist/mcp/tools/runtime-tools.js +92 -0
- package/dist/mcp/tools/scene-tools.d.ts +3 -0
- package/dist/mcp/tools/scene-tools.js +68 -119
- package/dist/mcp/tools/script-tools.d.ts +3 -0
- package/dist/mcp/tools/script-tools.js +118 -0
- package/dist/mcp/tools/spatial-tools.d.ts +2 -0
- package/dist/mcp/tools/spatial-tools.js +485 -0
- package/dist/mcp/tools/text-json.d.ts +8 -0
- package/dist/mcp/tools/text-json.js +12 -0
- package/dist/mcp/tools/{cloud-tools.d.ts → ui-tools.d.ts} +1 -1
- package/dist/mcp/tools/ui-tools.js +82 -0
- package/dist/mcp/tools/visual-tools.d.ts +2 -7
- package/dist/mcp/tools/visual-tools.js +383 -101
- package/dist/mcp/tools/with-engine.d.ts +9 -15
- package/dist/mcp/tools/with-engine.js +60 -96
- package/dist/project-memory/project-manifest.d.ts +36 -0
- package/dist/project-memory/project-manifest.js +50 -0
- package/dist/project-memory/project-memory.d.ts +57 -0
- package/dist/{lib → project-memory}/project-memory.js +46 -0
- package/gemini-extension.json +103 -2
- package/hooks/hooks-cursor.json +2 -2
- package/hooks/hooks.json +2 -1
- package/hooks/pre-commit-doctor.sh +45 -39
- package/hooks/run-hook.cmd +30 -23
- package/hooks/run-hook.sh +20 -0
- package/hooks/session-start.sh +18 -7
- package/integrations/README.md +70 -0
- package/integrations/claude/README.md +19 -0
- package/integrations/claude/manifest-target.json +16 -0
- package/integrations/cline/README.md +13 -0
- package/integrations/cline/manifest-target.json +3 -0
- package/integrations/codex/README.md +15 -0
- package/integrations/codex/manifest-target.json +5 -0
- package/integrations/cursor/README.md +16 -0
- package/integrations/cursor/manifest-target.json +5 -0
- package/integrations/factory/README.md +26 -0
- package/integrations/factory/manifest-target.json +5 -0
- package/integrations/gemini/README.md +26 -0
- package/integrations/gemini/manifest-target.json +5 -0
- package/integrations/github-copilot/README.md +12 -0
- package/integrations/github-copilot/manifest-target.json +3 -0
- package/integrations/kilo-code/README.md +16 -0
- package/integrations/kilo-code/manifest-target.json +3 -0
- package/integrations/lm-studio/README.md +12 -0
- package/integrations/lm-studio/manifest-target.json +3 -0
- package/integrations/opencode/README.md +15 -0
- package/integrations/opencode/manifest-target.json +3 -0
- package/integrations/roo-code/README.md +13 -0
- package/integrations/roo-code/manifest-target.json +3 -0
- package/integrations/vscode-copilot/README.md +12 -0
- package/integrations/vscode-copilot/manifest-target.json +3 -0
- package/integrations/windsurf/README.md +13 -0
- package/integrations/windsurf/manifest-target.json +3 -0
- package/library/references/collaborative-protocol/resource.yaml +24 -0
- package/library/references/gd-style/resource.yaml +24 -0
- package/{references → library/references/godot-version}/godot-version.md +6 -6
- package/library/references/godot-version/resource.yaml +22 -0
- package/library/references/headless-routing/headless-routing.md +46 -0
- package/library/references/headless-routing/resource.yaml +24 -0
- package/library/references/mcp-fresh-chat-playbook/mcp-fresh-chat-playbook.md +49 -0
- package/library/references/mcp-fresh-chat-playbook/resource.yaml +23 -0
- package/library/references/mcp-tools-reference/mcp-tools-reference.md +271 -0
- package/library/references/mcp-tools-reference/resource.yaml +17 -0
- package/library/references/product-map/product-map.md +103 -0
- package/library/references/product-map/resource.yaml +33 -0
- package/{references → library/references/public-surface-language}/public-surface-language.md +5 -7
- package/library/references/public-surface-language/resource.yaml +17 -0
- package/library/references/summer-folder/resource.yaml +20 -0
- package/{references → library/references/summer-folder}/summer-folder.md +22 -21
- package/{skills/rendering-and-lighting → library/skills}/3d-lighting/SKILL.md +15 -11
- package/library/skills/3d-lighting/resource.yaml +27 -0
- package/{skills/audio → library/skills}/adaptive-music/SKILL.md +1 -1
- package/library/skills/adaptive-music/resource.yaml +28 -0
- package/library/skills/agent-playtesting/SKILL.md +148 -0
- package/library/skills/agent-playtesting/resource.yaml +52 -0
- package/library/skills/ambient-bed/resource.yaml +24 -0
- package/{skills/video → library/skills}/animated-loop/SKILL.md +1 -1
- package/library/skills/animated-loop/resource.yaml +27 -0
- package/{skills/animation → library/skills}/animation-tree/SKILL.md +29 -14
- package/library/skills/animation-tree/resource.yaml +33 -0
- package/{skills/rendering-and-lighting → library/skills}/art-direction/SKILL.md +3 -3
- package/library/skills/art-direction/resource.yaml +29 -0
- package/{skills/asset-pipeline → library/skills}/asset-strategy/SKILL.md +44 -44
- package/library/skills/asset-strategy/resource.yaml +63 -0
- package/{skills/audio → library/skills}/audio-direction/SKILL.md +7 -7
- package/library/skills/audio-direction/resource.yaml +32 -0
- package/library/skills/auto-fire-targeting/resource.yaml +22 -0
- package/{skills/scene-and-project → library/skills}/brainstorm-game/SKILL.md +8 -8
- package/library/skills/brainstorm-game/resource.yaml +30 -0
- package/{skills/workflow → library/skills}/brainstorming/SKILL.md +2 -22
- package/library/skills/brainstorming/resource.yaml +23 -0
- package/{skills/workflow → library/skills}/brainstorming/spec-document-reviewer-prompt.md +1 -1
- package/{skills/scene-and-project → library/skills}/browse-templates/SKILL.md +18 -18
- package/library/skills/browse-templates/resource.yaml +23 -0
- package/library/skills/celeste-momentum-platforming/SKILL.md +366 -0
- package/library/skills/celeste-momentum-platforming/resource.yaml +33 -0
- package/library/skills/character-animation-wiring/SKILL.md +249 -0
- package/library/skills/character-animation-wiring/resource.yaml +39 -0
- package/{skills/3d-assets → library/skills}/character-model/SKILL.md +25 -25
- package/library/skills/character-model/resource.yaml +36 -0
- package/{skills/2d-assets → library/skills}/character-portrait/SKILL.md +14 -14
- package/library/skills/character-portrait/resource.yaml +30 -0
- package/{skills/video → library/skills}/cinematic-cutscene/SKILL.md +2 -2
- package/library/skills/cinematic-cutscene/resource.yaml +29 -0
- package/{skills/2d-assets → library/skills}/concept-art/SKILL.md +15 -15
- package/library/skills/concept-art/resource.yaml +34 -0
- package/{skills/2d-assets → library/skills}/create-asset-sheet/SKILL.md +8 -8
- package/library/skills/create-asset-sheet/resource.yaml +33 -0
- package/{skills/debugging → library/skills}/debug/SKILL.md +3 -3
- package/library/skills/debug/resource.yaml +31 -0
- package/{skills/workflow → library/skills}/debugging-game-feel/SKILL.md +11 -11
- package/library/skills/debugging-game-feel/resource.yaml +25 -0
- package/{skills/level-design → library/skills}/design-level/SKILL.md +6 -6
- package/library/skills/design-level/resource.yaml +31 -0
- package/{skills/gameplay-mechanics → library/skills}/design-mechanic/SKILL.md +3 -3
- package/library/skills/design-mechanic/resource.yaml +31 -0
- package/{skills/ai-and-npcs → library/skills}/design-npc/SKILL.md +7 -3
- package/library/skills/design-npc/resource.yaml +29 -0
- package/{skills/workflow → library/skills}/diagnosing-perf-regressions/SKILL.md +10 -10
- package/library/skills/diagnosing-perf-regressions/resource.yaml +25 -0
- package/{skills/workflow → library/skills}/dispatching-parallel-agents/SKILL.md +8 -8
- package/library/skills/dispatching-parallel-agents/resource.yaml +23 -0
- package/library/skills/driving-the-editor-ui/SKILL.md +85 -0
- package/library/skills/driving-the-editor-ui/resource.yaml +46 -0
- package/{skills/3d-assets → library/skills}/environment-kit/SKILL.md +11 -11
- package/library/skills/environment-kit/resource.yaml +29 -0
- package/{skills/deployment → library/skills}/export-and-ship/SKILL.md +5 -5
- package/library/skills/export-and-ship/resource.yaml +32 -0
- package/library/skills/fabricating-assets/SKILL.md +195 -0
- package/library/skills/fabricating-assets/resource.yaml +52 -0
- package/{skills/animation → library/skills}/facial-and-lipsync/SKILL.md +23 -11
- package/library/skills/facial-and-lipsync/resource.yaml +36 -0
- package/{skills/character-controllers → library/skills}/fps-controller/SKILL.md +8 -4
- package/library/skills/fps-controller/resource.yaml +29 -0
- package/{skills/visual-effects → library/skills}/game-feel/SKILL.md +7 -7
- package/library/skills/game-feel/resource.yaml +27 -0
- package/library/skills/gameskill/SKILL.md +64 -0
- package/library/skills/gameskill/resource.yaml +22 -0
- package/library/skills/gdscript-patterns/resource.yaml +23 -0
- package/{skills/animation → library/skills}/generate-motion/SKILL.md +16 -16
- package/library/skills/generate-motion/resource.yaml +34 -0
- package/library/skills/godogen-visual-proof-game-generation/SKILL.md +223 -0
- package/library/skills/godogen-visual-proof-game-generation/resource.yaml +33 -0
- package/{skills/workflow → library/skills}/headless-scripting/SKILL.md +14 -7
- package/library/skills/headless-scripting/resource.yaml +26 -0
- package/{skills/multiplayer-and-networking → library/skills}/host-authoritative-state/SKILL.md +1 -1
- package/library/skills/host-authoritative-state/resource.yaml +28 -0
- package/{skills/2d-assets → library/skills}/instantiate-asset-pack/SKILL.md +10 -12
- package/library/skills/instantiate-asset-pack/resource.yaml +29 -0
- package/{skills/workflow → library/skills}/investigating-bugs/SKILL.md +4 -4
- package/{skills/workflow → library/skills}/investigating-bugs/condition-based-waiting.md +8 -8
- package/library/skills/investigating-bugs/resource.yaml +24 -0
- package/{skills/workflow → library/skills}/investigating-bugs/root-cause-tracing.md +1 -7
- package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +164 -0
- package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +35 -0
- package/{skills/scene-and-project → library/skills}/make-game/SKILL.md +23 -23
- package/library/skills/make-game/resource.yaml +35 -0
- package/library/skills/music-track/resource.yaml +28 -0
- package/library/skills/navigate-summer/SKILL.md +61 -0
- package/library/skills/navigate-summer/resource.yaml +35 -0
- package/{skills/scene-and-project → library/skills}/new-project/SKILL.md +10 -10
- package/library/skills/new-project/resource.yaml +28 -0
- package/{skills/3d-assets → library/skills}/organic-model/SKILL.md +16 -16
- package/library/skills/organic-model/resource.yaml +32 -0
- package/{skills/multiplayer-and-networking → library/skills}/peer-to-peer-multiplayer/SKILL.md +2 -2
- package/library/skills/peer-to-peer-multiplayer/resource.yaml +28 -0
- package/{skills/2d-assets → library/skills}/pixel-art/SKILL.md +13 -13
- package/library/skills/pixel-art/resource.yaml +31 -0
- package/library/skills/play/resource.yaml +26 -0
- package/{skills/workflow → library/skills}/playtesting-a-feature/SKILL.md +41 -22
- package/library/skills/playtesting-a-feature/resource.yaml +31 -0
- package/{skills/animation → library/skills}/procedural-animation/SKILL.md +25 -10
- package/library/skills/procedural-animation/resource.yaml +33 -0
- package/{skills/3d-assets → library/skills}/prop-model/SKILL.md +13 -13
- package/library/skills/prop-model/resource.yaml +33 -0
- package/library/skills/psx-retro-rendering/SKILL.md +416 -0
- package/library/skills/psx-retro-rendering/resource.yaml +36 -0
- package/library/skills/realtime-wet-surfaces/SKILL.md +189 -0
- package/library/skills/realtime-wet-surfaces/resource.yaml +31 -0
- package/{skills/deployment → library/skills}/remote-deploy/SKILL.md +3 -3
- package/library/skills/remote-deploy/resource.yaml +23 -0
- package/{skills/animation → library/skills}/retarget/SKILL.md +15 -14
- package/library/skills/retarget/resource.yaml +33 -0
- package/library/skills/running-in-the-cloud/SKILL.md +103 -0
- package/library/skills/running-in-the-cloud/resource.yaml +33 -0
- package/{skills/scene-and-project → library/skills}/scene-composition/SKILL.md +9 -1
- package/library/skills/scene-composition/resource.yaml +27 -0
- package/library/skills/scene-hierarchy-design/SKILL.md +102 -0
- package/library/skills/scene-hierarchy-design/resource.yaml +31 -0
- package/library/skills/scene-scripting/SKILL.md +764 -0
- package/library/skills/scene-scripting/resource.yaml +58 -0
- package/{skills/level-design → library/skills}/scene-to-level/SKILL.md +16 -17
- package/library/skills/scene-to-level/resource.yaml +33 -0
- package/{skills/multiplayer-and-networking → library/skills}/setup-multiplayer/SKILL.md +1 -1
- package/library/skills/setup-multiplayer/resource.yaml +28 -0
- package/library/skills/skill-create/SKILL.md +138 -0
- package/library/skills/skill-create/resource.yaml +25 -0
- package/{skills/workflow → library/skills}/skill-improve/SKILL.md +2 -2
- package/library/skills/skill-improve/resource.yaml +25 -0
- package/{skills/workflow → library/skills}/skill-test/SKILL.md +4 -4
- package/library/skills/skill-test/resource.yaml +26 -0
- package/library/skills/skintokens-auto-rigging/SKILL.md +200 -0
- package/library/skills/skintokens-auto-rigging/resource.yaml +38 -0
- package/{skills/2d-assets → library/skills}/skybox-panorama/SKILL.md +8 -8
- package/library/skills/skybox-panorama/resource.yaml +28 -0
- package/{skills/audio → library/skills}/sound-effect/SKILL.md +2 -2
- package/library/skills/sound-effect/resource.yaml +27 -0
- package/library/skills/spatial-placement/SKILL.md +74 -0
- package/library/skills/spatial-placement/resource.yaml +42 -0
- package/library/skills/spatial-placement/tests/spec.md +65 -0
- package/{skills/2d-assets → library/skills}/sprite-sheet/SKILL.md +12 -12
- package/library/skills/sprite-sheet/resource.yaml +32 -0
- package/{skills/2d-assets → library/skills}/tileable-texture/SKILL.md +9 -9
- package/library/skills/tileable-texture/resource.yaml +31 -0
- package/{skills/video → library/skills}/trailer-shot/SKILL.md +1 -1
- package/library/skills/trailer-shot/resource.yaml +27 -0
- package/{skills/performance → library/skills}/tune-performance/SKILL.md +6 -6
- package/library/skills/tune-performance/resource.yaml +31 -0
- package/{skills/ui-and-ux → library/skills}/ui-basics/SKILL.md +1 -1
- package/library/skills/ui-basics/resource.yaml +25 -0
- package/{skills/2d-assets → library/skills}/ui-graphics/SKILL.md +11 -11
- package/library/skills/ui-graphics/resource.yaml +29 -0
- package/{skills/2d-assets → library/skills}/use-widget-asset/SKILL.md +4 -4
- package/library/skills/use-widget-asset/resource.yaml +29 -0
- package/{skills/workflow → library/skills}/using-summer/SKILL.md +12 -9
- package/library/skills/using-summer/resource.yaml +41 -0
- package/{skills/3d-assets → library/skills}/vehicle-model/SKILL.md +18 -18
- package/library/skills/vehicle-model/resource.yaml +34 -0
- package/{skills/workflow → library/skills}/verification-before-completion/SKILL.md +10 -10
- package/library/skills/verification-before-completion/resource.yaml +23 -0
- package/library/skills/verifying-scenes/SKILL.md +98 -0
- package/library/skills/verifying-scenes/resource.yaml +42 -0
- package/{skills/visual-effects/recipes/dissolve → library/skills/vfx-dissolve}/SKILL.md +31 -11
- package/library/skills/vfx-dissolve/resource.yaml +33 -0
- package/{skills/visual-effects/recipes/fire → library/skills/vfx-fire}/SKILL.md +43 -12
- package/library/skills/vfx-fire/_building-blocks/noise-3d-fbm.gdshaderinc +45 -0
- package/library/skills/vfx-fire/resource.yaml +35 -0
- package/{skills/visual-effects/recipes/hit-spark → library/skills/vfx-hit-spark}/SKILL.md +16 -10
- package/library/skills/vfx-hit-spark/_building-blocks/additive-billboard-particles.md +37 -0
- package/library/skills/vfx-hit-spark/resource.yaml +34 -0
- package/{skills/visual-effects/recipes/lightning → library/skills/vfx-lightning}/SKILL.md +24 -11
- package/library/skills/vfx-lightning/_building-blocks/additive-billboard-particles.md +37 -0
- package/library/skills/vfx-lightning/resource.yaml +33 -0
- package/{skills/visual-effects/recipes/magic-glow → library/skills/vfx-magic-glow}/SKILL.md +31 -11
- package/library/skills/vfx-magic-glow/_building-blocks/additive-billboard-particles.md +37 -0
- package/library/skills/vfx-magic-glow/resource.yaml +34 -0
- package/{skills/visual-effects/recipes/muzzle-flash → library/skills/vfx-muzzle-flash}/SKILL.md +29 -9
- package/library/skills/vfx-muzzle-flash/_building-blocks/additive-billboard-particles.md +37 -0
- package/library/skills/vfx-muzzle-flash/_building-blocks/trauma-shake-snippet.md +53 -0
- package/library/skills/vfx-muzzle-flash/resource.yaml +35 -0
- package/{skills/visual-effects/recipes/smoke → library/skills/vfx-smoke}/SKILL.md +35 -9
- package/library/skills/vfx-smoke/_building-blocks/noise-3d-fbm.gdshaderinc +45 -0
- package/library/skills/vfx-smoke/resource.yaml +32 -0
- package/{skills/visual-effects/recipes/water-ripple → library/skills/vfx-water-ripple}/SKILL.md +31 -9
- package/library/skills/vfx-water-ripple/_building-blocks/additive-billboard-particles.md +37 -0
- package/library/skills/vfx-water-ripple/resource.yaml +31 -0
- package/library/skills/voice-line/resource.yaml +27 -0
- package/library/skills/world-building-3d/SKILL.md +105 -0
- package/library/skills/world-building-3d/references/spatial-tools.md +50 -0
- package/library/skills/world-building-3d/resource.yaml +44 -0
- package/library/skills/world-building-3d/tests/spec.md +48 -0
- package/{skills/workflow → library/skills}/writing-plans/SKILL.md +19 -14
- package/library/skills/writing-plans/resource.yaml +23 -0
- package/{skills/workflow → library/skills}/writing-skills/SKILL.md +38 -44
- package/library/skills/writing-skills/resource.yaml +29 -0
- package/{skills/workflow → library/skills}/writing-skills/testing-skills-with-subagents.md +13 -14
- package/library/templates/2d-brario-platformer/resource.yaml +21 -0
- package/library/templates/2d-dungeon-roguelike/resource.yaml +23 -0
- package/library/templates/2d-grid-puzzle/resource.yaml +21 -0
- package/library/templates/2d-plants-and-zombies-tower-defense/resource.yaml +21 -0
- package/library/templates/2d-platformer/resource.yaml +24 -0
- package/library/templates/2d-rpg/resource.yaml +21 -0
- package/library/templates/2d-vampire-survivor-roguelike/resource.yaml +21 -0
- package/library/templates/3d-basic/resource.yaml +16 -0
- package/library/templates/3d-city-kit/resource.yaml +24 -0
- package/library/templates/3d-fps-old-school/resource.yaml +21 -0
- package/library/templates/3d-fps-simple-animated-npc/resource.yaml +21 -0
- package/library/templates/3d-lan-multiplayer-starter/resource.yaml +22 -0
- package/library/templates/3d-open-world-explore-tps/resource.yaml +21 -0
- package/library/templates/3d-procedural-road-world/resource.yaml +21 -0
- package/library/templates/3d-racing-game/resource.yaml +21 -0
- package/library/templates/3d-royale-clash-type/resource.yaml +21 -0
- package/library/templates/3d-third-person-controller/resource.yaml +21 -0
- package/library/templates/3d-voxel-sandbox/resource.yaml +24 -0
- package/library/templates/README.md +94 -0
- package/library/templates/empty/resource.yaml +16 -0
- package/library/tools/add-node/resource.yaml +60 -0
- package/library/tools/align-distribute-3d/resource.yaml +87 -0
- package/library/tools/api-docs/resource.yaml +57 -0
- package/library/tools/batch/resource.yaml +52 -0
- package/library/tools/camera-bookmark/resource.yaml +73 -0
- package/library/tools/check-job/resource.yaml +45 -0
- package/library/tools/clear-console/resource.yaml +40 -0
- package/library/tools/connect-signal/resource.yaml +63 -0
- package/library/tools/create-debug-report/resource.yaml +67 -0
- package/library/tools/create-scene/resource.yaml +59 -0
- package/library/tools/creator-config/resource.yaml +63 -0
- package/library/tools/creator-publish/resource.yaml +73 -0
- package/library/tools/creator-releases/resource.yaml +53 -0
- package/library/tools/fabricate-3d/resource.yaml +108 -0
- package/library/tools/game-control/resource.yaml +84 -0
- package/library/tools/game-input/resource.yaml +159 -0
- package/library/tools/game-probe/resource.yaml +90 -0
- package/library/tools/generate-3d/resource.yaml +112 -0
- package/library/tools/generate-audio/resource.yaml +80 -0
- package/library/tools/generate-image/resource.yaml +62 -0
- package/library/tools/generate-motion/resource.yaml +66 -0
- package/library/tools/generate-video/resource.yaml +66 -0
- package/library/tools/get-agent-playbook/resource.yaml +40 -0
- package/library/tools/get-asset/resource.yaml +42 -0
- package/library/tools/get-asset-download-url/resource.yaml +52 -0
- package/library/tools/get-console/resource.yaml +69 -0
- package/library/tools/get-debugger-errors/resource.yaml +56 -0
- package/library/tools/get-debugger-warnings/resource.yaml +52 -0
- package/library/tools/get-diagnostics/resource.yaml +42 -0
- package/library/tools/get-project-context/resource.yaml +45 -0
- package/library/tools/get-runtime-tree/resource.yaml +62 -0
- package/library/tools/get-scene-tree/resource.yaml +52 -0
- package/library/tools/get-script-errors/resource.yaml +45 -0
- package/library/tools/get-studio-workflow/resource.yaml +43 -0
- package/library/tools/import-asset/resource.yaml +73 -0
- package/library/tools/import-asset-by-id/resource.yaml +56 -0
- package/library/tools/import-from-url/resource.yaml +51 -0
- package/library/tools/import-from-url-batch/resource.yaml +60 -0
- package/library/tools/import-hdri/resource.yaml +69 -0
- package/library/tools/input-map-bind/resource.yaml +52 -0
- package/library/tools/inspect-node/resource.yaml +46 -0
- package/library/tools/inspect-resource/resource.yaml +45 -0
- package/library/tools/inspect-runtime-node/resource.yaml +54 -0
- package/library/tools/instantiate-scene/resource.yaml +62 -0
- package/library/tools/is-running/resource.yaml +40 -0
- package/library/tools/library-feedback/resource.yaml +89 -0
- package/library/tools/list-my-assets/resource.yaml +56 -0
- package/library/tools/navigation-probe/resource.yaml +85 -0
- package/library/tools/open/resource.yaml +80 -0
- package/library/tools/open-main-scene/resource.yaml +40 -0
- package/library/tools/open-scene/resource.yaml +46 -0
- package/library/tools/play/resource.yaml +91 -0
- package/library/tools/project-setting/resource.yaml +53 -0
- package/library/tools/read-file/resource.yaml +47 -0
- package/library/tools/read-library/resource.yaml +67 -0
- package/library/tools/recent-events/resource.yaml +71 -0
- package/library/tools/remove-node/resource.yaml +51 -0
- package/library/tools/replace-node/resource.yaml +57 -0
- package/library/tools/replace-text/resource.yaml +61 -0
- package/library/tools/run-editor-script/resource.yaml +61 -0
- package/library/tools/run-script/resource.yaml +73 -0
- package/library/tools/runtime-animate/resource.yaml +140 -0
- package/library/tools/runtime-call/resource.yaml +74 -0
- package/library/tools/runtime-set/resource.yaml +80 -0
- package/library/tools/runtime-spawn/resource.yaml +95 -0
- package/library/tools/save-scene/resource.yaml +50 -0
- package/library/tools/screenshot/resource.yaml +112 -0
- package/library/tools/search-assets/resource.yaml +67 -0
- package/library/tools/search-library/resource.yaml +81 -0
- package/library/tools/select-node/resource.yaml +48 -0
- package/library/tools/set-prop/resource.yaml +64 -0
- package/library/tools/set-resource-property/resource.yaml +66 -0
- package/library/tools/slice-asset-sheet/resource.yaml +47 -0
- package/library/tools/snap-to-surface/resource.yaml +90 -0
- package/library/tools/snapshot-diff/resource.yaml +58 -0
- package/library/tools/starcast/resource.yaml +120 -0
- package/library/tools/start-game-task/resource.yaml +91 -0
- package/library/tools/stop/resource.yaml +51 -0
- package/library/tools/test-placement/resource.yaml +109 -0
- package/library/tools/ui-actions/resource.yaml +77 -0
- package/library/tools/ui-activate/resource.yaml +88 -0
- package/library/tools/ui-screenshot/resource.yaml +63 -0
- package/library/tools/ui-tree/resource.yaml +69 -0
- package/library/tools/wait-for-event/resource.yaml +84 -0
- package/library/tools/world-snapshot/resource.yaml +60 -0
- package/library/tools/write-file/resource.yaml +54 -0
- package/package.json +22 -16
- package/registry/generated/aliases.json +207 -0
- package/registry/generated/counts.json +12 -0
- package/registry/generated/gemini-extension.json +122 -0
- package/registry/generated/index.json +7709 -0
- package/registry/generated/marketplace.claude.json +44 -0
- package/registry/generated/mcp.json +13 -0
- package/registry/generated/plugin.claude.json +135 -0
- package/registry/generated/plugin.codex.json +144 -0
- package/registry/generated/plugin.cursor.json +134 -0
- package/registry/generated/plugin.factory.json +117 -0
- package/registry/generated/skills-registry.json +851 -0
- package/registry/generated/templates-registry.json +455 -0
- package/registry/schemas/allowed-hosts.json +19 -0
- package/registry/schemas/collection.schema.json +68 -0
- package/registry/schemas/domains.json +96 -0
- package/registry/schemas/example.schema.json +11 -0
- package/registry/schemas/reference.schema.json +10 -0
- package/registry/schemas/resource.schema.json +154 -0
- package/registry/schemas/skill.schema.json +14 -0
- package/registry/schemas/template.schema.json +46 -0
- package/registry/schemas/tool.schema.json +61 -0
- package/_persona/summer/SKILL.md +0 -113
- package/dist/bin/postinstall.d.ts +0 -2
- package/dist/bin/postinstall.js +0 -3
- package/dist/commands/cloud.d.ts +0 -2
- package/dist/commands/cloud.js +0 -80
- package/dist/commands/create.d.ts +0 -3
- package/dist/commands/create.js +0 -171
- package/dist/commands/install.d.ts +0 -19
- package/dist/commands/install.js +0 -194
- package/dist/commands/list.js +0 -67
- package/dist/commands/logout.js +0 -13
- package/dist/commands/logs.d.ts +0 -2
- package/dist/commands/logs.js +0 -19
- package/dist/commands/open.d.ts +0 -2
- package/dist/commands/open.js +0 -32
- package/dist/commands/orchestrator.d.ts +0 -8
- package/dist/commands/orchestrator.js +0 -143
- package/dist/commands/run.d.ts +0 -2
- package/dist/commands/run.js +0 -167
- package/dist/commands/status.js +0 -46
- package/dist/lib/banner.d.ts +0 -4
- package/dist/lib/banner.js +0 -122
- package/dist/lib/cloud/api.d.ts +0 -79
- package/dist/lib/cloud/api.js +0 -107
- package/dist/lib/cloud/apply.d.ts +0 -32
- package/dist/lib/cloud/apply.js +0 -294
- package/dist/lib/cloud/checkpoint.d.ts +0 -26
- package/dist/lib/cloud/checkpoint.js +0 -142
- package/dist/lib/cloud/conflicts.d.ts +0 -55
- package/dist/lib/cloud/conflicts.js +0 -131
- package/dist/lib/cloud/containment.d.ts +0 -8
- package/dist/lib/cloud/containment.js +0 -52
- package/dist/lib/cloud/diff.d.ts +0 -39
- package/dist/lib/cloud/diff.js +0 -138
- package/dist/lib/cloud/engine-bridge.d.ts +0 -34
- package/dist/lib/cloud/engine-bridge.js +0 -139
- package/dist/lib/cloud/hash-cache.d.ts +0 -23
- package/dist/lib/cloud/hash-cache.js +0 -44
- package/dist/lib/cloud/hash.d.ts +0 -10
- package/dist/lib/cloud/hash.js +0 -111
- package/dist/lib/cloud/http.d.ts +0 -17
- package/dist/lib/cloud/http.js +0 -47
- package/dist/lib/cloud/lock-path.d.ts +0 -1
- package/dist/lib/cloud/lock-path.js +0 -5
- package/dist/lib/cloud/lock.d.ts +0 -14
- package/dist/lib/cloud/lock.js +0 -143
- package/dist/lib/cloud/manifest.d.ts +0 -6
- package/dist/lib/cloud/manifest.js +0 -41
- package/dist/lib/cloud/paths.d.ts +0 -20
- package/dist/lib/cloud/paths.js +0 -90
- package/dist/lib/cloud/project-godot-merge.d.ts +0 -32
- package/dist/lib/cloud/project-godot-merge.js +0 -185
- package/dist/lib/cloud/rules.d.ts +0 -39
- package/dist/lib/cloud/rules.js +0 -159
- package/dist/lib/cloud/sync.d.ts +0 -21
- package/dist/lib/cloud/sync.js +0 -518
- package/dist/lib/cloud/transfer.d.ts +0 -23
- package/dist/lib/cloud/transfer.js +0 -184
- package/dist/lib/cloud/types.d.ts +0 -62
- package/dist/lib/cloud/types.js +0 -1
- package/dist/lib/cloud/validate-path.d.ts +0 -23
- package/dist/lib/cloud/validate-path.js +0 -103
- package/dist/lib/engine.d.ts +0 -51
- package/dist/lib/game-task-plan.d.ts +0 -42
- package/dist/lib/project-memory.d.ts +0 -33
- package/dist/lib/public-surface-paths.d.ts +0 -13
- package/dist/lib/public-surface-paths.js +0 -42
- package/dist/lib/remote-templates.d.ts +0 -25
- package/dist/lib/remote-templates.js +0 -86
- package/dist/lib/skills-registry.d.ts +0 -572
- package/dist/lib/skills-registry.js +0 -1061
- package/dist/lib/version-check.d.ts +0 -106
- package/dist/mcp/tools/cloud-tools.js +0 -42
- package/references/mcp-tools-reference.md +0 -199
- package/references/template-registry.md +0 -73
- package/skills/README.md +0 -103
- package/skills/scene-and-project/summer-cloud/SKILL.md +0 -92
- package/skills/workflow/brainstorming/scripts/frame-template.html +0 -214
- package/skills/workflow/brainstorming/scripts/helper.js +0 -88
- package/skills/workflow/brainstorming/scripts/server.cjs +0 -354
- package/skills/workflow/brainstorming/scripts/start-server.sh +0 -148
- package/skills/workflow/brainstorming/scripts/stop-server.sh +0 -56
- package/skills/workflow/brainstorming/visual-companion.md +0 -287
- package/skills/workflow/gameskill/SKILL.md +0 -120
- package/skills/workflow/investigating-bugs/CREATION-LOG.md +0 -119
- package/skills/workflow/investigating-bugs/condition-based-waiting-example.ts +0 -158
- package/skills/workflow/investigating-bugs/find-polluter.sh +0 -63
- package/skills/workflow/investigating-bugs/test-academic.md +0 -14
- package/skills/workflow/investigating-bugs/test-pressure-1.md +0 -58
- package/skills/workflow/investigating-bugs/test-pressure-2.md +0 -68
- package/skills/workflow/investigating-bugs/test-pressure-3.md +0 -69
- package/skills/workflow/mcpupdate/SKILL.md +0 -134
- package/skills/workflow/skill-create/SKILL.md +0 -153
- package/skills/workflow/writing-skills/anthropic-best-practices.md +0 -1150
- package/skills/workflow/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
- package/skills/workflow/writing-skills/graphviz-conventions.dot +0 -172
- package/skills/workflow/writing-skills/persuasion-principles.md +0 -187
- package/skills/workflow/writing-skills/render-graphs.js +0 -168
- /package/dist/{commands → cli/commands}/config.d.ts +0 -0
- /package/dist/{commands → cli/commands}/debug.d.ts +0 -0
- /package/dist/{commands → cli/commands}/list.d.ts +0 -0
- /package/dist/{commands → cli/commands}/login.d.ts +0 -0
- /package/dist/{commands → cli/commands}/plan.d.ts +0 -0
- /package/dist/{commands → cli/commands}/publish.d.ts +0 -0
- /package/dist/{commands → cli/commands}/releases.d.ts +0 -0
- /package/dist/{commands → cli/commands}/setup.d.ts +0 -0
- /package/dist/{commands → cli/commands}/skills.d.ts +0 -0
- /package/dist/{lib → core}/log-filters.d.ts +0 -0
- /package/dist/{lib → core}/mcp-log.d.ts +0 -0
- /package/dist/{lib → core}/store.d.ts +0 -0
- /package/dist/{lib → core}/summer-compatibility.d.ts +0 -0
- /package/dist/{lib → core}/telemetry.d.ts +0 -0
- /package/dist/{lib/mcp-boot-notice.js → mcp/boot-notice.js} +0 -0
- /package/dist/{commands/mcp.d.ts → mcp/command.d.ts} +0 -0
- /package/{references → library/references/collaborative-protocol}/collaborative-protocol.md +0 -0
- /package/{references → library/references/gd-style}/gd-style.md +0 -0
- /package/{skills/audio → library/skills}/ambient-bed/SKILL.md +0 -0
- /package/{skills/gameplay-mechanics → library/skills}/auto-fire-targeting/SKILL.md +0 -0
- /package/{skills/scripting-patterns → library/skills}/gdscript-patterns/SKILL.md +0 -0
- /package/{skills/scripting-patterns → library/skills}/gdscript-patterns/reference.md +0 -0
- /package/{skills/workflow → library/skills}/investigating-bugs/defense-in-depth.md +0 -0
- /package/{skills/audio → library/skills}/music-track/SKILL.md +0 -0
- /package/{skills/scene-and-project → library/skills}/play/SKILL.md +0 -0
- /package/{skills/visual-effects → library/skills/vfx-dissolve}/_building-blocks/noise-3d-fbm.gdshaderinc +0 -0
- /package/{skills/visual-effects → library/skills/vfx-fire}/_building-blocks/additive-billboard-particles.md +0 -0
- /package/{skills/visual-effects → library/skills/vfx-lightning}/_building-blocks/trauma-shake-snippet.md +0 -0
- /package/{skills/audio → library/skills}/voice-line/SKILL.md +0 -0
- /package/{skills/workflow → library/skills}/writing-plans/plan-document-reviewer-prompt.md +0 -0
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `summer open` / `summer_open` — one behavior, two faces (CONTRACT §3).
|
|
3
|
+
*
|
|
4
|
+
* Resolve a target (id, intent phrase, res:// path or summerengine.com path)
|
|
5
|
+
* against the product map (./targets.ts), then either open it — the browser
|
|
6
|
+
* for web targets (through /login?returnUrl= when login is required and the
|
|
7
|
+
* CLI is not logged in), the running Summer Engine via the local API for
|
|
8
|
+
* editor targets — or, with `open: false`, return what would open without
|
|
9
|
+
* opening.
|
|
10
|
+
*
|
|
11
|
+
* Editor targets are FORWARDED, not implemented here: when the engine
|
|
12
|
+
* advertises `capabilities.navigation` the tool sends the one-table op
|
|
13
|
+
* `Navigate { target, ...args }`; on an engine that predates it the few ids the
|
|
14
|
+
* original ops can serve (scene, node, script, file, the three docks) use those
|
|
15
|
+
* ops and everything else answers `engine_lacks_op`. See NAVIGATION-PLAN.md.
|
|
16
|
+
*
|
|
17
|
+
* Both faces call runOpen(); the CLI (tool-dispatch + `summer open`) and the
|
|
18
|
+
* MCP tool (src/mcp/tools/navigation-tools.ts) only differ in how the engine
|
|
19
|
+
* client and the browser launcher are supplied.
|
|
20
|
+
*/
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
import { extractOpError } from "../engine-receipt.js";
|
|
23
|
+
import { NAV_TARGETS, WEB_CATALOG, getNavTarget, } from "./targets.js";
|
|
24
|
+
/** The ONE argument shape both faces validate with (mirrors
|
|
25
|
+
* library/tools/open/resource.yaml input_schema; parity-tested). */
|
|
26
|
+
export const openArgsShape = {
|
|
27
|
+
target: z
|
|
28
|
+
.string()
|
|
29
|
+
.optional()
|
|
30
|
+
.describe('Where to go: a target id (billing, my-games, mcp-guide, scene, node, inspector, …), an intent phrase ("change my plan"), a res:// path, or a summerengine.com path ("/pricing"). Omit to list every target.'),
|
|
31
|
+
params: z
|
|
32
|
+
.record(z.string())
|
|
33
|
+
.optional()
|
|
34
|
+
.describe("Slot values for the target: gameId, section, username, version, guide (agent name or guide slug), path (res://…), node, scene, line, col, tab."),
|
|
35
|
+
surface: z
|
|
36
|
+
.enum(["auto", "web", "editor"])
|
|
37
|
+
.optional()
|
|
38
|
+
.describe('Restrict matching to the website or the editor. "auto" (default) considers both.'),
|
|
39
|
+
open: z
|
|
40
|
+
.boolean()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe("Default true: open it. false = resolve only — return the URL or engine op and open nothing (works without the engine and without a browser). The CLI's --print."),
|
|
43
|
+
};
|
|
44
|
+
export const openArgsSchema = z.object(openArgsShape).strict();
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Safety rails
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
/** The only origins this tool ever opens a browser on: summerengine.com and its
|
|
49
|
+
* subdomains, plus loopback for local web development. A configured gateway
|
|
50
|
+
* (SUMMER_GATEWAY_URL / gateway.url) that points anywhere else is refused —
|
|
51
|
+
* the API calls may go there, a browser launch never does. */
|
|
52
|
+
export function isAllowedNavigationOrigin(origin) {
|
|
53
|
+
let host;
|
|
54
|
+
try {
|
|
55
|
+
host = new URL(origin).hostname.toLowerCase();
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return (host === "summerengine.com" ||
|
|
61
|
+
host.endsWith(".summerengine.com") ||
|
|
62
|
+
host === "localhost" ||
|
|
63
|
+
host === "127.0.0.1" ||
|
|
64
|
+
host === "[::1]" ||
|
|
65
|
+
host === "::1");
|
|
66
|
+
}
|
|
67
|
+
/** A project resource path the engine may be asked to open: `res://` plus a
|
|
68
|
+
* plain relative path — no parent segments, no backslashes, no percent
|
|
69
|
+
* escapes, nothing that could name a file outside the project. Returns the
|
|
70
|
+
* problem, or null when the path is acceptable. */
|
|
71
|
+
export function resPathProblem(value) {
|
|
72
|
+
if (!value.startsWith("res://"))
|
|
73
|
+
return `must start with res:// (got "${value}")`;
|
|
74
|
+
const rest = value.slice("res://".length);
|
|
75
|
+
if (rest.length === 0)
|
|
76
|
+
return "must name a file or folder under res://";
|
|
77
|
+
if (rest.includes("\\"))
|
|
78
|
+
return "must use forward slashes";
|
|
79
|
+
if (rest.includes("%"))
|
|
80
|
+
return "must not contain percent escapes";
|
|
81
|
+
if (rest.startsWith("/"))
|
|
82
|
+
return "must be relative to res:// (no leading slash)";
|
|
83
|
+
if (rest.split("/").some((segment) => segment === ".." || segment === "."))
|
|
84
|
+
return "must not contain . or .. segments";
|
|
85
|
+
if (/[\u0000-\u001f]/.test(rest))
|
|
86
|
+
return "must not contain control characters";
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
/** Launch the browser; a failed launch is a result, not a crash. */
|
|
90
|
+
async function launch(deps, url) {
|
|
91
|
+
try {
|
|
92
|
+
await deps.openUrl(url);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
return error instanceof Error ? error.message : String(error);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function openFailed(url, error, extra = {}) {
|
|
100
|
+
return {
|
|
101
|
+
ok: false,
|
|
102
|
+
action: "open_failed",
|
|
103
|
+
url,
|
|
104
|
+
...extra,
|
|
105
|
+
hint: `Could not launch a browser on this machine (${error}). Nothing opened — hand the user the url instead.`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
// Matching
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
const STOPWORDS = new Set([
|
|
112
|
+
"the", "a", "an", "my", "me", "i", "to", "of", "in", "on", "for", "please", "open", "show",
|
|
113
|
+
"go", "page", "want", "up", "take", "it", "is", "do", "how", "can", "you", "where", "with",
|
|
114
|
+
"and", "that", "this", "at", "into", "see", "let", "get", "bring", "our", "your", "im", "am",
|
|
115
|
+
]);
|
|
116
|
+
export function tokenize(text) {
|
|
117
|
+
return text
|
|
118
|
+
.toLowerCase()
|
|
119
|
+
.replace(/[’']/g, "")
|
|
120
|
+
.split(/[^a-z0-9]+/)
|
|
121
|
+
.filter((tok) => tok.length > 0 && !STOPWORDS.has(tok))
|
|
122
|
+
.map((tok) => (tok.length > 3 && tok.endsWith("s") ? tok.slice(0, -1) : tok));
|
|
123
|
+
}
|
|
124
|
+
function phraseScore(queryTokens, phrase) {
|
|
125
|
+
const phraseTokens = tokenize(phrase);
|
|
126
|
+
if (queryTokens.length === 0 || phraseTokens.length === 0)
|
|
127
|
+
return 0;
|
|
128
|
+
if (queryTokens.join(" ") === phraseTokens.join(" "))
|
|
129
|
+
return 1;
|
|
130
|
+
const phraseSet = new Set(phraseTokens);
|
|
131
|
+
const overlap = queryTokens.filter((tok) => phraseSet.has(tok)).length;
|
|
132
|
+
if (overlap === 0)
|
|
133
|
+
return 0;
|
|
134
|
+
const coverage = overlap / queryTokens.length;
|
|
135
|
+
const precision = overlap / phraseTokens.length;
|
|
136
|
+
return coverage * (0.7 + 0.3 * precision);
|
|
137
|
+
}
|
|
138
|
+
function scoreTarget(queryTokens, target) {
|
|
139
|
+
let best = 0;
|
|
140
|
+
for (const phrase of [target.id.replace(/-/g, " "), target.title, ...target.intents, ...(target.aliases ?? [])]) {
|
|
141
|
+
best = Math.max(best, phraseScore(queryTokens, phrase));
|
|
142
|
+
if (best === 1)
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
return best;
|
|
146
|
+
}
|
|
147
|
+
const MIN_SCORE = 0.5;
|
|
148
|
+
/** Rank every target for a free-text query. Exported for tests. */
|
|
149
|
+
export function rankTargets(query, surface = "auto") {
|
|
150
|
+
const queryTokens = tokenize(query);
|
|
151
|
+
const candidates = NAV_TARGETS.filter((target) => surface === "auto" || target.surface === surface);
|
|
152
|
+
return candidates
|
|
153
|
+
.map((target) => ({
|
|
154
|
+
id: target.id,
|
|
155
|
+
surface: target.surface,
|
|
156
|
+
title: target.title,
|
|
157
|
+
score: round(scoreTarget(queryTokens, target)),
|
|
158
|
+
}))
|
|
159
|
+
.filter((match) => match.score >= MIN_SCORE)
|
|
160
|
+
.sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));
|
|
161
|
+
}
|
|
162
|
+
function round(value) {
|
|
163
|
+
return Math.round(value * 1000) / 1000;
|
|
164
|
+
}
|
|
165
|
+
function resolveResourcePath(path, params) {
|
|
166
|
+
const problem = resPathProblem(path);
|
|
167
|
+
if (problem) {
|
|
168
|
+
return { kind: "not_found", matches: [], hint: `Refused resource path: ${problem}.` };
|
|
169
|
+
}
|
|
170
|
+
const lower = path.toLowerCase();
|
|
171
|
+
const id = lower.endsWith(".tscn") || lower.endsWith(".scn") ? "scene" : lower.endsWith(".gd") || lower.endsWith(".cs") ? "script" : "file";
|
|
172
|
+
return { kind: "target", target: getNavTarget(id), params: { ...params, path } };
|
|
173
|
+
}
|
|
174
|
+
/** Redirect-style query params on an unmapped path must be relative same-origin
|
|
175
|
+
* paths; a full URL there would turn the login page into an open redirect. */
|
|
176
|
+
const REDIRECT_PARAMS = new Set(["returnurl", "redirect", "next", "callbackurl", "redirect_uri", "return_to"]);
|
|
177
|
+
export function unsafeRedirectParam(pathWithQuery) {
|
|
178
|
+
const q = pathWithQuery.indexOf("?");
|
|
179
|
+
if (q === -1)
|
|
180
|
+
return null;
|
|
181
|
+
for (const [key, value] of new URLSearchParams(pathWithQuery.slice(q + 1))) {
|
|
182
|
+
if (!REDIRECT_PARAMS.has(key.toLowerCase()))
|
|
183
|
+
continue;
|
|
184
|
+
if (!value.startsWith("/") || value.startsWith("//") || value.startsWith("/\\"))
|
|
185
|
+
return key;
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
function resolveWebPath(path, params) {
|
|
190
|
+
const badParam = unsafeRedirectParam(path);
|
|
191
|
+
if (badParam) {
|
|
192
|
+
return { kind: "not_found", matches: [], hint: `Refused: query parameter "${badParam}" must be a relative summerengine.com path (it is used as a redirect target).` };
|
|
193
|
+
}
|
|
194
|
+
const wanted = path.replace(/\/+$/, "") || "/";
|
|
195
|
+
for (const target of NAV_TARGETS) {
|
|
196
|
+
if (!target.web || target.web.origin !== "gateway")
|
|
197
|
+
continue;
|
|
198
|
+
const literal = target.web.path.replace(/\[\/\{[a-zA-Z]+\}\]/g, "");
|
|
199
|
+
if (literal.includes("{"))
|
|
200
|
+
continue;
|
|
201
|
+
if (literal.replace(/\/+$/, "") === wanted || literal === wanted) {
|
|
202
|
+
return { kind: "target", target, params };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return { kind: "url", url: path };
|
|
206
|
+
}
|
|
207
|
+
export function resolveTarget(rawTarget, params, surface) {
|
|
208
|
+
const raw = rawTarget.trim();
|
|
209
|
+
if (raw.startsWith("res://"))
|
|
210
|
+
return resolveResourcePath(raw, params);
|
|
211
|
+
if (raw.startsWith("/") && !raw.startsWith("//"))
|
|
212
|
+
return resolveWebPath(raw, params);
|
|
213
|
+
const direct = getNavTarget(raw.toLowerCase().replace(/\s+/g, "-"));
|
|
214
|
+
if (direct && (surface === "auto" || direct.surface === surface)) {
|
|
215
|
+
return { kind: "target", target: direct, params };
|
|
216
|
+
}
|
|
217
|
+
const matches = rankTargets(raw, surface);
|
|
218
|
+
if (matches.length === 0) {
|
|
219
|
+
return {
|
|
220
|
+
kind: "not_found",
|
|
221
|
+
matches,
|
|
222
|
+
hint: `No destination matches "${raw.length > 80 ? raw.slice(0, 77) + "..." : raw}". Run 'summer open --list' (or call summer_open with no target) to see every target, or pass a res:// path or a summerengine.com path.`,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
const [top, second] = matches;
|
|
226
|
+
const clear = top.score >= 0.999
|
|
227
|
+
? !second || second.score < 0.999
|
|
228
|
+
: top.score >= 0.6 && (!second || top.score - second.score >= 0.25);
|
|
229
|
+
if (clear)
|
|
230
|
+
return { kind: "target", target: getNavTarget(top.id), params };
|
|
231
|
+
return { kind: "ambiguous", matches: matches.slice(0, 5) };
|
|
232
|
+
}
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
// Rendering
|
|
235
|
+
// ---------------------------------------------------------------------------
|
|
236
|
+
function summarize(target, availability) {
|
|
237
|
+
return {
|
|
238
|
+
id: target.id,
|
|
239
|
+
surface: target.surface,
|
|
240
|
+
title: target.title,
|
|
241
|
+
description: target.description,
|
|
242
|
+
requires: target.requires,
|
|
243
|
+
...(target.params ? { params: target.params } : {}),
|
|
244
|
+
...(availability ? { availability } : {}),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
class ParamError extends Error {
|
|
248
|
+
}
|
|
249
|
+
function normalizeParam(param, value) {
|
|
250
|
+
const clean = value.trim();
|
|
251
|
+
if (!param.values)
|
|
252
|
+
return clean;
|
|
253
|
+
const lower = clean.toLowerCase();
|
|
254
|
+
if (param.values.includes(lower))
|
|
255
|
+
return lower;
|
|
256
|
+
const alias = param.valueAliases?.[lower];
|
|
257
|
+
if (alias)
|
|
258
|
+
return alias;
|
|
259
|
+
throw new ParamError(`${param.name} must be one of: ${param.values.join(", ")}` +
|
|
260
|
+
(param.valueAliases ? ` (or an alias: ${Object.keys(param.valueAliases).join(", ")})` : ""));
|
|
261
|
+
}
|
|
262
|
+
/** Fill a web path template. `{slot}` required, `[/{slot}]` optional. */
|
|
263
|
+
export function renderWebPath(template, params, declared = []) {
|
|
264
|
+
const byName = new Map(declared.map((param) => [param.name, param]));
|
|
265
|
+
const lookup = (name) => {
|
|
266
|
+
const value = params[name];
|
|
267
|
+
if (value === undefined || value === "")
|
|
268
|
+
return undefined;
|
|
269
|
+
const param = byName.get(name);
|
|
270
|
+
return param ? normalizeParam(param, value) : value.trim();
|
|
271
|
+
};
|
|
272
|
+
let out = template.replace(/\[\/\{([a-zA-Z]+)\}\]/g, (_m, name) => {
|
|
273
|
+
const value = lookup(name);
|
|
274
|
+
return value === undefined ? "" : `/${encodeURIComponent(value)}`;
|
|
275
|
+
});
|
|
276
|
+
out = out.replace(/\{([a-zA-Z]+)\}/g, (_m, name) => {
|
|
277
|
+
const value = lookup(name);
|
|
278
|
+
if (value === undefined)
|
|
279
|
+
throw new ParamError(`Missing required param: ${name}`);
|
|
280
|
+
return encodeURIComponent(value);
|
|
281
|
+
});
|
|
282
|
+
return out;
|
|
283
|
+
}
|
|
284
|
+
function requireParams(meta, params) {
|
|
285
|
+
for (const param of meta.params ?? []) {
|
|
286
|
+
const value = params[param.name];
|
|
287
|
+
if (param.required && (value === undefined || value === "")) {
|
|
288
|
+
throw new ParamError(`Missing required param: ${param.name}`);
|
|
289
|
+
}
|
|
290
|
+
// Resource paths are forwarded to the engine as-is; refuse anything that
|
|
291
|
+
// does not name a file under the project.
|
|
292
|
+
if ((param.name === "path" || param.name === "scene") && meta.id !== "assistant" && value !== undefined && value !== "") {
|
|
293
|
+
const problem = resPathProblem(value);
|
|
294
|
+
if (problem)
|
|
295
|
+
throw new ParamError(`${param.name} ${problem}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/** Numeric args (line, col) travel as numbers; everything else as trimmed strings. */
|
|
300
|
+
function argValue(name, value) {
|
|
301
|
+
const trimmed = value.trim();
|
|
302
|
+
return (name === "line" || name === "col") && /^\d+$/.test(trimmed) ? Number.parseInt(trimmed, 10) : trimmed;
|
|
303
|
+
}
|
|
304
|
+
/** The one-table op: Navigate { target, ...args }. */
|
|
305
|
+
export function buildNavigateOp(meta, params) {
|
|
306
|
+
const op = { op: "Navigate", target: meta.navigate.target, ...(meta.navigate.fixed ?? {}) };
|
|
307
|
+
for (const [paramName, argName] of Object.entries(meta.navigate.map ?? {})) {
|
|
308
|
+
const value = params[paramName];
|
|
309
|
+
if (value !== undefined && value !== "")
|
|
310
|
+
op[argName] = argValue(argName, value);
|
|
311
|
+
}
|
|
312
|
+
return op;
|
|
313
|
+
}
|
|
314
|
+
/** The pre-Navigate op for engines that predate the table (only some rows have one). */
|
|
315
|
+
export function buildLegacyOp(meta, params) {
|
|
316
|
+
if (!meta.legacy)
|
|
317
|
+
return null;
|
|
318
|
+
const op = { op: meta.legacy.op, ...(meta.legacy.fixed ?? {}) };
|
|
319
|
+
for (const [paramName, field] of Object.entries(meta.legacy.map ?? {})) {
|
|
320
|
+
const value = params[paramName];
|
|
321
|
+
if (value !== undefined && value !== "")
|
|
322
|
+
op[field] = value.trim();
|
|
323
|
+
}
|
|
324
|
+
return op;
|
|
325
|
+
}
|
|
326
|
+
function mainSceneFrom(projectState) {
|
|
327
|
+
const root = (projectState ?? {});
|
|
328
|
+
const data = (root.data ?? root);
|
|
329
|
+
const entries = data.entries;
|
|
330
|
+
if (Array.isArray(entries)) {
|
|
331
|
+
for (const entry of entries) {
|
|
332
|
+
const item = (entry ?? {});
|
|
333
|
+
if (item.key === "application/run/main_scene" || item.key === "run/main_scene") {
|
|
334
|
+
return typeof item.value === "string" && item.value.length > 0 ? item.value : null;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
for (const key of ["mainScene", "main_scene", "mainScenePath", "main_scene_path"]) {
|
|
339
|
+
const value = data[key] ?? root[key];
|
|
340
|
+
if (typeof value === "string" && value.length > 0)
|
|
341
|
+
return value;
|
|
342
|
+
}
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
/** Which ids the connected engine can open. undefined = engine predates the advert. */
|
|
346
|
+
export function advertisedNavigation(client) {
|
|
347
|
+
const targets = client.getEngineCapabilities?.()?.navigation?.targets;
|
|
348
|
+
return targets ? new Set(targets.map((t) => t.id)) : undefined;
|
|
349
|
+
}
|
|
350
|
+
export function editorAvailability(meta, advertised) {
|
|
351
|
+
if (advertised)
|
|
352
|
+
return advertised.has(meta.navigate.target) ? "available" : "unavailable";
|
|
353
|
+
return meta.legacy ? "legacy" : "unavailable";
|
|
354
|
+
}
|
|
355
|
+
export function listTargets(surface = "auto", advertised) {
|
|
356
|
+
return NAV_TARGETS.filter((target) => surface === "auto" || target.surface === surface).map((target) => target.editor
|
|
357
|
+
? summarize(target, advertised === "unknown" ? "unknown" : editorAvailability(target.editor, advertised))
|
|
358
|
+
: summarize(target));
|
|
359
|
+
}
|
|
360
|
+
// ---------------------------------------------------------------------------
|
|
361
|
+
// The behavior
|
|
362
|
+
// ---------------------------------------------------------------------------
|
|
363
|
+
export async function runOpen(args, deps) {
|
|
364
|
+
const surface = args.surface ?? "auto";
|
|
365
|
+
const params = args.params ?? {};
|
|
366
|
+
const print = args.open === false;
|
|
367
|
+
const docsOrigin = deps.docsOrigin ?? WEB_CATALOG.docsBase;
|
|
368
|
+
if (!args.target || args.target.trim() === "") {
|
|
369
|
+
let advertised = "unknown";
|
|
370
|
+
if (surface !== "web") {
|
|
371
|
+
try {
|
|
372
|
+
advertised = advertisedNavigation(await deps.engine());
|
|
373
|
+
}
|
|
374
|
+
catch {
|
|
375
|
+
advertised = "unknown";
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return {
|
|
379
|
+
ok: true,
|
|
380
|
+
action: "listed",
|
|
381
|
+
targets: listTargets(surface, advertised),
|
|
382
|
+
hint: "Pass a target id, an intent phrase, a res:// path, or a summerengine.com path. Editor availability comes from the connected engine: available = Navigate op; legacy = served by an older op; unavailable = update Summer Engine; unknown = engine not running.",
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
const gateway = (await deps.gatewayUrl()).replace(/\/+$/, "");
|
|
386
|
+
if (!isAllowedNavigationOrigin(gateway) || !isAllowedNavigationOrigin(docsOrigin)) {
|
|
387
|
+
return {
|
|
388
|
+
ok: false,
|
|
389
|
+
action: "blocked_origin",
|
|
390
|
+
hint: `Refusing to open a browser on ${isAllowedNavigationOrigin(gateway) ? docsOrigin : gateway}: summer_open only opens summerengine.com, its subdomains, and loopback. Check gateway.url / SUMMER_GATEWAY_URL.`,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
// A full URL is accepted only on the two origins this tool ever opens; the
|
|
394
|
+
// path is then resolved like a summerengine.com path.
|
|
395
|
+
let rawTarget = args.target.trim();
|
|
396
|
+
if (/^https?:\/\//i.test(rawTarget)) {
|
|
397
|
+
let parsed;
|
|
398
|
+
try {
|
|
399
|
+
parsed = new URL(rawTarget);
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
return { ok: false, action: "not_found", hint: `"${rawTarget}" is not a valid URL.` };
|
|
403
|
+
}
|
|
404
|
+
const sameGateway = parsed.origin === gateway || parsed.origin.replace("://www.", "://") === gateway.replace("://www.", "://");
|
|
405
|
+
if (parsed.origin === docsOrigin) {
|
|
406
|
+
const url = `${docsOrigin}${parsed.pathname}${parsed.search}`;
|
|
407
|
+
if (print)
|
|
408
|
+
return { ok: true, action: "printed", url, unmapped: true };
|
|
409
|
+
const failure = await launch(deps, url);
|
|
410
|
+
if (failure)
|
|
411
|
+
return openFailed(url, failure, { unmapped: true });
|
|
412
|
+
return { ok: true, action: "opened", url, opened_url: url, unmapped: true };
|
|
413
|
+
}
|
|
414
|
+
if (!sameGateway) {
|
|
415
|
+
return {
|
|
416
|
+
ok: false,
|
|
417
|
+
action: "not_found",
|
|
418
|
+
hint: `summer_open only opens ${gateway} and ${docsOrigin}; "${parsed.origin}" is not a Summer destination.`,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
rawTarget = `${parsed.pathname}${parsed.search}`;
|
|
422
|
+
}
|
|
423
|
+
const resolution = resolveTarget(rawTarget, params, surface);
|
|
424
|
+
if (resolution.kind === "not_found") {
|
|
425
|
+
return { ok: false, action: "not_found", matches: resolution.matches, hint: resolution.hint };
|
|
426
|
+
}
|
|
427
|
+
if (resolution.kind === "ambiguous") {
|
|
428
|
+
return {
|
|
429
|
+
ok: false,
|
|
430
|
+
action: "ambiguous",
|
|
431
|
+
matches: resolution.matches,
|
|
432
|
+
hint: `"${args.target.length > 80 ? args.target.slice(0, 77) + "..." : args.target}" matches several destinations. Call again with one of the ids listed in matches.`,
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
if (resolution.kind === "url") {
|
|
436
|
+
const url = `${gateway}${resolution.url}`;
|
|
437
|
+
const base = {
|
|
438
|
+
ok: true,
|
|
439
|
+
action: print ? "printed" : "opened",
|
|
440
|
+
url,
|
|
441
|
+
unmapped: true,
|
|
442
|
+
hint: "This path is not in the product map; it was opened on the Summer gateway origin as given.",
|
|
443
|
+
};
|
|
444
|
+
if (print)
|
|
445
|
+
return base;
|
|
446
|
+
const failure = await launch(deps, url);
|
|
447
|
+
if (failure)
|
|
448
|
+
return openFailed(url, failure, { unmapped: true });
|
|
449
|
+
return { ...base, opened_url: url };
|
|
450
|
+
}
|
|
451
|
+
const { target } = resolution;
|
|
452
|
+
// ---- web -----------------------------------------------------------------
|
|
453
|
+
if (target.web) {
|
|
454
|
+
const summary = summarize(target);
|
|
455
|
+
let path;
|
|
456
|
+
try {
|
|
457
|
+
path = renderWebPath(target.web.path, resolution.params, target.params);
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
if (error instanceof ParamError)
|
|
461
|
+
return { ok: false, action: "invalid_params", target: summary, hint: error.message };
|
|
462
|
+
throw error;
|
|
463
|
+
}
|
|
464
|
+
const origin = target.web.origin === "docs" ? docsOrigin : gateway;
|
|
465
|
+
const url = `${origin}${path}`;
|
|
466
|
+
const needsLogin = target.requires.login === true && target.web.origin === "gateway";
|
|
467
|
+
const loggedIn = needsLogin ? await deps.isLoggedIn() : undefined;
|
|
468
|
+
const loginUrl = needsLogin
|
|
469
|
+
? `${gateway}${WEB_CATALOG.login.path}?${WEB_CATALOG.login.returnParam}=${encodeURIComponent(path)}`
|
|
470
|
+
: undefined;
|
|
471
|
+
const result = {
|
|
472
|
+
ok: true,
|
|
473
|
+
action: print ? "printed" : "opened",
|
|
474
|
+
target: summary,
|
|
475
|
+
url,
|
|
476
|
+
...(loginUrl ? { login_url: loginUrl } : {}),
|
|
477
|
+
...(loggedIn !== undefined ? { logged_in: loggedIn } : {}),
|
|
478
|
+
};
|
|
479
|
+
if (print)
|
|
480
|
+
return result;
|
|
481
|
+
const toOpen = needsLogin && loggedIn === false ? loginUrl : url;
|
|
482
|
+
const failure = await launch(deps, toOpen);
|
|
483
|
+
if (failure)
|
|
484
|
+
return openFailed(toOpen, failure, { target: summary, ...(loginUrl ? { login_url: loginUrl } : {}), ...(loggedIn !== undefined ? { logged_in: loggedIn } : {}) });
|
|
485
|
+
return {
|
|
486
|
+
...result,
|
|
487
|
+
opened_url: toOpen,
|
|
488
|
+
...(needsLogin && loggedIn === false
|
|
489
|
+
? { hint: "Not logged in on this machine, so the login page was opened with returnUrl set; the destination loads after sign-in." }
|
|
490
|
+
: {}),
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
// ---- editor: forward to the engine's table -------------------------------
|
|
494
|
+
const meta = target.editor;
|
|
495
|
+
try {
|
|
496
|
+
requireParams(meta, resolution.params);
|
|
497
|
+
}
|
|
498
|
+
catch (error) {
|
|
499
|
+
if (error instanceof ParamError)
|
|
500
|
+
return { ok: false, action: "invalid_params", target: summarize(target), hint: error.message };
|
|
501
|
+
throw error;
|
|
502
|
+
}
|
|
503
|
+
let client;
|
|
504
|
+
try {
|
|
505
|
+
client = await deps.engine();
|
|
506
|
+
}
|
|
507
|
+
catch (error) {
|
|
508
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
509
|
+
const navigateOp = buildNavigateOp(meta, resolution.params);
|
|
510
|
+
if (meta.mainSceneDefault && navigateOp.path === undefined)
|
|
511
|
+
navigateOp.path = "<application/run/main_scene>";
|
|
512
|
+
const summary = summarize(target, meta.legacy ? "legacy" : "unknown");
|
|
513
|
+
if (print) {
|
|
514
|
+
return { ok: true, action: "printed", target: summary, op: navigateOp, engine: { running: false, error: message } };
|
|
515
|
+
}
|
|
516
|
+
return {
|
|
517
|
+
ok: false,
|
|
518
|
+
action: "engine_not_running",
|
|
519
|
+
target: summary,
|
|
520
|
+
op: navigateOp,
|
|
521
|
+
engine: { running: false, error: message },
|
|
522
|
+
hint: `Summer Engine is not running (or no project is open), so nothing was opened. Start it with 'summer run <project>' or open the project in the Summer desktop app, then retry. What would open: ${target.title} — ${target.description}`,
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
const version = client.getEngineVersion?.();
|
|
526
|
+
const advertised = advertisedNavigation(client);
|
|
527
|
+
const availability = editorAvailability(meta, advertised);
|
|
528
|
+
const summary = summarize(target, availability);
|
|
529
|
+
const engine = { running: true, version, navigation: advertised !== undefined };
|
|
530
|
+
if (availability === "unavailable") {
|
|
531
|
+
const navigateOp = buildNavigateOp(meta, resolution.params);
|
|
532
|
+
return {
|
|
533
|
+
ok: false,
|
|
534
|
+
action: "unsupported",
|
|
535
|
+
target: summary,
|
|
536
|
+
op: navigateOp,
|
|
537
|
+
engine,
|
|
538
|
+
failure_reason: "engine_lacks_op",
|
|
539
|
+
hint: advertised
|
|
540
|
+
? `This Summer Engine build (${version ?? "unknown version"}) has the Navigate op but does not advertise the "${meta.navigate.target}" destination. Update Summer Engine; until then tell the user what to open by hand: ${target.title}.`
|
|
541
|
+
: `This Summer Engine build (${version ?? "unknown version"}) predates the Navigate op, and "${target.id}" has no legacy equivalent. Update Summer Engine (restart it after updating); until then tell the user what to open by hand: ${target.title}.`,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
const op = availability === "legacy" ? buildLegacyOp(meta, resolution.params) : buildNavigateOp(meta, resolution.params);
|
|
545
|
+
if (meta.mainSceneDefault && op.path === undefined) {
|
|
546
|
+
const mainScene = mainSceneFrom(await client.getProjectState("application/"));
|
|
547
|
+
if (!mainScene) {
|
|
548
|
+
return {
|
|
549
|
+
ok: false,
|
|
550
|
+
action: "engine_error",
|
|
551
|
+
target: summary,
|
|
552
|
+
op,
|
|
553
|
+
engine,
|
|
554
|
+
hint: "The project has no application/run/main_scene configured. Pass params.path with an explicit res://…tscn.",
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
op.path = mainScene;
|
|
558
|
+
}
|
|
559
|
+
if (print)
|
|
560
|
+
return { ok: true, action: "printed", target: summary, op, engine };
|
|
561
|
+
const receipt = await client.executeOps([op]);
|
|
562
|
+
const failure = extractOpError(receipt);
|
|
563
|
+
if (failure) {
|
|
564
|
+
return { ok: false, action: "engine_error", target: summary, op, engine, receipt, hint: failure };
|
|
565
|
+
}
|
|
566
|
+
return { ok: true, action: "opened", target: summary, op, engine, receipt };
|
|
567
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function renderProductMap(): string;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders library/references/product-map/product-map.md from the same data
|
|
3
|
+
* `summer_open` uses (targets.ts): the web rows from the vendored
|
|
4
|
+
* /agent-routes.json snapshot, the editor rows from the engine-id metadata.
|
|
5
|
+
* `node scripts/navigation/render-product-map.ts` writes it; navigation.test.ts
|
|
6
|
+
* fails when the committed file differs from this render.
|
|
7
|
+
*/
|
|
8
|
+
import { EDITOR_TARGETS, WEB_CATALOG } from "./targets.js";
|
|
9
|
+
function esc(text) {
|
|
10
|
+
return text.replace(/\|/g, "\\|");
|
|
11
|
+
}
|
|
12
|
+
function intents(list) {
|
|
13
|
+
return esc(list.slice(0, 4).map((i) => `"${i}"`).join(", "));
|
|
14
|
+
}
|
|
15
|
+
function params(list) {
|
|
16
|
+
if (!list || list.length === 0)
|
|
17
|
+
return "—";
|
|
18
|
+
return list.map((p) => `\`${p.name}\`${p.required ? " (required)" : ""}`).join(", ");
|
|
19
|
+
}
|
|
20
|
+
function idCell(id, aliases) {
|
|
21
|
+
return `\`${id}\`${aliases && aliases.length ? ` (${aliases.map((a) => `\`${a}\``).join(", ")})` : ""}`;
|
|
22
|
+
}
|
|
23
|
+
function webRow(route) {
|
|
24
|
+
// The apex host is what the capability lint allows; the tool itself uses the
|
|
25
|
+
// configured gateway (www. in production).
|
|
26
|
+
const origin = route.origin === "docs" ? WEB_CATALOG.docsBase : "https://summerengine.com";
|
|
27
|
+
return `| ${idCell(route.id, route.aliases)} | web | ${intents(route.intents)} | \`${esc(origin + route.path)}\` | ${params(route.params)} | ${route.auth === "signed-in" ? "login" : "—"} | ${esc(route.description)} |`;
|
|
28
|
+
}
|
|
29
|
+
function editorRow(meta) {
|
|
30
|
+
const nav = meta.navigate;
|
|
31
|
+
const navArgs = [
|
|
32
|
+
...Object.entries(nav.fixed ?? {}).map(([k, v]) => `${k}=${v}`),
|
|
33
|
+
...Object.entries(nav.map ?? {}).map(([p, a]) => `${a}=<${p}>`),
|
|
34
|
+
];
|
|
35
|
+
const where = `Navigate target=${nav.target}${navArgs.length ? " " + navArgs.join(" ") : ""}${meta.mainSceneDefault ? " (path defaults to the main scene)" : ""}`;
|
|
36
|
+
const legacy = meta.legacy
|
|
37
|
+
? `\`${meta.legacy.op}\`${meta.legacy.fixed ? " " + JSON.stringify(meta.legacy.fixed) : ""}`
|
|
38
|
+
: "— (needs an engine with the Navigate op)";
|
|
39
|
+
return `| ${idCell(meta.id, meta.aliases)} | editor | ${intents(meta.intents)} | \`${esc(where)}\` | ${params(meta.params)} | ${legacy} | ${esc(meta.description)} |`;
|
|
40
|
+
}
|
|
41
|
+
export function renderProductMap() {
|
|
42
|
+
const lines = [];
|
|
43
|
+
lines.push("# Summer product map");
|
|
44
|
+
lines.push("");
|
|
45
|
+
lines.push("> Every place an agent can send the user: pages on summerengine.com and docs.summerengine.com, and surfaces inside the Summer Engine editor. One table, two surfaces. Open any row with `summer_open` (MCP) or `summer open <id>` (CLI); the `navigate-summer` skill says when to open a surface for the user and when to act through the API instead.");
|
|
46
|
+
lines.push("");
|
|
47
|
+
lines.push("**Generated file.** Rendered from the tool's own data by `node scripts/navigation/render-product-map.ts`; a test fails when this file and the data disagree. Do not edit by hand.");
|
|
48
|
+
lines.push("");
|
|
49
|
+
lines.push("## Who owns what");
|
|
50
|
+
lines.push("");
|
|
51
|
+
lines.push("- **Web rows** come from summerengine.com's own route catalog (`/agent-routes.json`, published from the web repo's `src/lib/navigation/routes.ts`). The toolkit vendors a snapshot (`assets/navigation/web-routes.json`, refreshed with `npm run sync:web-routes`); it does not invent pages.");
|
|
52
|
+
lines.push("- **Editor rows** are ids of Summer Engine's one navigation table (`navigate_ops.cpp`, op `Navigate`). The running engine advertises which ids it can open in `/api/health` `capabilities.navigation`; `summer open --list` shows availability from the connected engine. Engines that predate the `Navigate` op can still serve the rows with a legacy op (last-but-one column); every other row answers `engine_lacks_op` with an update hint.");
|
|
53
|
+
lines.push("");
|
|
54
|
+
lines.push("## How to read a row");
|
|
55
|
+
lines.push("");
|
|
56
|
+
lines.push("- **id** — what you pass as `target`. Aliases in parentheses also resolve. Intent phrases in the third column resolve too (`summer open \"change my plan\"`).");
|
|
57
|
+
lines.push(`- **where** — the URL (web) or the engine op (editor). \`{slot}\` is a required param; \`[/{slot}]\` is optional. Web URLs are shown on the apex host; the tool uses the configured gateway (\`gateway.url\` / \`SUMMER_GATEWAY_URL\`), so a staging gateway opens staging.`);
|
|
58
|
+
lines.push("- **params** — slot values passed as `params: { … }`. `guide` accepts an agent name (`cursor`, `claude-code`, `codex`, `gemini`, …) or a guide slug; `section` is one of the game's Studio sections; `line`/`col` are for `script`.");
|
|
59
|
+
lines.push(`- **login** — the page needs a Summer account; when this machine has no CLI login token the tool opens \`${WEB_CATALOG.login.path}?${WEB_CATALOG.login.returnParam}=<path>\` and the destination loads after sign-in. Editor rows need Summer Engine running with the project open; otherwise the tool reports \`engine_not_running\` and nothing opens.`);
|
|
60
|
+
lines.push("");
|
|
61
|
+
lines.push("Things that do not exist and are therefore not in the map (verified against the web app, 2026-09-03): a public play URL for a published game (`/games` is a curated gallery; distribution runs through a game's Builds / Releases / Store page in Studio, so \"my published games\" is `my-games`), and an API-token or MCP-credential page (CLI login is a device-code flow started by `summer login`).");
|
|
62
|
+
lines.push("");
|
|
63
|
+
lines.push("## Web");
|
|
64
|
+
lines.push("");
|
|
65
|
+
lines.push("| id | surface | intents (excerpt) | where | params | login | what the user sees |");
|
|
66
|
+
lines.push("|---|---|---|---|---|---|---|");
|
|
67
|
+
for (const route of WEB_CATALOG.routes)
|
|
68
|
+
lines.push(webRow(route));
|
|
69
|
+
lines.push("");
|
|
70
|
+
lines.push("## Editor");
|
|
71
|
+
lines.push("");
|
|
72
|
+
lines.push("| id | surface | intents (excerpt) | where (Navigate op) | params | legacy op (pre-Navigate engines) | what the user sees |");
|
|
73
|
+
lines.push("|---|---|---|---|---|---|---|");
|
|
74
|
+
for (const meta of EDITOR_TARGETS)
|
|
75
|
+
lines.push(editorRow(meta));
|
|
76
|
+
lines.push("");
|
|
77
|
+
lines.push("## Shorthands the tool also accepts");
|
|
78
|
+
lines.push("");
|
|
79
|
+
lines.push("- A `res://` path: `.tscn`/`.scn` → `scene`, `.gd`/`.cs` → `script`, anything else → `file`.");
|
|
80
|
+
lines.push("- A summerengine.com path: `/pricing` resolves to the matching row; an unknown path on the gateway origin opens as given and is reported `unmapped: true`.");
|
|
81
|
+
lines.push("- Anything that is not on summerengine.com or docs.summerengine.com is refused.");
|
|
82
|
+
lines.push("");
|
|
83
|
+
return lines.join("\n");
|
|
84
|
+
}
|