summer-engine 3.2.1 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +2 -2
  3. package/.codex-plugin/plugin.json +3 -3
  4. package/.cursor-plugin/plugin.json +2 -2
  5. package/.factory-plugin/plugin.json +2 -2
  6. package/CHANGELOG.md +25 -0
  7. package/README.md +5 -3
  8. package/dist/cli/commands/login.js +12 -0
  9. package/dist/cli/commands/publish.js +2 -1
  10. package/dist/core/auth.js +3 -0
  11. package/dist/core/capabilities/audit/args.d.ts +14 -14
  12. package/dist/core/capabilities/engine-run.d.ts +8 -0
  13. package/dist/core/capabilities/engine-run.js +33 -0
  14. package/dist/core/capabilities/export-game.d.ts +99 -0
  15. package/dist/core/capabilities/export-game.js +369 -0
  16. package/dist/core/capabilities/export-presets.d.ts +50 -0
  17. package/dist/core/capabilities/export-presets.js +177 -0
  18. package/dist/core/capabilities/export-templates.d.ts +118 -0
  19. package/dist/core/capabilities/export-templates.js +291 -0
  20. package/dist/core/capabilities/publish-build.d.ts +64 -0
  21. package/dist/core/capabilities/publish-build.js +448 -0
  22. package/dist/core/capabilities/publish-download.d.ts +37 -0
  23. package/dist/core/capabilities/publish-download.js +168 -0
  24. package/dist/core/capabilities/runtime-control.d.ts +10 -10
  25. package/dist/core/capabilities/summer-bundle.d.ts +49 -0
  26. package/dist/core/capabilities/summer-bundle.js +156 -0
  27. package/dist/core/capabilities/tool-dispatch.js +33 -1
  28. package/dist/core/capabilities/ui-control.d.ts +2 -2
  29. package/dist/core/library-read.d.ts +2 -2
  30. package/dist/core/oauth.d.ts +78 -0
  31. package/dist/core/oauth.js +309 -0
  32. package/dist/core/util/zip-write.d.ts +18 -0
  33. package/dist/core/util/zip-write.js +112 -0
  34. package/dist/core/util/zip.d.ts +22 -0
  35. package/dist/core/util/zip.js +140 -0
  36. package/dist/mcp/hosted-mount.d.ts +96 -0
  37. package/dist/mcp/hosted-mount.js +206 -0
  38. package/dist/mcp/server.d.ts +2 -1
  39. package/dist/mcp/server.js +13 -6
  40. package/dist/mcp/tools/creator-tools.js +54 -1
  41. package/gemini-extension.json +1 -1
  42. package/library/references/mcp-tools-reference/mcp-tools-reference.md +6 -3
  43. package/library/skills/export-and-ship/SKILL.md +2 -0
  44. package/library/skills/multiplayer-publish/SKILL.md +5 -1
  45. package/library/skills/navigate-summer/SKILL.md +1 -1
  46. package/library/tools/creator-publish/resource.yaml +4 -3
  47. package/library/tools/creator-releases/resource.yaml +1 -1
  48. package/library/tools/export-game/resource.yaml +72 -0
  49. package/library/tools/export-templates/resource.yaml +63 -0
  50. package/library/tools/open/resource.yaml +1 -1
  51. package/library/tools/publish-build/resource.yaml +78 -0
  52. package/package.json +1 -1
  53. package/registry/generated/aliases.json +3 -0
  54. package/registry/generated/counts.json +2 -2
  55. package/registry/generated/gemini-extension.json +1 -1
  56. package/registry/generated/index.json +119 -10
  57. package/registry/generated/marketplace.claude.json +2 -2
  58. package/registry/generated/plugin.claude.json +2 -2
  59. package/registry/generated/plugin.codex.json +3 -3
  60. package/registry/generated/plugin.cursor.json +2 -2
  61. package/registry/generated/plugin.factory.json +2 -2
@@ -11,8 +11,8 @@
11
11
  {
12
12
  "name": "summer",
13
13
  "source": "./",
14
- "version": "3.2.1",
15
- "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 101-tool MCP bridge to the local desktop app.",
14
+ "version": "3.3.0",
15
+ "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 104-tool MCP bridge to the local desktop app.",
16
16
  "author": {
17
17
  "name": "Summer Engine",
18
18
  "email": "founders@summerengine.com"
@@ -2,8 +2,8 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "_generated": "GENERATED from integrations/claude — do not edit; npm run generate:registry",
4
4
  "name": "summer",
5
- "version": "3.2.1",
6
- "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 101-tool MCP bridge to the local desktop app.",
5
+ "version": "3.3.0",
6
+ "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 104-tool MCP bridge to the local desktop app.",
7
7
  "author": {
8
8
  "name": "Summer Engine",
9
9
  "email": "founders@summerengine.com",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "_generated": "GENERATED from integrations/codex — do not edit; npm run generate:registry",
3
3
  "name": "summer",
4
- "version": "3.2.1",
5
- "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 101-tool MCP bridge. Build games by talking.",
4
+ "version": "3.3.0",
5
+ "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 104-tool MCP bridge. Build games by talking.",
6
6
  "author": {
7
7
  "name": "Summer Engine",
8
8
  "email": "founders@summerengine.com",
@@ -144,7 +144,7 @@
144
144
  "interface": {
145
145
  "displayName": "Summer",
146
146
  "shortDescription": "Superpowers for AI game dev. Build games by talking.",
147
- "longDescription": "Summer turns Codex into a game-dev studio for Summer Engine. Users make Summer games with the Summer SDK and GDScript. The plugin adds game-dev skills, lifecycle hooks, and a 101-tool MCP bridge for guarded project files, scene editing, asset import, play mode, diagnostics, generation, and creator workflows. Git, shell, and grep stay with the host agent. Summer follows its upstream technical base continuously; version-sensitive work uses the bundled compatibility reference instead of a fixed onboarding version. Session-start orients the session. Pre-commit doctor (opt-in) blocks bad commits.",
147
+ "longDescription": "Summer turns Codex into a game-dev studio for Summer Engine. Users make Summer games with the Summer SDK and GDScript. The plugin adds game-dev skills, lifecycle hooks, and a 104-tool MCP bridge for guarded project files, scene editing, asset import, play mode, diagnostics, generation, and creator workflows. Git, shell, and grep stay with the host agent. Summer follows its upstream technical base continuously; version-sensitive work uses the bundled compatibility reference instead of a fixed onboarding version. Session-start orients the session. Pre-commit doctor (opt-in) blocks bad commits.",
148
148
  "developerName": "Summer Engine",
149
149
  "category": "Coding",
150
150
  "capabilities": [
@@ -3,8 +3,8 @@
3
3
  "_generated": "GENERATED from integrations/cursor — do not edit; npm run generate:registry",
4
4
  "name": "summer",
5
5
  "displayName": "Summer",
6
- "version": "3.2.1",
7
- "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 101-tool MCP bridge to the local desktop app.",
6
+ "version": "3.3.0",
7
+ "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 104-tool MCP bridge to the local desktop app.",
8
8
  "author": {
9
9
  "name": "Summer Engine",
10
10
  "email": "founders@summerengine.com"
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "_generated": "GENERATED from integrations/factory — do not edit; npm run generate:registry",
3
3
  "name": "summer",
4
- "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 101-tool MCP bridge to the local desktop app.",
5
- "version": "3.2.1",
4
+ "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 104-tool MCP bridge to the local desktop app.",
5
+ "version": "3.3.0",
6
6
  "author": {
7
7
  "name": "Summer Engine",
8
8
  "email": "founders@summerengine.com",
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  All notable changes to summer-engine will be documented here. Following [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [Semantic Versioning](https://semver.org/).
4
4
 
5
+ ## [3.3.0] - 2026-10-09
6
+
7
+ Your agent can now take a game from the editor to the Summer Games store:
8
+
9
+ - Export for every platform the store takes: iPhone, Android, Mac, Windows and the web, as a summer.games bundle or as a store download.
10
+ - Install the export templates for your engine version with one tool call. Each file is checked before it is installed.
11
+ - Sign in to the store from the terminal with `summer login --store`.
12
+ - Upload a build and publish it with `summer_publish_build`, after you confirm the game, file and version.
13
+ - Use the Studio, board and store tools (projects, store page, art, build upload, send for the owner's approval, the board, Grow) through the one Summer Engine MCP. After the store sign-in, the local MCP loads the hosted tools, prompts and resources next to the engine tools.
14
+
15
+ ### Added
16
+ - `summer_export_game` (preview): exports the game for summer.games with the installed Summer Engine, headless and without a window (`--headless --path <project> --export-release "summer.games" <out>.zip`), and returns the `.zip` path, sha256, size and the bundle manifest (main scene, target platforms, hosted or not). The default output is `<project>/.summer/exports/`, ignored by the editor and by git. No running editor and no export template are needed.
17
+ - `summer_publish_build` (preview): uploads that `.zip` to the creator's game through the creator store routes Studio's export upload uses: declare the export, upload 64 MiB parts straight from disk to presigned URLs, seal, wait until Summer makes the Build, name its client pack, and with `publish: true` approve it. The first call returns the exact game, file, digest, size and version for the user to confirm. A retry with the same file and version continues the same upload. Defaults to the last export.
18
+ - `summer login --store`: browser sign-in to the Summer store (OAuth 2.1 with PKCE and a loopback redirect) against the hosted MCP's authorization server. The CLI is one public client: it listens on a fixed loopback port (47615, 47616 or 47617), registers its client once per machine for exactly those redirects (`~/.summer/oauth-client`) and reuses it on later logins and refreshes; `--store --force` registers a new one. The token and its refresh token live in `~/.summer/oauth-token`; `summer logout` clears it.
19
+ - `summer_export_game` `targets` and `format`: export in the exact file the Summer Games store takes per platform. `format: "bundle"` (default) makes the summer.games bundle for `ios`, `android`, `macos`, `windows` through a named `summer.games <targets>` preset written to `export_presets.cfg` (only its platform options are ever rewritten). `format: "download"` with one target makes the store's web build (`web`: an HTML5 `.zip` with `index.html` at the root, on Summer's WebGPU/JSPI Forward+ template, checked against the store's size limits; Compatibility-renderer projects are refused) or a desktop download (`macos`: ad hoc signed `.app` zip for `macos-universal`; `windows`: `.exe` with its pack embedded, zipped for `windows-x64`). Missing templates, platforms the installed engine cannot export and platforms the store will refuse come back as clear errors and warnings.
20
+ - `summer_export_templates` (preview): `list` and `install` export templates from Summer's CDN (`<base>/<summerVersion>/manifest.json`, schema `summer.export-templates.v1`; `SUMMER_TEMPLATES_URL` overrides the base) into the folder the engine reads, `<data>/Godot/export_templates/<FULL_CONFIG>/`, each file sha256-checked before it is installed.
21
+ - One Summer Engine MCP: with a store sign-in (`summer login --store`), the local MCP mounts the hosted Summer Engine MCP's tools, prompts and resources (mcp.summerengine.com: projects, store page, art, build upload, `summer_store_submit` for the owner's approval, the board, Grow, the publish-your-game, store-listing and store-art skills, the docs pointer) under their own names and forwards each call with that sign-in. A name the local MCP already has stays local. The mount runs after the server is up and never delays the engine tools; without a sign-in, `summer_store_tools` says how to sign in and mounts on the next call.
22
+ - `summer_publish_build` uploads web builds and desktop downloads (`summer_export_game` `format: "download"`) as the game's store version for `web`, `macos-universal`, `windows-x64` or `linux-x64` (the store's second build path): create, upload parts from disk (16 MiB for web, 64 MiB for native), complete, wait until checked. The platform comes from the last export or `platform`. A retry continues an unfinished upload of the same file and version and skips the parts storage has. Web zips are checked first (`index.html` at the root, at most 2000 files, 500 MiB). On a game that is already live the store leaves finishing the upload to the owner, and the tool says so.
23
+
24
+ ### Fixed
25
+ - `summer_publish_build` accepted only iPhone for a game without a server; the store also takes Android (summer-platform `StandaloneTargets`). It now accepts `ios` and `android` and declares exactly the bundle's platforms.
26
+
27
+ ### Deprecated
28
+ - `summer_creator_publish` and `summer publish` (a `.pck` to the legacy Summercraft creator API with a separate `sc_` token). Use `summer_export_game`, then `summer_publish_build`.
29
+
5
30
  ## [3.2.1] - 2026-10-07
6
31
 
7
32
  ### Changed
package/README.md CHANGED
@@ -226,7 +226,7 @@ Only skip brainstorm if the user explicitly said "skip brainstorm" or "just buil
226
226
  |---|---|---|
227
227
  | **Create** | Available | Scaffold from a pinned template, build scenes and scripts through MCP, generate 2D/3D/audio/video assets, guided by the library. |
228
228
  | **Test** | Available | The verification ladder: compile checks, screenshots, live play with debugger reads, and input-driven probes (`RunVerification`) that press real keys and assert on real frames. |
229
- | **Publish** | Available (creator CLI) | `summer publish` streams an already-exported Summer `.pck` to the Summer Platform for review — explicit, confirmed, immutable releases with real history (`summer releases`). Nothing is ever submitted silently. |
229
+ | **Publish** | Preview | `summer_export_game` exports the summer.games `.zip` with the installed engine (headless); `summer_publish_build` uploads it to your game's store listing after you confirm the exact game, file and version (sign in once with `summer login --store`). The older `summer publish` (`.pck` to the legacy creator API) is deprecated. Nothing is ever submitted silently. |
230
230
  | **Grow** | Direction | Store distribution, analytics, retention and live-ops tooling arrive as new library entries (the structure is built for it — lifecycle is metadata, not architecture). Not promised by this package today. |
231
231
 
232
232
  ## What's in this repo
@@ -321,6 +321,7 @@ We tell you before we touch your disk.
321
321
  | Summer Engine app | ~1 GB (engine + bundled Git/runtime tools) | `npx -y summer-engine@latest install` | Summer's signed releases |
322
322
  | Auth token | ~1 KB | `npx -y summer-engine@latest login` | Browser to `~/.summer/auth-token` |
323
323
  | Creator token | ~50 bytes | only when you run `summer login --creator` and mint one | One-time browser value to `~/.summer/creator-token`; never replaces the auth token |
324
+ | Store sign-in | ~2 KB | only when you run `summer login --store` | Browser OAuth (PKCE, loopback port 47615-47617) to `~/.summer/oauth-token` with its refresh token, plus this machine's public client id in `~/.summer/oauth-client`; never replaces the auth token |
324
325
  | Skill files | small, bundled | in the npm package | no extra network call |
325
326
  | Generated assets (3D / image / audio / video) | varies | only on explicit `summer_generate_*` calls when that provider route is enabled for the account | Summer Engine Studio |
326
327
  | URL imports | varies | only on explicit `summer_import_from_url` calls | the URL you provide |
@@ -348,10 +349,11 @@ matchmaking are not promised by this package.
348
349
  |---|---|
349
350
  | `summer install [--yes]` | Download Summer Engine. Prints URL and size first; never replaces an installed engine without confirmation. |
350
351
  | `summer login` | Browser-based core Summer sign-in. |
351
- | `summer login --creator` | Open the Summer Platform token settings and securely connect a separate publish-scoped creator token. |
352
+ | `summer login --store` | Browser sign-in to the Summer store so agents can upload builds (`summer_publish_build`). |
353
+ | `summer login --creator` | Deprecated with `summer publish`: connect a separate publish-scoped creator token for the legacy creator API. |
352
354
  | `summer logout` | Clear auth tokens. |
353
355
  | `summer config [get\|set\|unset]` | Read or update the shared non-secret `~/.summer/config.json`. |
354
- | `summer publish [project] --artifact <game.pck> --version <value> [--confirm]` | Compute and show the exact immutable target; after approval, stream it through prepare → write-once PUT → finalize. |
356
+ | `summer publish [project] --artifact <game.pck> --version <value> [--confirm]` | Deprecated: use `summer tool export-game`, then `summer tool publish-build`. Streams a `.pck` to the legacy creator API through prepare → write-once PUT → finalize. |
355
357
  | `summer releases [--cursor <value>]` | List real creator-owned release history. |
356
358
  | `summer status` | Engine state, port, auth. |
357
359
  | `summer doctor` | Diagnose Node, login, engine, project memory, MCP. |
@@ -3,6 +3,7 @@ import { randomUUID } from "crypto";
3
3
  import open from "open";
4
4
  import { getAuthToken, getCreatorToken, saveCreatorToken, saveLoginSession, } from "../../core/auth.js";
5
5
  import { getCreatorApiUrl, resolveGatewayUrl } from "../../core/config.js";
6
+ import { readStoredOAuthToken, runStoreLogin } from "../../core/oauth.js";
6
7
  const POLL_INTERVAL_MS = 2000;
7
8
  // One generous window on ONE session id. First-time users may need to create an
8
9
  // account and confirm an email before they can approve the CLI. The gateway
@@ -14,8 +15,19 @@ const HEARTBEAT_MS = 30000;
14
15
  export const loginCommand = new Command("login")
15
16
  .description("Sign in to Summer Engine via your browser")
16
17
  .option("--creator", "Connect a separately scoped Summercraft creator token for publishing")
18
+ .option("--store", "Sign in to the Summer store so agents can upload builds (summer_publish_build)")
17
19
  .option("--force", "Force re-authentication even if already logged in")
18
20
  .action(async (opts) => {
21
+ if (opts.store) {
22
+ if ((await readStoredOAuthToken()) && !opts.force) {
23
+ console.log("Already signed in to the Summer store. Use --store --force to sign in again.");
24
+ return;
25
+ }
26
+ // --force also registers a new client, the way back if this machine's was removed.
27
+ await runStoreLogin({ fetch, now: Date.now, openUrl: open, log: console.log, newClient: Boolean(opts.force) });
28
+ console.log("Signed in to the Summer store. Your core Summer login was not changed.");
29
+ return;
30
+ }
19
31
  if (opts.creator) {
20
32
  const existingCreator = await getCreatorToken();
21
33
  if (existingCreator && !opts.force) {
@@ -1,7 +1,7 @@
1
1
  import { Command } from "commander";
2
2
  import { publishCreator } from "../../core/capabilities/creator.js";
3
3
  export const publishCommand = new Command("publish")
4
- .description("Publish a confirmed creator release")
4
+ .description("Deprecated: publish a .pck to the legacy creator API (use `summer tool export-game`, then `summer tool publish-build`)")
5
5
  .argument("[project]", "Project root. Defaults to the current directory.")
6
6
  .requiredOption("--artifact <path>", "Exact exported Summer .pck artifact")
7
7
  .requiredOption("--version <value>", "Immutable release version")
@@ -11,6 +11,7 @@ export const publishCommand = new Command("publish")
11
11
  .option("--notes <text>", "Release notes")
12
12
  .option("--confirm", "Confirm the exact project and channel after reviewing them")
13
13
  .action(async (project, opts) => {
14
+ console.error("summer publish is deprecated: run `summer tool export-game`, then `summer tool publish-build`, to upload the summer.games .zip to your game.");
14
15
  const result = await publishCreator({
15
16
  project,
16
17
  ...opts,
package/dist/core/auth.js CHANGED
@@ -6,6 +6,8 @@ const LEGACY_CLOUD_TOKEN_FILE = "cloud-token";
6
6
  const CREATOR_TOKEN_FILE = "creator-token";
7
7
  const USER_FILE = "user.json";
8
8
  const METADATA_FILE = "credential-metadata.json";
9
+ /** The Summer store OAuth token (core/oauth.ts OAUTH_TOKEN_FILE). */
10
+ const STORE_OAUTH_TOKEN_FILE = "oauth-token";
9
11
  function decodeJwtMetadata(token, explicitScopes = []) {
10
12
  const payload = decodeJwtPayload(token);
11
13
  const aud = payload.aud;
@@ -194,6 +196,7 @@ export async function clearAuthCredentials() {
194
196
  AUTH_TOKEN_FILE,
195
197
  LEGACY_CLOUD_TOKEN_FILE,
196
198
  CREATOR_TOKEN_FILE,
199
+ STORE_OAUTH_TOKEN_FILE,
197
200
  USER_FILE,
198
201
  METADATA_FILE,
199
202
  ]) {
@@ -34,11 +34,11 @@ export declare const sceneAuditShape: {
34
34
  key: z.ZodString;
35
35
  reason: z.ZodString;
36
36
  }, "strict", z.ZodTypeAny, {
37
- reason: string;
38
37
  key: string;
39
- }, {
40
38
  reason: string;
39
+ }, {
41
40
  key: string;
41
+ reason: string;
42
42
  }>, "many">>;
43
43
  show_accepted: z.ZodOptional<z.ZodBoolean>;
44
44
  render: z.ZodOptional<z.ZodEnum<["sheet", "none"]>>;
@@ -55,38 +55,38 @@ export declare const sceneAuditArgsSchema: z.ZodObject<{
55
55
  key: z.ZodString;
56
56
  reason: z.ZodString;
57
57
  }, "strict", z.ZodTypeAny, {
58
- reason: string;
59
58
  key: string;
60
- }, {
61
59
  reason: string;
60
+ }, {
62
61
  key: string;
62
+ reason: string;
63
63
  }>, "many">>;
64
64
  show_accepted: z.ZodOptional<z.ZodBoolean>;
65
65
  render: z.ZodOptional<z.ZodEnum<["sheet", "none"]>>;
66
66
  }, "strict", z.ZodTypeAny, {
67
- limit?: number | undefined;
68
- root?: string | undefined;
69
- scenePath?: string | undefined;
70
67
  accept?: {
71
- reason: string;
72
68
  key: string;
69
+ reason: string;
73
70
  }[] | undefined;
71
+ limit?: number | undefined;
72
+ root?: string | undefined;
73
+ scenePath?: string | undefined;
74
74
  render?: "none" | "sheet" | undefined;
75
- checks?: ("through_hole" | "floor_gap" | "floating" | "sunken" | "interpenetration" | "exposed_edge" | "open_fixture_end" | "orientation" | "uv_stretch" | "duplicate" | "z_fight" | "depth_step" | "lights" | "transform" | "resource")[] | undefined;
75
+ checks?: ("resource" | "through_hole" | "floor_gap" | "floating" | "sunken" | "interpenetration" | "exposed_edge" | "open_fixture_end" | "orientation" | "uv_stretch" | "duplicate" | "z_fight" | "depth_step" | "lights" | "transform")[] | undefined;
76
76
  min_severity?: "error" | "warn" | "look" | undefined;
77
77
  offset?: number | undefined;
78
78
  budget_ms?: number | undefined;
79
79
  show_accepted?: boolean | undefined;
80
80
  }, {
81
- limit?: number | undefined;
82
- root?: string | undefined;
83
- scenePath?: string | undefined;
84
81
  accept?: {
85
- reason: string;
86
82
  key: string;
83
+ reason: string;
87
84
  }[] | undefined;
85
+ limit?: number | undefined;
86
+ root?: string | undefined;
87
+ scenePath?: string | undefined;
88
88
  render?: "none" | "sheet" | undefined;
89
- checks?: ("through_hole" | "floor_gap" | "floating" | "sunken" | "interpenetration" | "exposed_edge" | "open_fixture_end" | "orientation" | "uv_stretch" | "duplicate" | "z_fight" | "depth_step" | "lights" | "transform" | "resource")[] | undefined;
89
+ checks?: ("resource" | "through_hole" | "floor_gap" | "floating" | "sunken" | "interpenetration" | "exposed_edge" | "open_fixture_end" | "orientation" | "uv_stretch" | "duplicate" | "z_fight" | "depth_step" | "lights" | "transform")[] | undefined;
90
90
  min_severity?: "error" | "warn" | "look" | undefined;
91
91
  offset?: number | undefined;
92
92
  budget_ms?: number | undefined;
@@ -0,0 +1,8 @@
1
+ export interface EngineRun {
2
+ code: number | null;
3
+ signal: NodeJS.Signals | null;
4
+ timedOut: boolean;
5
+ output: string;
6
+ }
7
+ /** Spawn the engine (argv only, no shell), keep the last output, kill on timeout. */
8
+ export declare function runEngine(binary: string, args: string[], timeoutMs: number): Promise<EngineRun>;
@@ -0,0 +1,33 @@
1
+ import { spawn as nodeSpawn } from "node:child_process";
2
+ /** One headless engine process: argv only (no shell), the last output kept, killed on timeout. */
3
+ const OUTPUT_TAIL_BYTES = 8 * 1024;
4
+ const KILL_GRACE_MS = 5_000;
5
+ /** Spawn the engine (argv only, no shell), keep the last output, kill on timeout. */
6
+ export function runEngine(binary, args, timeoutMs) {
7
+ return new Promise((resolvePromise, reject) => {
8
+ const child = nodeSpawn(binary, args, { stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
9
+ let output = "";
10
+ let timedOut = false;
11
+ const keep = (chunk) => {
12
+ output = (output + chunk.toString("utf8")).slice(-OUTPUT_TAIL_BYTES);
13
+ };
14
+ child.stdout?.on("data", keep);
15
+ child.stderr?.on("data", keep);
16
+ let killTimer;
17
+ const timer = setTimeout(() => {
18
+ timedOut = true;
19
+ child.kill("SIGTERM");
20
+ killTimer = setTimeout(() => child.kill("SIGKILL"), KILL_GRACE_MS);
21
+ }, timeoutMs);
22
+ child.on("error", (error) => {
23
+ clearTimeout(timer);
24
+ clearTimeout(killTimer);
25
+ reject(error);
26
+ });
27
+ child.on("close", (code, signal) => {
28
+ clearTimeout(timer);
29
+ clearTimeout(killTimer);
30
+ resolvePromise({ code, signal, timedOut, output });
31
+ });
32
+ });
33
+ }
@@ -0,0 +1,99 @@
1
+ import { runEngine, type EngineRun } from "./engine-run.js";
2
+ import { SUMMER_GAMES_PRESET, type EnsuredPreset, type StoreTarget } from "./export-presets.js";
3
+ import { type TemplatesDependencies } from "./export-templates.js";
4
+ import { type SummerBundle } from "./summer-bundle.js";
5
+ export { runEngine, SUMMER_GAMES_PRESET, type EngineRun };
6
+ /**
7
+ * summer_export_game: run the installed Summer Engine headless and return the
8
+ * file the Summer Games store takes for the chosen targets.
9
+ *
10
+ * <engine> --headless --path <project> --export-release "<preset>" <out>
11
+ *
12
+ * format "bundle" (default): the summer.bundle.v1 .zip for build-publications
13
+ * (summer_publish_build). Summer runs its client.pck on its own templates in
14
+ * the Summer Games apps, so no template and no signing. Without targets the
15
+ * engine's in-memory "summer.games" preset is used as is (every platform
16
+ * summer.build.json declares); with targets a named summer.games preset ticks
17
+ * exactly those (export-presets.ts).
18
+ *
19
+ * format "download" (one target: web, macos or windows): what the store's
20
+ * versions intake takes. web is a static HTML5 .zip (index.html at the root)
21
+ * built on Summer's WebGPU/JSPI Forward+ template; macos is the .app zipped
22
+ * (macos-universal, ad hoc signed, as the store asks for no signing); windows
23
+ * is the .exe with its pack embedded, zipped (windows-x64). These need the
24
+ * matching export template (summer_export_templates).
25
+ *
26
+ * --headless opens no window.
27
+ */
28
+ export declare const LAST_EXPORT_FILE = "last-export.json";
29
+ export type ExportFormat = "bundle" | "download";
30
+ export interface ExportGameInput {
31
+ /** Project root (has project.godot). Defaults to the MCP's --project, then the working directory. */
32
+ project?: string;
33
+ /** Output .zip path. Defaults to <project>/.summer/exports/<name>-<time>.zip. */
34
+ out?: string;
35
+ /** Export with debug enabled (--export-debug). */
36
+ debug?: boolean;
37
+ /** Export preset name; the engine's own is "summer.games". Bundle format without targets only. */
38
+ preset?: string;
39
+ /** Store platforms: macos, windows, ios, android, web. */
40
+ targets?: string[];
41
+ /** "bundle" (store build for the Summer apps) or "download" (web build, native download). Default: bundle; web is always download. */
42
+ format?: string;
43
+ timeoutMs?: number;
44
+ }
45
+ export interface ExportGameResult {
46
+ ok: true;
47
+ format: ExportFormat;
48
+ path: string;
49
+ sha256: string;
50
+ sizeBytes: number;
51
+ project: string;
52
+ preset: string;
53
+ /** The targets asked for, when any were. */
54
+ targets?: StoreTarget[];
55
+ /** What happened to export_presets.cfg for the preset this export used. */
56
+ presetChange?: EnsuredPreset["change"];
57
+ debug: boolean;
58
+ engine: string;
59
+ durationMs: number;
60
+ /** Bundle format: the bundle manifest. */
61
+ bundle?: Omit<SummerBundle, "hostedBuild" | "files"> & {
62
+ fileCount: number;
63
+ };
64
+ /** Download format: the store versions platform id (web, macos-universal, windows-x64). */
65
+ storePlatform?: string;
66
+ /** Download format: files in the zip. */
67
+ fileCount?: number;
68
+ /** Download format: the project icon the export used, or null. */
69
+ icon?: string | null;
70
+ /** Download format: what signing the file carries. */
71
+ signing?: string;
72
+ /** Things the store will still refuse or warn about, in plain words. */
73
+ warnings?: string[];
74
+ next: string;
75
+ }
76
+ export interface LastExport {
77
+ path: string;
78
+ project: string;
79
+ sha256: string;
80
+ sizeBytes: number;
81
+ exportedAt: string;
82
+ /** Download exports: the store versions platform the file is for (summer_publish_build reads it). */
83
+ storePlatform?: string;
84
+ }
85
+ export interface ExportGameDependencies {
86
+ findBinary: () => string | null;
87
+ run: (binary: string, args: string[], timeoutMs: number) => Promise<EngineRun>;
88
+ now: () => Date;
89
+ /** Template lookup for download exports (overridable in tests). */
90
+ templates?: Partial<TemplatesDependencies>;
91
+ }
92
+ export declare function resolveExportProject(project?: string): string;
93
+ /** One value from project.godot ([section] key=value), unquoted. */
94
+ export declare function projectSetting(project: string, section: string, key: string): string | null;
95
+ /** Lowercase ascii slug for file names and the macOS bundle id. */
96
+ export declare function slugify(name: string): string;
97
+ export declare function exportGame(input: ExportGameInput, overrides?: Partial<ExportGameDependencies>): Promise<ExportGameResult>;
98
+ /** The file the last summer_export_game wrote (bundle or download), when it is still on disk. */
99
+ export declare function readLastExport(): Promise<LastExport | null>;