summer-engine 3.3.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +4 -2
- package/.codex-plugin/plugin.json +5 -3
- package/.cursor-plugin/plugin.json +4 -2
- package/.factory-plugin/plugin.json +4 -2
- package/.opencode/INSTALL.md +8 -8
- package/.opencode/plugins/summer.js +2 -2
- package/AGENTS.md +7 -7
- package/CHANGELOG.md +50 -0
- package/GEMINI.md +1 -1
- package/NOTICE +1 -1
- package/README.md +32 -35
- package/assets/api-docs.json.gz +0 -0
- package/assets/autopilot/run.sh +2 -2
- package/assets/navigation/web-routes.json +1 -1
- package/commands/gameskill.md +2 -2
- package/commands/summer.md +25 -25
- package/dist/cli/commands/install.d.ts +10 -0
- package/dist/cli/commands/install.js +55 -10
- package/dist/cli/commands/open.d.ts +1 -1
- package/dist/cli/commands/run.d.ts +1 -1
- package/dist/cli/commands/run.js +1 -1
- package/dist/cli/commands/skills.js +2 -2
- package/dist/cli/commands/tool.d.ts +7 -0
- package/dist/cli/commands/tool.js +36 -1
- package/dist/core/api-client.d.ts +5 -6
- package/dist/core/api-client.js +12 -15
- package/dist/core/auth.js +2 -2
- package/dist/core/capabilities/asset-import.d.ts +0 -1
- package/dist/core/capabilities/camera-view.d.ts +1 -1
- package/dist/core/capabilities/camera-view.js +2 -2
- package/dist/core/capabilities/capture-gameplay.d.ts +69 -0
- package/dist/core/capabilities/capture-gameplay.js +283 -0
- package/dist/core/capabilities/connect-signal.d.ts +1 -2
- package/dist/core/capabilities/connect-signal.js +1 -2
- package/dist/core/capabilities/console-read.d.ts +2 -2
- package/dist/core/capabilities/console-read.js +2 -2
- package/dist/core/capabilities/creator.js +1 -1
- package/dist/core/capabilities/doctor.d.ts +9 -1
- package/dist/core/capabilities/doctor.js +47 -4
- package/dist/core/capabilities/engine-receipt.d.ts +5 -7
- package/dist/core/capabilities/engine-receipt.js +7 -9
- package/dist/core/capabilities/engine-run.d.ts +4 -0
- package/dist/core/capabilities/engine-run.js +33 -5
- package/dist/core/capabilities/export-engine-version.d.ts +15 -0
- package/dist/core/capabilities/export-engine-version.js +24 -0
- package/dist/core/capabilities/export-game.d.ts +9 -1
- package/dist/core/capabilities/export-game.js +115 -39
- package/dist/core/capabilities/export-presets.d.ts +1 -1
- package/dist/core/capabilities/export-presets.js +1 -1
- package/dist/core/capabilities/fabricate-mesh.d.ts +2 -3
- package/dist/core/capabilities/fabricate-mesh.js +2 -3
- package/dist/core/capabilities/frame-quality.d.ts +4 -4
- package/dist/core/capabilities/frame-quality.js +4 -4
- package/dist/core/capabilities/grep.d.ts +1 -1
- package/dist/core/capabilities/grep.js +1 -1
- package/dist/core/capabilities/image-generation.d.ts +9 -0
- package/dist/core/capabilities/image-generation.js +19 -1
- package/dist/core/capabilities/navigation/open.d.ts +1 -1
- package/dist/core/capabilities/navigation/open.js +1 -1
- package/dist/core/capabilities/navigation/render-product-map.js +1 -1
- package/dist/core/capabilities/navigation/targets.js +2 -2
- package/dist/core/capabilities/placement-batch.d.ts +1 -1
- package/dist/core/capabilities/placement-batch.js +2 -2
- package/dist/core/capabilities/play-determinism.d.ts +1 -1
- package/dist/core/capabilities/play-determinism.js +1 -1
- package/dist/core/capabilities/publish-build.d.ts +15 -2
- package/dist/core/capabilities/publish-build.js +78 -28
- package/dist/core/capabilities/publish-download.d.ts +1 -2
- package/dist/core/capabilities/publish-download.js +2 -3
- package/dist/core/capabilities/replace-node.d.ts +1 -3
- package/dist/core/capabilities/replace-node.js +1 -3
- package/dist/core/capabilities/runtime-control.d.ts +5 -7
- package/dist/core/capabilities/runtime-control.js +7 -9
- package/dist/core/capabilities/scene-batch.d.ts +1 -1
- package/dist/core/capabilities/scene-batch.js +1 -1
- package/dist/core/capabilities/scene-kind.js +1 -1
- package/dist/core/capabilities/scene-readback.d.ts +3 -4
- package/dist/core/capabilities/scene-readback.js +3 -4
- package/dist/core/capabilities/scene-script.d.ts +2 -2
- package/dist/core/capabilities/scene-script.js +2 -2
- package/dist/core/capabilities/seeing/shot-store.d.ts +1 -1
- package/dist/core/capabilities/seeing/shot-store.js +1 -1
- package/dist/core/capabilities/summer-bundle.d.ts +2 -3
- package/dist/core/capabilities/summer-bundle.js +2 -3
- package/dist/core/capabilities/surface-snap.d.ts +1 -1
- package/dist/core/capabilities/surface-snap.js +1 -1
- package/dist/core/capabilities/tool-dispatch.js +11 -1
- package/dist/core/capabilities/ui-control.d.ts +1 -2
- package/dist/core/capabilities/ui-control.js +1 -2
- package/dist/core/capabilities/world-snapshot.d.ts +1 -1
- package/dist/core/capabilities/world-snapshot.js +1 -1
- package/dist/core/capability-skew.d.ts +2 -3
- package/dist/core/capability-skew.js +4 -5
- package/dist/core/config.js +2 -2
- package/dist/core/engine-install.d.ts +16 -0
- package/dist/core/engine-install.js +32 -2
- package/dist/core/feedback/client.js +1 -1
- package/dist/core/hosted-mcp.d.ts +115 -0
- package/dist/core/hosted-mcp.js +164 -0
- package/dist/core/launch-posture.d.ts +6 -3
- package/dist/core/launch-posture.js +18 -5
- package/dist/core/library-read.js +1 -2
- package/dist/core/templates.d.ts +1 -2
- package/dist/core/templates.js +1 -2
- package/dist/mcp/hosted-mount.d.ts +13 -59
- package/dist/mcp/hosted-mount.js +24 -30
- package/dist/mcp/server.d.ts +2 -2
- package/dist/mcp/server.js +5 -4
- package/dist/mcp/tools/creator-tools.js +14 -4
- package/dist/mcp/tools/debug-tools.js +1 -1
- package/dist/mcp/tools/generate-tools.js +19 -9
- package/dist/mcp/tools/navigation-tools.d.ts +1 -1
- package/dist/mcp/tools/navigation-tools.js +1 -1
- package/dist/mcp/tools/spatial-tools.js +1 -1
- package/dist/mcp/tools/visual-tools.js +2 -2
- package/dist/mcp/tools/with-engine.d.ts +1 -2
- package/dist/mcp/tools/with-engine.js +1 -2
- package/gemini-extension.json +3 -1
- package/hooks/session-start.sh +2 -2
- package/integrations/README.md +70 -76
- package/integrations/claude/README.md +0 -3
- package/integrations/codex/README.md +1 -2
- package/integrations/copilot-jetbrains/README.md +1 -1
- package/integrations/cursor/README.md +1 -2
- package/integrations/factory/README.md +15 -11
- package/integrations/mistral-vibe/README.md +1 -1
- package/integrations/opencode/README.md +1 -1
- package/integrations/roo-code/README.md +1 -1
- package/integrations/rovo-dev/README.md +1 -1
- package/integrations/trae/README.md +1 -1
- package/integrations/windsurf/README.md +3 -3
- package/library/references/collaborative-protocol/collaborative-protocol.md +5 -5
- package/library/references/gd-style/gd-style.md +4 -6
- package/library/references/godot-version/godot-version.md +3 -3
- package/library/references/headless-routing/headless-routing.md +2 -2
- package/library/references/mcp-fresh-chat-playbook/mcp-fresh-chat-playbook.md +2 -2
- package/library/references/mcp-tools-reference/mcp-tools-reference.md +18 -16
- package/library/references/product-map/product-map.md +1 -1
- package/library/references/public-surface-language/public-surface-language.md +1 -1
- package/library/references/summer-folder/summer-folder.md +1 -1
- package/library/skills/3d-lighting/SKILL.md +4 -4
- package/library/skills/README.md +11 -9
- package/library/skills/adaptive-music/SKILL.md +7 -7
- package/library/skills/ai-characters-in-games/SKILL.md +1 -1
- package/library/skills/ambient-bed/SKILL.md +12 -14
- package/library/skills/animated-loop/SKILL.md +42 -42
- package/library/skills/animation-tree/SKILL.md +6 -6
- package/library/skills/art-direction/SKILL.md +8 -11
- package/library/skills/asset-strategy/SKILL.md +3 -3
- package/library/skills/audio-direction/SKILL.md +8 -10
- package/library/skills/auto-fire-targeting/SKILL.md +4 -3
- package/library/skills/bounded-engine-runs/SKILL.md +95 -0
- package/library/skills/bounded-engine-runs/resource.yaml +29 -0
- package/library/skills/brainstorm-game/SKILL.md +5 -5
- package/library/skills/brainstorming/SKILL.md +9 -15
- package/library/skills/celeste-momentum-platforming/SKILL.md +8 -13
- package/library/skills/celeste-momentum-platforming/resource.yaml +1 -1
- package/library/skills/character-animation-wiring/SKILL.md +2 -2
- package/library/skills/character-model/SKILL.md +15 -26
- package/library/skills/character-movement/SKILL.md +1 -1
- package/library/skills/character-movement/references/movement-3d.md +1 -1
- package/library/skills/character-portrait/SKILL.md +4 -4
- package/library/skills/cinematic-cutscene/SKILL.md +38 -38
- package/library/skills/combat-basics/SKILL.md +1 -1
- package/library/skills/compatibility-renderer-traps/SKILL.md +78 -0
- package/library/skills/compatibility-renderer-traps/resource.yaml +28 -0
- package/library/skills/concept-art/SKILL.md +4 -4
- package/library/skills/create-asset-sheet/SKILL.md +12 -31
- package/library/skills/debug/SKILL.md +5 -4
- package/library/skills/debugging-game-feel/SKILL.md +1 -4
- package/library/skills/debugging-game-feel/resource.yaml +1 -1
- package/library/skills/design-level/SKILL.md +5 -5
- package/library/skills/design-mechanic/SKILL.md +6 -6
- package/library/skills/design-npc/SKILL.md +8 -15
- package/library/skills/diagnosing-perf-regressions/SKILL.md +5 -10
- package/library/skills/dispatching-parallel-agents/SKILL.md +1 -19
- package/library/skills/environment-kit/SKILL.md +5 -5
- package/library/skills/export-and-ship/SKILL.md +25 -24
- package/library/skills/fabricating-assets/SKILL.md +1 -1
- package/library/skills/facial-and-lipsync/SKILL.md +5 -5
- package/library/skills/fps-controller/SKILL.md +17 -16
- package/library/skills/fps-controller/resource.yaml +0 -2
- package/library/skills/game-feel/SKILL.md +6 -7
- package/library/skills/gameskill/SKILL.md +3 -3
- package/library/skills/gdscript-patterns/SKILL.md +3 -3
- package/library/skills/generate-motion/SKILL.md +5 -22
- package/library/skills/godogen-visual-proof-game-generation/SKILL.md +72 -90
- package/library/skills/godogen-visual-proof-game-generation/resource.yaml +0 -1
- package/library/skills/headless-scripting/SKILL.md +8 -8
- package/library/skills/headless-scripting/resource.yaml +1 -0
- package/library/skills/in-game-purchases/SKILL.md +123 -118
- package/library/skills/in-game-purchases/resource.yaml +2 -2
- package/library/skills/instantiate-asset-pack/SKILL.md +7 -3
- package/library/skills/investigating-bugs/SKILL.md +3 -11
- package/library/skills/investigating-bugs/condition-based-waiting.md +0 -10
- package/library/skills/investigating-bugs/root-cause-tracing.md +0 -8
- package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +15 -15
- package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +0 -1
- package/library/skills/make-game/SKILL.md +3 -5
- package/library/skills/make-game/references/2d-platformer.md +1 -1
- package/library/skills/multiplayer-project/SKILL.md +1 -1
- package/library/skills/multiplayer-testing/SKILL.md +4 -4
- package/library/skills/music-track/SKILL.md +40 -38
- package/library/skills/new-project/SKILL.md +4 -6
- package/library/skills/organic-model/SKILL.md +9 -9
- package/library/skills/pixel-art/SKILL.md +6 -6
- package/library/skills/play/SKILL.md +3 -4
- package/library/skills/playtesting-a-feature/SKILL.md +4 -6
- package/library/skills/procedural-animation/SKILL.md +10 -11
- package/library/skills/prop-model/SKILL.md +4 -4
- package/library/skills/psx-retro-rendering/SKILL.md +20 -20
- package/library/skills/psx-retro-rendering/resource.yaml +2 -3
- package/library/skills/realtime-wet-surfaces/SKILL.md +15 -15
- package/library/skills/realtime-wet-surfaces/resource.yaml +1 -2
- package/library/skills/remote-deploy/SKILL.md +20 -21
- package/library/skills/retarget/SKILL.md +19 -23
- package/library/skills/running-in-the-cloud/SKILL.md +5 -5
- package/library/skills/scene-composition/SKILL.md +5 -5
- package/library/skills/scene-hierarchy-design/SKILL.md +3 -3
- package/library/skills/scene-hierarchy-design/resource.yaml +0 -1
- package/library/skills/scene-scripting/SKILL.md +3 -3
- package/library/skills/scene-to-level/SKILL.md +28 -31
- package/library/skills/skill-create/SKILL.md +1 -1
- package/library/skills/skill-improve/SKILL.md +9 -9
- package/library/skills/skill-test/SKILL.md +10 -10
- package/library/skills/skintokens-auto-rigging/SKILL.md +18 -18
- package/library/skills/skintokens-auto-rigging/resource.yaml +3 -3
- package/library/skills/skybox-panorama/SKILL.md +8 -9
- package/library/skills/sound-effect/SKILL.md +19 -19
- package/library/skills/spatial-placement/SKILL.md +2 -2
- package/library/skills/spatial-placement/references/kit-placement-tools.md +12 -22
- package/library/skills/sprite-sheet/SKILL.md +10 -10
- package/library/skills/summer-analytics/SKILL.md +3 -3
- package/library/skills/summer-friends/SKILL.md +10 -10
- package/library/skills/summer-leaderboards/SKILL.md +6 -6
- package/library/skills/summer-match-results/SKILL.md +13 -13
- package/library/skills/summer-matchmaking/SKILL.md +11 -11
- package/library/skills/summer-parties/SKILL.md +9 -9
- package/library/skills/summer-player-data/SKILL.md +12 -12
- package/library/skills/summer-store/SKILL.md +6 -6
- package/library/skills/summer-world-chat/SKILL.md +9 -9
- package/library/skills/summer-world-saves/SKILL.md +7 -7
- package/library/skills/text-to-motion/rigging-for-text-motion.md +1 -1
- package/library/skills/tileable-texture/SKILL.md +1 -1
- package/library/skills/trailer-shot/SKILL.md +36 -36
- package/library/skills/tune-performance/SKILL.md +13 -13
- package/library/skills/tune-performance/resource.yaml +1 -1
- package/library/skills/ui-graphics/SKILL.md +7 -7
- package/library/skills/use-widget-asset/SKILL.md +7 -7
- package/library/skills/using-summer/SKILL.md +5 -7
- package/library/skills/vehicle-model/SKILL.md +6 -7
- package/library/skills/vehicle-model/resource.yaml +2 -2
- package/library/skills/verification-before-completion/SKILL.md +5 -6
- package/library/skills/vfx-dissolve/SKILL.md +4 -4
- package/library/skills/vfx-fire/SKILL.md +6 -6
- package/library/skills/vfx-fire/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/vfx-hit-spark/SKILL.md +4 -4
- package/library/skills/vfx-hit-spark/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/vfx-lightning/SKILL.md +5 -5
- package/library/skills/vfx-lightning/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/vfx-lightning/_building-blocks/trauma-shake-snippet.md +9 -3
- package/library/skills/vfx-magic-glow/SKILL.md +4 -4
- package/library/skills/vfx-magic-glow/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/vfx-muzzle-flash/SKILL.md +5 -5
- package/library/skills/vfx-muzzle-flash/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/vfx-muzzle-flash/_building-blocks/trauma-shake-snippet.md +9 -3
- package/library/skills/vfx-smoke/SKILL.md +5 -5
- package/library/skills/vfx-water-ripple/SKILL.md +2 -2
- package/library/skills/vfx-water-ripple/_building-blocks/additive-billboard-particles.md +3 -3
- package/library/skills/voice-line/SKILL.md +9 -9
- package/library/skills/web-compatibility-look/resource.yaml +1 -0
- package/library/skills/world-building-3d/references/spatial-tools.md +2 -2
- package/library/skills/writing-plans/SKILL.md +4 -4
- package/library/skills/writing-skills/SKILL.md +8 -8
- package/library/tools/capture-gameplay/resource.yaml +73 -0
- package/library/tools/creator-publish/resource.yaml +4 -4
- package/library/tools/creator-releases/resource.yaml +5 -5
- package/library/tools/generate-image/resource.yaml +15 -1
- package/library/tools/publish-build/resource.yaml +6 -2
- package/package.json +1 -1
- package/registry/generated/aliases.json +1 -0
- package/registry/generated/counts.json +3 -3
- package/registry/generated/gemini-extension.json +3 -1
- package/registry/generated/index.json +248 -135
- package/registry/generated/marketplace.claude.json +2 -2
- package/registry/generated/plugin.claude.json +4 -2
- package/registry/generated/plugin.codex.json +5 -3
- package/registry/generated/plugin.cursor.json +4 -2
- package/registry/generated/plugin.factory.json +4 -2
- package/registry/generated/skills-index.md +11 -9
- package/registry/generated/skills-registry.json +33 -6
- package/registry/schemas/domains.json +1 -1
|
@@ -7,7 +7,7 @@ export { runEngine, SUMMER_GAMES_PRESET, type EngineRun };
|
|
|
7
7
|
* summer_export_game: run the installed Summer Engine headless and return the
|
|
8
8
|
* file the Summer Games store takes for the chosen targets.
|
|
9
9
|
*
|
|
10
|
-
* <engine> --headless --path <project> --export-release "<preset>" <out>
|
|
10
|
+
* <engine> --headless --summer-no-api --path <project> --export-release "<preset>" <out>
|
|
11
11
|
*
|
|
12
12
|
* format "bundle" (default): the summer.bundle.v1 .zip for build-publications
|
|
13
13
|
* (summer_publish_build). Summer runs its client.pck on its own templates in
|
|
@@ -69,10 +69,16 @@ export interface ExportGameResult {
|
|
|
69
69
|
icon?: string | null;
|
|
70
70
|
/** Download format: what signing the file carries. */
|
|
71
71
|
signing?: string;
|
|
72
|
+
/** Files in the project folder the export created, changed or removed (export_presets.cfg, project.godot, ...). */
|
|
73
|
+
projectChanges?: ProjectChange[];
|
|
72
74
|
/** Things the store will still refuse or warn about, in plain words. */
|
|
73
75
|
warnings?: string[];
|
|
74
76
|
next: string;
|
|
75
77
|
}
|
|
78
|
+
export interface ProjectChange {
|
|
79
|
+
file: string;
|
|
80
|
+
change: "created" | "modified" | "deleted";
|
|
81
|
+
}
|
|
76
82
|
export interface LastExport {
|
|
77
83
|
path: string;
|
|
78
84
|
project: string;
|
|
@@ -84,6 +90,8 @@ export interface LastExport {
|
|
|
84
90
|
}
|
|
85
91
|
export interface ExportGameDependencies {
|
|
86
92
|
findBinary: () => string | null;
|
|
93
|
+
/** Installed Summer version of the binary (Info.plist, sq.version), or null. */
|
|
94
|
+
engineVersion: (binary: string) => string | null;
|
|
87
95
|
run: (binary: string, args: string[], timeoutMs: number) => Promise<EngineRun>;
|
|
88
96
|
now: () => Date;
|
|
89
97
|
/** Template lookup for download exports (overridable in tests). */
|
|
@@ -6,7 +6,8 @@ import { engineSelectionFromEnv } from "../engine.js";
|
|
|
6
6
|
import { findEngineBinary } from "../engine-install.js";
|
|
7
7
|
import { readStoreJson, writeStoreJson } from "../store.js";
|
|
8
8
|
import { writeZip } from "../util/zip-write.js";
|
|
9
|
-
import { runEngine } from "./engine-run.js";
|
|
9
|
+
import { engineErrorLines, runEngine } from "./engine-run.js";
|
|
10
|
+
import { assertExportEngine, installedEngineVersion } from "./export-engine-version.js";
|
|
10
11
|
import { BUNDLE_TARGETS, DOWNLOAD_TARGETS, SUMMER_GAMES_PRESET, bundlePresetSpec, ensurePreset, normalizeTargets, variantString, } from "./export-presets.js";
|
|
11
12
|
import { engineTemplateInfo, findInstalledTemplate, templateFileFor } from "./export-templates.js";
|
|
12
13
|
import { BuildToolError, hashFile, readSummerBundle } from "./summer-bundle.js";
|
|
@@ -15,7 +16,7 @@ export { runEngine, SUMMER_GAMES_PRESET };
|
|
|
15
16
|
* summer_export_game: run the installed Summer Engine headless and return the
|
|
16
17
|
* file the Summer Games store takes for the chosen targets.
|
|
17
18
|
*
|
|
18
|
-
* <engine> --headless --path <project> --export-release "<preset>" <out>
|
|
19
|
+
* <engine> --headless --summer-no-api --path <project> --export-release "<preset>" <out>
|
|
19
20
|
*
|
|
20
21
|
* format "bundle" (default): the summer.bundle.v1 .zip for build-publications
|
|
21
22
|
* (summer_publish_build). Summer runs its client.pck on its own templates in
|
|
@@ -35,15 +36,15 @@ export { runEngine, SUMMER_GAMES_PRESET };
|
|
|
35
36
|
*/
|
|
36
37
|
export const LAST_EXPORT_FILE = "last-export.json";
|
|
37
38
|
const DEFAULT_TIMEOUT_MS = 15 * 60_000;
|
|
38
|
-
/** Store platform ids of the versions intake
|
|
39
|
+
/** Store platform ids of the store's versions intake. */
|
|
39
40
|
const STORE_VERSION_PLATFORM = {
|
|
40
41
|
web: "web",
|
|
41
42
|
macos: "macos-universal",
|
|
42
43
|
windows: "windows-x64",
|
|
43
44
|
};
|
|
44
|
-
/** Web zip limits of the store
|
|
45
|
+
/** Web zip limits of the store. */
|
|
45
46
|
const WEB_LIMITS = { zipBytes: 500 * 1024 * 1024, fileBytes: 200 * 1024 * 1024, files: 2000 };
|
|
46
|
-
/** Games without a server run on the phone apps only (
|
|
47
|
+
/** Games without a server run on the phone apps only (the store's standalone targets). */
|
|
47
48
|
const STANDALONE_TARGETS = ["ios", "android"];
|
|
48
49
|
/** Engine support per bundle target, for the recovery text when a target is missing. */
|
|
49
50
|
const TARGET_ENGINE_NOTE = {
|
|
@@ -51,6 +52,7 @@ const TARGET_ENGINE_NOTE = {
|
|
|
51
52
|
};
|
|
52
53
|
const defaultDependencies = {
|
|
53
54
|
findBinary: () => findEngineBinary(platform()),
|
|
55
|
+
engineVersion: installedEngineVersion,
|
|
54
56
|
run: runEngine,
|
|
55
57
|
now: () => new Date(),
|
|
56
58
|
};
|
|
@@ -81,6 +83,69 @@ async function defaultExportDir(project) {
|
|
|
81
83
|
function outputTail(output) {
|
|
82
84
|
return output.trim().split("\n").slice(-40).join("\n");
|
|
83
85
|
}
|
|
86
|
+
/** size and mtime of every file at the top of the project folder (project.godot, export_presets.cfg, ...). */
|
|
87
|
+
async function snapshotProjectFiles(project) {
|
|
88
|
+
const files = new Map();
|
|
89
|
+
for (const entry of await readdir(project, { withFileTypes: true })) {
|
|
90
|
+
if (!entry.isFile())
|
|
91
|
+
continue;
|
|
92
|
+
const info = await stat(join(project, entry.name)).catch(() => null);
|
|
93
|
+
if (info)
|
|
94
|
+
files.set(entry.name, `${info.size}:${info.mtimeMs}`);
|
|
95
|
+
}
|
|
96
|
+
return files;
|
|
97
|
+
}
|
|
98
|
+
async function projectChangesSince(project, before, output) {
|
|
99
|
+
const after = await snapshotProjectFiles(project);
|
|
100
|
+
const changes = [];
|
|
101
|
+
for (const [file, value] of after) {
|
|
102
|
+
if (output && resolve(project, file) === resolve(output))
|
|
103
|
+
continue;
|
|
104
|
+
if (!before.has(file))
|
|
105
|
+
changes.push({ file, change: "created" });
|
|
106
|
+
else if (before.get(file) !== value)
|
|
107
|
+
changes.push({ file, change: "modified" });
|
|
108
|
+
}
|
|
109
|
+
for (const file of before.keys())
|
|
110
|
+
if (!after.has(file))
|
|
111
|
+
changes.push({ file, change: "deleted" });
|
|
112
|
+
return changes.sort((a, b) => a.file.localeCompare(b.file));
|
|
113
|
+
}
|
|
114
|
+
function projectChangeWarnings(changes) {
|
|
115
|
+
return changes.some((entry) => entry.file === "project.godot" && entry.change === "modified")
|
|
116
|
+
? ["Summer Engine rewrote project.godot while it exported (an engine update cleans up old settings; the previous file is project.godot.bak). Review the change and commit or revert it."]
|
|
117
|
+
: [];
|
|
118
|
+
}
|
|
119
|
+
/** Re-throw an export failure with the project files it already changed. */
|
|
120
|
+
async function withProjectChanges(project, before, work) {
|
|
121
|
+
try {
|
|
122
|
+
return await work();
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
if (!(error instanceof BuildToolError))
|
|
126
|
+
throw error;
|
|
127
|
+
const changes = await projectChangesSince(project, before).catch(() => []);
|
|
128
|
+
if (!changes.length)
|
|
129
|
+
throw error;
|
|
130
|
+
throw new BuildToolError(error.code, error.message.replace(` ${error.recovery}`, ""), error.recovery, error.status, { ...error.detail, projectChanges: changes });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** Plain recovery for what the engine printed; the generic preset hint only when a preset is what it names. */
|
|
134
|
+
function exportFailureRecovery(errors, preset) {
|
|
135
|
+
const text = errors.join("\n");
|
|
136
|
+
if (/export preset/i.test(text) && /(invalid|not found|no such|unknown)/i.test(text)) {
|
|
137
|
+
return `Recovery: this engine has no "${preset}" export preset, which means it predates summer.games exports: update Summer Engine to 0.7.0+ (run "summer install --yes"), then export again.`;
|
|
138
|
+
}
|
|
139
|
+
if (/source graph|client pack|authority|domain/i.test(text)) {
|
|
140
|
+
return ("Recovery: this is a hosted game whose source graph puts a resource the client loads in a server-only (authority) domain. " +
|
|
141
|
+
"Open the source graph summer.build.json names (source_graph, usually source-domains.json) and narrow the authority root to the server-only files " +
|
|
142
|
+
"(for example the authority scene and its script), so the scenes and resources the client starts (such as the network composition .tres) sit under a shared or client root. " +
|
|
143
|
+
"The multiplayer-project skill explains the domains. Then export again.");
|
|
144
|
+
}
|
|
145
|
+
return errors.length
|
|
146
|
+
? "Recovery: fix what the engine names above and export again."
|
|
147
|
+
: "Recovery: the engine printed no ERROR line; read output, fix what it names, and export again.";
|
|
148
|
+
}
|
|
84
149
|
/** One value from project.godot ([section] key=value), unquoted. */
|
|
85
150
|
export function projectSetting(project, section, key) {
|
|
86
151
|
let current = "";
|
|
@@ -189,7 +254,8 @@ async function listFiles(root) {
|
|
|
189
254
|
return files.sort();
|
|
190
255
|
}
|
|
191
256
|
async function runExport(deps, binary, project, preset, out, debug, timeoutMs, notes) {
|
|
192
|
-
|
|
257
|
+
// --summer-no-api: an export needs no local HTTP API; nothing binds 127.0.0.1:6550 or writes discovery files.
|
|
258
|
+
const args = ["--headless", "--summer-no-api", "--path", project, debug ? "--export-debug" : "--export-release", preset, out];
|
|
193
259
|
let run;
|
|
194
260
|
try {
|
|
195
261
|
run = await deps.run(binary, args, timeoutMs);
|
|
@@ -201,10 +267,9 @@ async function runExport(deps, binary, project, preset, out, debug, timeoutMs, n
|
|
|
201
267
|
throw new BuildToolError("export_timeout", `The export did not finish within ${Math.round(timeoutMs / 1000)} seconds and was stopped.`, "Recovery: a first export imports every asset; retry with a larger timeoutSeconds.", undefined, { output: outputTail(run.output) });
|
|
202
268
|
}
|
|
203
269
|
if (run.code !== 0 || !existsSync(out)) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
].join(" "), undefined, { output: outputTail(run.output) });
|
|
270
|
+
const errors = run.errors?.length ? run.errors : engineErrorLines(run.output);
|
|
271
|
+
const named = errors.slice(0, 3).map((line) => line.replace(/^(SCRIPT )?ERROR:\s*/, ""));
|
|
272
|
+
throw new BuildToolError("export_failed", `Summer Engine did not export the game (exit ${run.code ?? run.signal})${named.length ? `: ${named.join(" | ")}` : "."}`, [exportFailureRecovery(errors, preset), ...notes].join(" "), undefined, { errors, output: outputTail(run.output) });
|
|
208
273
|
}
|
|
209
274
|
}
|
|
210
275
|
export async function exportGame(input, overrides = {}) {
|
|
@@ -227,15 +292,19 @@ export async function exportGame(input, overrides = {}) {
|
|
|
227
292
|
if (!binary) {
|
|
228
293
|
throw new BuildToolError("engine_not_installed", "Summer Engine is not installed on this machine.", 'Recovery: run "summer install", or set SUMMER_BIN to the engine executable, then export again.');
|
|
229
294
|
}
|
|
295
|
+
// Before any preset is written: an old engine cannot read them.
|
|
296
|
+
assertExportEngine(binary, deps.engineVersion(binary));
|
|
230
297
|
if (format === "download") {
|
|
231
298
|
return exportDownload(deps, binary, project, targets[0], out, debug, timeoutMs, started);
|
|
232
299
|
}
|
|
233
300
|
out ??= join(await defaultExportDir(project), `${basename(project)}-${stamp(started)}.zip`);
|
|
234
301
|
const before = existsSync(out) ? statSync(out).mtimeMs : null;
|
|
302
|
+
const projectBefore = await snapshotProjectFiles(project);
|
|
235
303
|
const ensured = targets ? await ensurePreset(project, bundlePresetSpec(targets)) : undefined;
|
|
236
304
|
const preset = ensured?.name ?? (input.preset?.trim() || SUMMER_GAMES_PRESET);
|
|
237
305
|
const notes = (targets ?? []).flatMap((target) => TARGET_ENGINE_NOTE[target] ?? []);
|
|
238
|
-
await runExport(deps, binary, project, preset, out, debug, timeoutMs, notes);
|
|
306
|
+
await withProjectChanges(project, projectBefore, () => runExport(deps, binary, project, preset, out, debug, timeoutMs, notes));
|
|
307
|
+
const projectChanges = await projectChangesSince(project, projectBefore, out);
|
|
239
308
|
if (before !== null && statSync(out).mtimeMs === before) {
|
|
240
309
|
throw new BuildToolError("export_failed", "Summer Engine exited without writing a new bundle.", "Recovery: read the engine output and export again.");
|
|
241
310
|
}
|
|
@@ -244,7 +313,7 @@ export async function exportGame(input, overrides = {}) {
|
|
|
244
313
|
if (missing.length) {
|
|
245
314
|
throw new BuildToolError("export_target_unsupported", `This Summer Engine exported the bundle without ${missing.join(", ")}: its summer.games preset has no such platform.`, ["Recovery: update Summer Engine and export again, or export without those targets.", ...missing.flatMap((target) => TARGET_ENGINE_NOTE[target] ?? [])].join(" "), undefined, { exportedPlatforms: bundle.targetPlatforms, path: out });
|
|
246
315
|
}
|
|
247
|
-
const warnings =
|
|
316
|
+
const warnings = projectChangeWarnings(projectChanges);
|
|
248
317
|
const desktopOnly = bundle.hosted ? [] : bundle.targetPlatforms.filter((target) => !STANDALONE_TARGETS.includes(target));
|
|
249
318
|
if (desktopOnly.length) {
|
|
250
319
|
warnings.push(`This game has no server, and the store runs games without a server on iPhone and Android only: summer_publish_build will refuse ${desktopOnly.join(", ")}. ` +
|
|
@@ -267,6 +336,7 @@ export async function exportGame(input, overrides = {}) {
|
|
|
267
336
|
engine: binary,
|
|
268
337
|
durationMs: deps.now().getTime() - started.getTime(),
|
|
269
338
|
bundle: { ...summary, fileCount: files.length },
|
|
339
|
+
...(projectChanges.length ? { projectChanges } : {}),
|
|
270
340
|
...(warnings.length ? { warnings } : {}),
|
|
271
341
|
next: "Upload it to the game's store listing with summer_publish_build (gameId, clientVersion).",
|
|
272
342
|
};
|
|
@@ -296,6 +366,7 @@ async function exportDownload(deps, binary, project, target, requestedOut, debug
|
|
|
296
366
|
throw error;
|
|
297
367
|
}
|
|
298
368
|
const spec = downloadPresetSpec(target, slug);
|
|
369
|
+
const projectBefore = await snapshotProjectFiles(project);
|
|
299
370
|
const ensured = await ensurePreset(project, spec);
|
|
300
371
|
const exportsDir = await defaultExportDir(project);
|
|
301
372
|
const work = join(exportsDir, `${slug}-${target}-${stamp(started)}`);
|
|
@@ -304,37 +375,41 @@ async function exportDownload(deps, binary, project, target, requestedOut, debug
|
|
|
304
375
|
const out = requestedOut ?? join(exportsDir, `${slug}-${storePlatform}-${stamp(started)}.zip`);
|
|
305
376
|
const warnings = [];
|
|
306
377
|
let fileCount = 1;
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
else {
|
|
316
|
-
const engineOut = join(work, target === "web" ? "index.html" : `${slug}.exe`);
|
|
317
|
-
await runExport(deps, binary, project, spec.name, engineOut, debug, timeoutMs, []);
|
|
318
|
-
const files = await listFiles(work);
|
|
319
|
-
const entries = files.map((file) => ({ name: relative(work, file).split(sep).join("/"), source: file }));
|
|
320
|
-
if (target === "web") {
|
|
321
|
-
const sizes = await Promise.all(files.map(async (file) => (await stat(file)).size));
|
|
322
|
-
const total = sizes.reduce((sum, size) => sum + size, 0);
|
|
323
|
-
const tooBig = entries.find((_entry, index) => sizes[index] > WEB_LIMITS.fileBytes);
|
|
324
|
-
if (entries.length > WEB_LIMITS.files || total > WEB_LIMITS.zipBytes || tooBig) {
|
|
325
|
-
throw new BuildToolError("web_build_too_large", `The web build has ${entries.length} files and ${Math.round(total / 1048576)} MiB${tooBig ? `; ${tooBig.name} is over 200 MiB` : ""}. The store takes at most ${WEB_LIMITS.files} files, 500 MiB, 200 MiB per file.`, "Recovery: exclude unused assets from the export (Project > Export > Resources) or compress textures, then export again.");
|
|
326
|
-
}
|
|
378
|
+
await withProjectChanges(project, projectBefore, async () => {
|
|
379
|
+
try {
|
|
380
|
+
if (target === "macos") {
|
|
381
|
+
// The macOS exporter writes the .app inside a .zip itself.
|
|
382
|
+
const engineOut = join(work, `${slug}.zip`);
|
|
383
|
+
await runExport(deps, binary, project, spec.name, engineOut, debug, timeoutMs, []);
|
|
384
|
+
await rename(engineOut, out);
|
|
385
|
+
warnings.push("macOS shows players an unidentified-developer prompt for an ad hoc signed app; the store accepts it as is.");
|
|
327
386
|
}
|
|
328
387
|
else {
|
|
329
|
-
|
|
388
|
+
const engineOut = join(work, target === "web" ? "index.html" : `${slug}.exe`);
|
|
389
|
+
await runExport(deps, binary, project, spec.name, engineOut, debug, timeoutMs, []);
|
|
390
|
+
const files = await listFiles(work);
|
|
391
|
+
const entries = files.map((file) => ({ name: relative(work, file).split(sep).join("/"), source: file }));
|
|
392
|
+
if (target === "web") {
|
|
393
|
+
const sizes = await Promise.all(files.map(async (file) => (await stat(file)).size));
|
|
394
|
+
const total = sizes.reduce((sum, size) => sum + size, 0);
|
|
395
|
+
const tooBig = entries.find((_entry, index) => sizes[index] > WEB_LIMITS.fileBytes);
|
|
396
|
+
if (entries.length > WEB_LIMITS.files || total > WEB_LIMITS.zipBytes || tooBig) {
|
|
397
|
+
throw new BuildToolError("web_build_too_large", `The web build has ${entries.length} files and ${Math.round(total / 1048576)} MiB${tooBig ? `; ${tooBig.name} is over 200 MiB` : ""}. The store takes at most ${WEB_LIMITS.files} files, 500 MiB, 200 MiB per file.`, "Recovery: exclude unused assets from the export (Project > Export > Resources) or compress textures, then export again.");
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
warnings.push("The .exe is not code signed; Windows SmartScreen may warn players. The store accepts it as is.");
|
|
402
|
+
}
|
|
403
|
+
await writeZip(out, entries);
|
|
404
|
+
fileCount = entries.length;
|
|
330
405
|
}
|
|
331
|
-
await writeZip(out, entries);
|
|
332
|
-
fileCount = entries.length;
|
|
333
406
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
407
|
+
finally {
|
|
408
|
+
await rm(work, { recursive: true, force: true });
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
const projectChanges = await projectChangesSince(project, projectBefore, out);
|
|
412
|
+
warnings.unshift(...projectChangeWarnings(projectChanges));
|
|
338
413
|
const icon = projectSetting(project, "application", "config/icon");
|
|
339
414
|
if (!icon)
|
|
340
415
|
warnings.push("The project has no icon (Project Settings > Application > Config > Icon); the export uses the Summer default.");
|
|
@@ -358,6 +433,7 @@ async function exportDownload(deps, binary, project, target, requestedOut, debug
|
|
|
358
433
|
fileCount,
|
|
359
434
|
icon,
|
|
360
435
|
signing: target === "macos" ? "ad hoc (built-in), not notarized" : "none",
|
|
436
|
+
...(projectChanges.length ? { projectChanges } : {}),
|
|
361
437
|
...(warnings.length ? { warnings } : {}),
|
|
362
438
|
next: `Upload it as the game's ${storePlatform} store version with summer_publish_build (gameId, clientVersion); it reads the platform from this export.`,
|
|
363
439
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Store targets for summer_export_game, and the export presets that make them.
|
|
3
3
|
*
|
|
4
|
-
* The Summer Games store has two intakes
|
|
4
|
+
* The Summer Games store has two intakes:
|
|
5
5
|
* - build-publications takes ONE summer.bundle.v1 .zip per Build. Summer runs
|
|
6
6
|
* its client.pck on its own client templates (the Summer Games iOS and
|
|
7
7
|
* Android apps, the Summer desktop app on macOS and Windows), so the creator
|
|
@@ -5,7 +5,7 @@ import { BuildToolError } from "./summer-bundle.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* Store targets for summer_export_game, and the export presets that make them.
|
|
7
7
|
*
|
|
8
|
-
* The Summer Games store has two intakes
|
|
8
|
+
* The Summer Games store has two intakes:
|
|
9
9
|
* - build-publications takes ONE summer.bundle.v1 .zip per Build. Summer runs
|
|
10
10
|
* its client.pck on its own client templates (the Summer Games iOS and
|
|
11
11
|
* Android apps, the Summer desktop app on macOS and Windows), so the creator
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* (`summer tool fabricate-3d`) so both faces validate the same arguments, send
|
|
5
5
|
* the same op with the same clamps, and wait the same client poll budget.
|
|
6
6
|
*
|
|
7
|
-
* What the op does on the engine side
|
|
7
|
+
* What the op does on the engine side: run one
|
|
8
8
|
* agent-authored bpy script in a supervised headless child of the USER'S OWN
|
|
9
9
|
* Blender install, validate the .glb the child exported, move it under res://,
|
|
10
10
|
* wait for the editor import to settle, and optionally instantiate it into the
|
|
@@ -28,8 +28,7 @@ export declare const FABRICATE_DEFAULT_OUT_DIR = "res://assets/fabricated/";
|
|
|
28
28
|
/** What the tool tells the model to do when the engine lacks FabricateMesh. */
|
|
29
29
|
export declare const FABRICATE_FALLBACK = "generate the asset with summer_generate_3d, import one from the free library with summer_search_assets / summer_import_asset, use summer_import_hdri for environment lighting, or build blockout geometry in-scene with summer_add_node / summer_set_prop or a summer_run_editor_script";
|
|
30
30
|
/**
|
|
31
|
-
* Mirror of the engine's out_path pre-validation
|
|
32
|
-
* _resolve_out_path) so a bad destination is refused on this side with the
|
|
31
|
+
* Mirror of the engine's out_path pre-validation so a bad destination is refused on this side with the
|
|
33
32
|
* same words, and nothing is sent. Returns null when the path is acceptable.
|
|
34
33
|
*/
|
|
35
34
|
export declare function fabricateOutPathProblem(rawPath: string): string | null;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* (`summer tool fabricate-3d`) so both faces validate the same arguments, send
|
|
5
5
|
* the same op with the same clamps, and wait the same client poll budget.
|
|
6
6
|
*
|
|
7
|
-
* What the op does on the engine side
|
|
7
|
+
* What the op does on the engine side: run one
|
|
8
8
|
* agent-authored bpy script in a supervised headless child of the USER'S OWN
|
|
9
9
|
* Blender install, validate the .glb the child exported, move it under res://,
|
|
10
10
|
* wait for the editor import to settle, and optionally instantiate it into the
|
|
@@ -30,8 +30,7 @@ export const FABRICATE_DEFAULT_OUT_DIR = "res://assets/fabricated/";
|
|
|
30
30
|
export const FABRICATE_FALLBACK = "generate the asset with summer_generate_3d, import one from the free library with summer_search_assets / summer_import_asset, use summer_import_hdri for environment lighting, or build blockout geometry in-scene with summer_add_node / summer_set_prop or a summer_run_editor_script";
|
|
31
31
|
const VECTOR3_VARIANT_RE = /^Vector3\(\s*[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?\s*,\s*[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?\s*,\s*[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?\s*\)$/;
|
|
32
32
|
/**
|
|
33
|
-
* Mirror of the engine's out_path pre-validation
|
|
34
|
-
* _resolve_out_path) so a bad destination is refused on this side with the
|
|
33
|
+
* Mirror of the engine's out_path pre-validation so a bad destination is refused on this side with the
|
|
35
34
|
* same words, and nothing is sent. Returns null when the path is acceptable.
|
|
36
35
|
*/
|
|
37
36
|
export function fabricateOutPathProblem(rawPath) {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Frame-quality probe for engine screenshots (tool/screenshot).
|
|
3
3
|
*
|
|
4
|
-
* WHY THIS EXISTS. In the 2026-09-03 end-to-end run
|
|
5
|
-
*
|
|
4
|
+
* WHY THIS EXISTS. In the 2026-09-03 end-to-end run,
|
|
5
|
+
* `summer_screenshot target:"viewport"` returned an entirely black
|
|
6
6
|
* 1072x1280 JPEG (src/core/capabilities/__fixtures__/frames/01-mcp-viewport-black.jpg)
|
|
7
7
|
* with a caption
|
|
8
8
|
* telling the agent to describe what it saw. It was the first viewport capture
|
|
9
9
|
* after scene mutations had flipped the editor from the 3D to the 2D tab; the
|
|
10
10
|
* same call 67 s later returned real content. Engine side, the ViewportSnapshot
|
|
11
|
-
* op
|
|
11
|
+
* op reads the
|
|
12
12
|
* editor SubViewport's texture with get_texture()->get_image() AS-IS — no forced
|
|
13
13
|
* RenderingServer draw and no blank-frame retry, both of which ScenePreview has
|
|
14
|
-
*
|
|
14
|
+
* because a not-yet-drawn
|
|
15
15
|
* texture reads back black. That is consistent with a 2D subviewport that had
|
|
16
16
|
* not been redrawn since the tab switch, but it has NOT been proven by
|
|
17
17
|
* instrumenting the engine, so this module detects the SYMPTOM (a flat frame)
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Frame-quality probe for engine screenshots (tool/screenshot).
|
|
3
3
|
*
|
|
4
|
-
* WHY THIS EXISTS. In the 2026-09-03 end-to-end run
|
|
5
|
-
*
|
|
4
|
+
* WHY THIS EXISTS. In the 2026-09-03 end-to-end run,
|
|
5
|
+
* `summer_screenshot target:"viewport"` returned an entirely black
|
|
6
6
|
* 1072x1280 JPEG (src/core/capabilities/__fixtures__/frames/01-mcp-viewport-black.jpg)
|
|
7
7
|
* with a caption
|
|
8
8
|
* telling the agent to describe what it saw. It was the first viewport capture
|
|
9
9
|
* after scene mutations had flipped the editor from the 3D to the 2D tab; the
|
|
10
10
|
* same call 67 s later returned real content. Engine side, the ViewportSnapshot
|
|
11
|
-
* op
|
|
11
|
+
* op reads the
|
|
12
12
|
* editor SubViewport's texture with get_texture()->get_image() AS-IS — no forced
|
|
13
13
|
* RenderingServer draw and no blank-frame retry, both of which ScenePreview has
|
|
14
|
-
*
|
|
14
|
+
* because a not-yet-drawn
|
|
15
15
|
* texture reads back black. That is consistent with a 2D subviewport that had
|
|
16
16
|
* not been redrawn since the tab switch, but it has NOT been proven by
|
|
17
17
|
* instrumenting the engine, so this module detects the SYMPTOM (a flat frame)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* grep — ONE implementation of `summer_grep` for both faces
|
|
3
3
|
* (src/mcp/tools/file-tools.ts and tool-dispatch.ts), over the engine's
|
|
4
|
-
* ripgrep-backed Grep op
|
|
4
|
+
* ripgrep-backed Grep op.
|
|
5
5
|
*
|
|
6
6
|
* The engine op returns {file, line, content} per match and parses only
|
|
7
7
|
* ripgrep's "match" events, so its contextLines flag adds nothing to the
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* grep — ONE implementation of `summer_grep` for both faces
|
|
3
3
|
* (src/mcp/tools/file-tools.ts and tool-dispatch.ts), over the engine's
|
|
4
|
-
* ripgrep-backed Grep op
|
|
4
|
+
* ripgrep-backed Grep op.
|
|
5
5
|
*
|
|
6
6
|
* The engine op returns {file, line, content} per match and parses only
|
|
7
7
|
* ripgrep's "match" events, so its contextLines flag adds nothing to the
|
|
@@ -6,19 +6,28 @@ export declare const imageGenerationArgsSchema: z.ZodObject<{
|
|
|
6
6
|
style: z.ZodDefault<z.ZodString>;
|
|
7
7
|
referenceImageUrl: z.ZodOptional<z.ZodString>;
|
|
8
8
|
removeBackground: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
aspectRatio: z.ZodOptional<z.ZodEnum<["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3", "5:4", "4:5", "21:9"]>>;
|
|
10
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
9
12
|
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
10
13
|
}, "strip", z.ZodTypeAny, {
|
|
11
14
|
prompt: string;
|
|
12
15
|
model: string;
|
|
13
16
|
style: string;
|
|
17
|
+
width?: number | undefined;
|
|
18
|
+
height?: number | undefined;
|
|
14
19
|
options?: Record<string, any> | undefined;
|
|
15
20
|
referenceImageUrl?: string | undefined;
|
|
16
21
|
removeBackground?: boolean | undefined;
|
|
22
|
+
aspectRatio?: "1:1" | "16:9" | "9:16" | "4:3" | "3:4" | "3:2" | "2:3" | "5:4" | "4:5" | "21:9" | undefined;
|
|
17
23
|
}, {
|
|
18
24
|
prompt: string;
|
|
25
|
+
width?: number | undefined;
|
|
26
|
+
height?: number | undefined;
|
|
19
27
|
options?: Record<string, any> | undefined;
|
|
20
28
|
model?: string | undefined;
|
|
21
29
|
style?: string | undefined;
|
|
22
30
|
referenceImageUrl?: string | undefined;
|
|
23
31
|
removeBackground?: boolean | undefined;
|
|
32
|
+
aspectRatio?: "1:1" | "16:9" | "9:16" | "4:3" | "3:4" | "3:2" | "2:3" | "5:4" | "4:5" | "21:9" | undefined;
|
|
24
33
|
}>;
|
|
@@ -15,8 +15,26 @@ export const imageGenerationArgsSchema = z.object({
|
|
|
15
15
|
.optional()
|
|
16
16
|
.describe("Source image URL for img2img / edit mode. The prompt describes how to transform this image."),
|
|
17
17
|
removeBackground: z.boolean().optional().describe("Remove the background server-side and return an alpha PNG for sprites, icons, or isolated objects."),
|
|
18
|
+
aspectRatio: z
|
|
19
|
+
.enum(["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3", "5:4", "4:5", "21:9"])
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("Aspect ratio of the output (default 1:1). The result reports the real width and height."),
|
|
22
|
+
width: z
|
|
23
|
+
.number()
|
|
24
|
+
.int()
|
|
25
|
+
.min(64)
|
|
26
|
+
.max(4096)
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Smallest output width in pixels; pass with height. 1920 with height 1080 for store key art, 1080 with 1920 for a tall cover."),
|
|
29
|
+
height: z
|
|
30
|
+
.number()
|
|
31
|
+
.int()
|
|
32
|
+
.min(64)
|
|
33
|
+
.max(4096)
|
|
34
|
+
.optional()
|
|
35
|
+
.describe("Smallest output height in pixels; pass with width."),
|
|
18
36
|
options: z
|
|
19
37
|
.record(z.any())
|
|
20
38
|
.optional()
|
|
21
|
-
.describe("
|
|
39
|
+
.describe("Extra model params (seed, negative_prompt, ...). The result lists any it did not use in ignoredOptions."),
|
|
22
40
|
});
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* advertises `capabilities.navigation` the tool sends the one-table op
|
|
13
13
|
* `Navigate { target, ...args }`; on an engine that predates it the few ids the
|
|
14
14
|
* original ops can serve (scene, node, script, file, the three docks) use those
|
|
15
|
-
* ops and everything else answers `engine_lacks_op`.
|
|
15
|
+
* ops and everything else answers `engine_lacks_op`.
|
|
16
16
|
*
|
|
17
17
|
* Both faces call runOpen(); the CLI (tool-dispatch + `summer open`) and the
|
|
18
18
|
* MCP tool (src/mcp/tools/navigation-tools.ts) only differ in how the engine
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* advertises `capabilities.navigation` the tool sends the one-table op
|
|
13
13
|
* `Navigate { target, ...args }`; on an engine that predates it the few ids the
|
|
14
14
|
* original ops can serve (scene, node, script, file, the three docks) use those
|
|
15
|
-
* ops and everything else answers `engine_lacks_op`.
|
|
15
|
+
* ops and everything else answers `engine_lacks_op`.
|
|
16
16
|
*
|
|
17
17
|
* Both faces call runOpen(); the CLI (tool-dispatch + `summer open`) and the
|
|
18
18
|
* MCP tool (src/mcp/tools/navigation-tools.ts) only differ in how the engine
|
|
@@ -49,7 +49,7 @@ export function renderProductMap() {
|
|
|
49
49
|
lines.push("## Who owns what");
|
|
50
50
|
lines.push("");
|
|
51
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 (
|
|
52
|
+
lines.push("- **Editor rows** are ids of Summer Engine's one navigation table (the `Navigate` op). 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
53
|
lines.push("");
|
|
54
54
|
lines.push("## How to read a row");
|
|
55
55
|
lines.push("");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The product map as the toolkit sees it (
|
|
2
|
+
* The product map as the toolkit sees it (rendered for agents as library/references/product-map).
|
|
3
3
|
*
|
|
4
4
|
* The toolkit does NOT own where things are. Each product does:
|
|
5
5
|
*
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* src/lib/navigation/routes.ts). A vendored snapshot lives at
|
|
8
8
|
* assets/navigation/web-routes.json (refresh: `npm run sync:web-routes`) and
|
|
9
9
|
* every web row below is built from it — nothing hand-written.
|
|
10
|
-
* - Summer Engine owns one table of editor destinations (
|
|
10
|
+
* - Summer Engine owns one table of editor destinations (the Navigate op) and
|
|
11
11
|
* advertises the ids it can open in /api/health capabilities.navigation.
|
|
12
12
|
* The rows below are METADATA for those ids (titles, intents, argument
|
|
13
13
|
* names) plus, for the few ids an older engine can serve through its
|
|
@@ -8,7 +8,7 @@ export type PlacementField = (typeof PLACEMENT_FIELDS)[number];
|
|
|
8
8
|
/** Model-visible budget for compact receipts (the 5 KB tool-result contract). */
|
|
9
9
|
export declare const COMPACT_LIMIT_BYTES: number;
|
|
10
10
|
/** Held-back transform SetProps sent per request; the engine refuses requests
|
|
11
|
-
* over 256 ops
|
|
11
|
+
* over 256 ops. */
|
|
12
12
|
export declare const TRANSFORM_OPS_PER_REQUEST = 200;
|
|
13
13
|
export interface PlacementProp {
|
|
14
14
|
key: PlacementField;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* twins.
|
|
5
5
|
*
|
|
6
6
|
* The engine's InstantiateScene accepts only parent / scene / name /
|
|
7
|
-
* target_size
|
|
7
|
+
* target_size and must travel as its own
|
|
8
8
|
* request (single-only). A placed piece is therefore an InstantiateScene plus
|
|
9
9
|
* SetProps on the node path its receipt reports (meta.nodePath, which already
|
|
10
10
|
* carries any collision rename). The caller writes ONE op; this module expands
|
|
@@ -35,7 +35,7 @@ export const PLACEMENT_FIELDS = ["position", "rotation_degrees", "scale", "trans
|
|
|
35
35
|
/** Model-visible budget for compact receipts (the 5 KB tool-result contract). */
|
|
36
36
|
export const COMPACT_LIMIT_BYTES = 5 * 1024;
|
|
37
37
|
/** Held-back transform SetProps sent per request; the engine refuses requests
|
|
38
|
-
* over 256 ops
|
|
38
|
+
* over 256 ops. */
|
|
39
39
|
export const TRANSFORM_OPS_PER_REQUEST = 200;
|
|
40
40
|
const SUMMARY_TARGET_BYTES = 4600;
|
|
41
41
|
const ERROR_TEXT_LIMIT = 240;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* summer_play tool and the CLI dispatcher.
|
|
6
6
|
*
|
|
7
7
|
* Transport note: the engine's /api/play rung copies only `scene` into the
|
|
8
|
-
* PlayGame op
|
|
8
|
+
* PlayGame op, so a launch that carries a
|
|
9
9
|
* pin is sent as an explicit PlayGame op through /api/ops instead. A launch
|
|
10
10
|
* without any pin stays on /api/play, byte-for-byte the v1 call.
|
|
11
11
|
*
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* summer_play tool and the CLI dispatcher.
|
|
6
6
|
*
|
|
7
7
|
* Transport note: the engine's /api/play rung copies only `scene` into the
|
|
8
|
-
* PlayGame op
|
|
8
|
+
* PlayGame op, so a launch that carries a
|
|
9
9
|
* pin is sent as an explicit PlayGame op through /api/ops instead. A launch
|
|
10
10
|
* without any pin stays on /api/play, byte-for-byte the v1 call.
|
|
11
11
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BuildToolError } from "./summer-bundle.js";
|
|
2
|
-
/**
|
|
2
|
+
/** Store client versions: vMAJOR.MINOR.PATCH[-rN]. */
|
|
3
3
|
export declare const CLIENT_VERSION: RegExp;
|
|
4
4
|
export interface PublishBuildInput {
|
|
5
5
|
gameId?: string;
|
|
@@ -32,7 +32,7 @@ export interface Store {
|
|
|
32
32
|
key?: string;
|
|
33
33
|
}): Promise<T>;
|
|
34
34
|
}
|
|
35
|
-
export declare function storeError(status: number, code: string, message: string | undefined): BuildToolError;
|
|
35
|
+
export declare function storeError(status: number, code: string, message: string | undefined, requestId?: string): BuildToolError;
|
|
36
36
|
export declare function createStore(baseUrl: string, token: string, deps: PublishBuildDependencies): Store;
|
|
37
37
|
/** Whole-file and per-part SHA-256 ("sha256:<hex>") in one pass. */
|
|
38
38
|
export declare function hashParts(path: string, partSize: number): Promise<{
|
|
@@ -57,6 +57,19 @@ export declare function uploadParts(sign: (partNumbers: number[]) => Promise<Gra
|
|
|
57
57
|
partCount: number;
|
|
58
58
|
}, deps: PublishBuildDependencies, parts?: number[]): Promise<void>;
|
|
59
59
|
export declare function normalizeClientVersion(value?: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Before the person confirms, prove the target is real: the game exists for
|
|
62
|
+
* this account, and its store page lists the platforms the export targets.
|
|
63
|
+
*/
|
|
64
|
+
export declare function checkStoreGame(gameId: string, exportTargets: string[], deps: PublishBuildDependencies): Promise<{
|
|
65
|
+
game: {
|
|
66
|
+
gameId: string;
|
|
67
|
+
name: string | null;
|
|
68
|
+
status: string | null;
|
|
69
|
+
targets: string[];
|
|
70
|
+
};
|
|
71
|
+
warnings: string[];
|
|
72
|
+
}>;
|
|
60
73
|
export type PublishBuildResult = Record<string, unknown> & {
|
|
61
74
|
ok: true;
|
|
62
75
|
status: string;
|