summer-engine 3.2.1 → 3.4.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 (97) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +4 -2
  3. package/.codex-plugin/plugin.json +5 -3
  4. package/.cursor-plugin/plugin.json +4 -2
  5. package/.factory-plugin/plugin.json +4 -2
  6. package/CHANGELOG.md +61 -0
  7. package/README.md +7 -4
  8. package/assets/api-docs.json.gz +0 -0
  9. package/dist/cli/commands/install.d.ts +10 -0
  10. package/dist/cli/commands/install.js +55 -10
  11. package/dist/cli/commands/login.js +12 -0
  12. package/dist/cli/commands/publish.js +2 -1
  13. package/dist/cli/commands/tool.d.ts +7 -0
  14. package/dist/cli/commands/tool.js +36 -1
  15. package/dist/core/auth.js +3 -0
  16. package/dist/core/capabilities/audit/args.d.ts +14 -14
  17. package/dist/core/capabilities/capture-gameplay.d.ts +69 -0
  18. package/dist/core/capabilities/capture-gameplay.js +283 -0
  19. package/dist/core/capabilities/creator.js +1 -1
  20. package/dist/core/capabilities/doctor.d.ts +9 -1
  21. package/dist/core/capabilities/doctor.js +47 -4
  22. package/dist/core/capabilities/engine-run.d.ts +12 -0
  23. package/dist/core/capabilities/engine-run.js +61 -0
  24. package/dist/core/capabilities/export-engine-version.d.ts +15 -0
  25. package/dist/core/capabilities/export-engine-version.js +24 -0
  26. package/dist/core/capabilities/export-game.d.ts +107 -0
  27. package/dist/core/capabilities/export-game.js +445 -0
  28. package/dist/core/capabilities/export-presets.d.ts +50 -0
  29. package/dist/core/capabilities/export-presets.js +177 -0
  30. package/dist/core/capabilities/export-templates.d.ts +118 -0
  31. package/dist/core/capabilities/export-templates.js +291 -0
  32. package/dist/core/capabilities/image-generation.d.ts +9 -0
  33. package/dist/core/capabilities/image-generation.js +19 -1
  34. package/dist/core/capabilities/publish-build.d.ts +77 -0
  35. package/dist/core/capabilities/publish-build.js +500 -0
  36. package/dist/core/capabilities/publish-download.d.ts +37 -0
  37. package/dist/core/capabilities/publish-download.js +168 -0
  38. package/dist/core/capabilities/runtime-control.d.ts +10 -10
  39. package/dist/core/capabilities/summer-bundle.d.ts +49 -0
  40. package/dist/core/capabilities/summer-bundle.js +156 -0
  41. package/dist/core/capabilities/tool-dispatch.js +43 -1
  42. package/dist/core/capabilities/ui-control.d.ts +2 -2
  43. package/dist/core/config.js +2 -2
  44. package/dist/core/engine-install.d.ts +16 -0
  45. package/dist/core/engine-install.js +32 -2
  46. package/dist/core/hosted-mcp.d.ts +115 -0
  47. package/dist/core/hosted-mcp.js +164 -0
  48. package/dist/core/launch-posture.d.ts +3 -0
  49. package/dist/core/launch-posture.js +15 -2
  50. package/dist/core/library-read.d.ts +2 -2
  51. package/dist/core/oauth.d.ts +78 -0
  52. package/dist/core/oauth.js +309 -0
  53. package/dist/core/util/zip-write.d.ts +18 -0
  54. package/dist/core/util/zip-write.js +112 -0
  55. package/dist/core/util/zip.d.ts +22 -0
  56. package/dist/core/util/zip.js +140 -0
  57. package/dist/mcp/hosted-mount.d.ts +50 -0
  58. package/dist/mcp/hosted-mount.js +200 -0
  59. package/dist/mcp/server.d.ts +2 -1
  60. package/dist/mcp/server.js +14 -6
  61. package/dist/mcp/tools/creator-tools.js +64 -1
  62. package/dist/mcp/tools/generate-tools.js +12 -2
  63. package/gemini-extension.json +3 -1
  64. package/library/references/mcp-tools-reference/mcp-tools-reference.md +7 -3
  65. package/library/skills/README.md +6 -4
  66. package/library/skills/bounded-engine-runs/SKILL.md +96 -0
  67. package/library/skills/bounded-engine-runs/resource.yaml +29 -0
  68. package/library/skills/compatibility-renderer-traps/SKILL.md +78 -0
  69. package/library/skills/compatibility-renderer-traps/resource.yaml +28 -0
  70. package/library/skills/concept-art/SKILL.md +2 -2
  71. package/library/skills/export-and-ship/SKILL.md +4 -0
  72. package/library/skills/headless-scripting/resource.yaml +1 -0
  73. package/library/skills/in-game-purchases/SKILL.md +123 -118
  74. package/library/skills/in-game-purchases/resource.yaml +2 -2
  75. package/library/skills/multiplayer-publish/SKILL.md +5 -1
  76. package/library/skills/navigate-summer/SKILL.md +1 -1
  77. package/library/skills/web-compatibility-look/resource.yaml +1 -0
  78. package/library/tools/capture-gameplay/resource.yaml +73 -0
  79. package/library/tools/creator-publish/resource.yaml +4 -3
  80. package/library/tools/creator-releases/resource.yaml +1 -1
  81. package/library/tools/export-game/resource.yaml +72 -0
  82. package/library/tools/export-templates/resource.yaml +63 -0
  83. package/library/tools/generate-image/resource.yaml +15 -1
  84. package/library/tools/open/resource.yaml +1 -1
  85. package/library/tools/publish-build/resource.yaml +78 -0
  86. package/package.json +1 -1
  87. package/registry/generated/aliases.json +4 -0
  88. package/registry/generated/counts.json +3 -3
  89. package/registry/generated/gemini-extension.json +3 -1
  90. package/registry/generated/index.json +241 -19
  91. package/registry/generated/marketplace.claude.json +2 -2
  92. package/registry/generated/plugin.claude.json +4 -2
  93. package/registry/generated/plugin.codex.json +5 -3
  94. package/registry/generated/plugin.cursor.json +4 -2
  95. package/registry/generated/plugin.factory.json +4 -2
  96. package/registry/generated/skills-index.md +6 -4
  97. package/registry/generated/skills-registry.json +28 -1
@@ -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.4.0",
15
+ "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 105-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.4.0",
6
+ "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 105-tool MCP bridge to the local desktop app.",
7
7
  "author": {
8
8
  "name": "Summer Engine",
9
9
  "email": "founders@summerengine.com",
@@ -38,6 +38,7 @@
38
38
  "./library/skills/asset-strategy/",
39
39
  "./library/skills/audio-direction/",
40
40
  "./library/skills/auto-fire-targeting/",
41
+ "./library/skills/bounded-engine-runs/",
41
42
  "./library/skills/brainstorm-game/",
42
43
  "./library/skills/brainstorming/",
43
44
  "./library/skills/browse-templates/",
@@ -49,6 +50,7 @@
49
50
  "./library/skills/character-portrait/",
50
51
  "./library/skills/cinematic-cutscene/",
51
52
  "./library/skills/combat-basics/",
53
+ "./library/skills/compatibility-renderer-traps/",
52
54
  "./library/skills/concept-art/",
53
55
  "./library/skills/create-asset-sheet/",
54
56
  "./library/skills/debug/",
@@ -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.4.0",
5
+ "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 105-tool MCP bridge. Build games by talking.",
6
6
  "author": {
7
7
  "name": "Summer Engine",
8
8
  "email": "founders@summerengine.com",
@@ -33,6 +33,7 @@
33
33
  "./library/skills/asset-strategy/",
34
34
  "./library/skills/audio-direction/",
35
35
  "./library/skills/auto-fire-targeting/",
36
+ "./library/skills/bounded-engine-runs/",
36
37
  "./library/skills/brainstorm-game/",
37
38
  "./library/skills/brainstorming/",
38
39
  "./library/skills/browse-templates/",
@@ -44,6 +45,7 @@
44
45
  "./library/skills/character-portrait/",
45
46
  "./library/skills/cinematic-cutscene/",
46
47
  "./library/skills/combat-basics/",
48
+ "./library/skills/compatibility-renderer-traps/",
47
49
  "./library/skills/concept-art/",
48
50
  "./library/skills/create-asset-sheet/",
49
51
  "./library/skills/debug/",
@@ -144,7 +146,7 @@
144
146
  "interface": {
145
147
  "displayName": "Summer",
146
148
  "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.",
149
+ "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 105-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
150
  "developerName": "Summer Engine",
149
151
  "category": "Coding",
150
152
  "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.4.0",
7
+ "description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 105-tool MCP bridge to the local desktop app.",
8
8
  "author": {
9
9
  "name": "Summer Engine",
10
10
  "email": "founders@summerengine.com"
@@ -45,6 +45,7 @@
45
45
  "./library/skills/asset-strategy/",
46
46
  "./library/skills/audio-direction/",
47
47
  "./library/skills/auto-fire-targeting/",
48
+ "./library/skills/bounded-engine-runs/",
48
49
  "./library/skills/brainstorm-game/",
49
50
  "./library/skills/brainstorming/",
50
51
  "./library/skills/browse-templates/",
@@ -56,6 +57,7 @@
56
57
  "./library/skills/character-portrait/",
57
58
  "./library/skills/cinematic-cutscene/",
58
59
  "./library/skills/combat-basics/",
60
+ "./library/skills/compatibility-renderer-traps/",
59
61
  "./library/skills/concept-art/",
60
62
  "./library/skills/create-asset-sheet/",
61
63
  "./library/skills/debug/",
@@ -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 105-tool MCP bridge to the local desktop app.",
5
+ "version": "3.4.0",
6
6
  "author": {
7
7
  "name": "Summer Engine",
8
8
  "email": "founders@summerengine.com",
@@ -30,6 +30,7 @@
30
30
  "./library/skills/asset-strategy/",
31
31
  "./library/skills/audio-direction/",
32
32
  "./library/skills/auto-fire-targeting/",
33
+ "./library/skills/bounded-engine-runs/",
33
34
  "./library/skills/brainstorm-game/",
34
35
  "./library/skills/brainstorming/",
35
36
  "./library/skills/browse-templates/",
@@ -41,6 +42,7 @@
41
42
  "./library/skills/character-portrait/",
42
43
  "./library/skills/cinematic-cutscene/",
43
44
  "./library/skills/combat-basics/",
45
+ "./library/skills/compatibility-renderer-traps/",
44
46
  "./library/skills/concept-art/",
45
47
  "./library/skills/create-asset-sheet/",
46
48
  "./library/skills/debug/",
package/CHANGELOG.md CHANGED
@@ -2,6 +2,67 @@
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.4.0] - 2026-10-09
6
+
7
+ Publishing a game from your agent now works end to end, with fewer surprises:
8
+
9
+ - Take store screenshots of real gameplay without opening the editor (`summer_capture_gameplay`).
10
+ - Make store-size art: ask `summer_generate_image` for an aspect ratio or a size.
11
+ - See the store tools as soon as your agent connects, and use them from the terminal (`summer tool`). `summer doctor` checks that the store accepts your sign-in.
12
+ - An export tells you first when your Summer Engine is too old, shows the engine's real error when it fails, and lists the project files it changed.
13
+ - A publish preview checks that the game exists before it asks you to confirm.
14
+ - `summer install --path` installs Summer.app into the folder you name, and every command uses that engine.
15
+ - New skills for running the engine safely from an agent and for games that also run on the Compatibility renderer.
16
+
17
+ ### Added
18
+ - `summer_capture_gameplay` (CLI `summer tool capture-gameplay`): saves real gameplay frames (HUD included) without a running editor. It starts the game in the engine's offscreen verify instance (`--summer-verify`, real renderer, window offscreen, no focus, never `--headless`) at `resolution` (default `1920x1080`), waits `waitSeconds`, and saves `frames` PNGs to `<project>/.summer/captures/<time>/`. It imports a never-opened project first, passes `--summer-no-api`, and returns each frame's path with its real width and height. It warns when the stretch settings render another size.
19
+ - `summer_generate_image` `aspectRatio` (1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 5:4, 4:5, 21:9) and `width` + `height` (64 to 4096), sent to the image route as top-level fields. The server picks a model that reaches the size, or refuses a named model that cannot, before any spend. The result reports the real size and the model. The `options` description now says what the server really does. Until the server side ships, the new fields are accepted and ignored.
20
+ - `summer tool` runs a name that is not a local tool on the hosted Summer Engine MCP with the store sign-in (`summer tool summer_store_list_games`). `summer tool --list` lists the hosted tools after the local ones, or says to run `summer login --store`.
21
+ - `summer doctor` store-access check: with a store sign-in it calls `summer_store_list_games` (8 s limit) and shows the answer, or the store's code, message and request id on a refusal. Without a sign-in it says only publishing needs one.
22
+ - `summer doctor` shows the installed engine version and warns below 0.7.0, the first version that exports for summer.games.
23
+ - Skills `bounded-engine-runs` (run the engine from an agent with a time limit, a memory cap, one engine per project, muted and offscreen) and `compatibility-renderer-traps` (Forward+ games that also run on Compatibility: the instance-uniform budget, black MultiMesh colors, sRGB vertex colors, paired captures).
24
+
25
+ ### Changed
26
+ - With a store sign-in, the first `tools/list` waits up to 5 s for the hosted mount, so hosts that list tools once see the store tools. Without a sign-in nothing waits. A slower mount still adds them later.
27
+ - `summer_export_game` reads the engine version before it writes any preset. Below 0.7.0 it stops with `engine_too_old` and says how to update; nothing is written to the project.
28
+ - `summer_export_game` runs the engine with `--summer-no-api`, so an export no longer starts the local engine API. The result lists `projectChanges` (top-level files created, changed or deleted) and warns when the engine rewrote `project.godot`.
29
+ - `summer_publish_build` checks the game in the store before the confirmation preview. An unknown id returns `game_not_found` with your real games. A platform the store page does not list returns a warning. The preview shows the game name and id.
30
+ - `summer install --path` on macOS installs to `<dir>/Summer.app` (before, the bundle's contents went loose into the folder). Each install is recorded in `~/.summer/engine-install.json`, and run, doctor and export use that engine before the default locations. Without a terminal, progress prints one line per 10%. After an install, a note says the first start of a new engine version can take several minutes.
31
+ - `export-and-ship` skill: store key art, covers and icons carry no text, logos or UI; screenshots are real gameplay and may show the game's own HUD. On the hosted-game error "is in the source graph's authority_engine domain", narrow the authority root in `source-domains.json`.
32
+ - `concept-art` skill no longer says the aspect ratio cannot be set over MCP.
33
+
34
+ ### Fixed
35
+ - `summer_export_game` failures show the engine's own `ERROR:` lines: the first three in the message, up to 20 in `detail.errors`, instead of a guess about an old engine. The old-engine hint appears only when the engine names a missing or invalid preset. A source-graph domain error gets its own recovery step.
36
+ - `summer_publish_build` without a `gameId` says why the game list is missing (for example the store's 401 message). `store_auth_refused` carries the store's message and request id and no longer sends you to `summer login --store --force` first, which looped.
37
+ - `gateway.url`, `creator.apiUrl` and the creator upload URL accept the IPv6 loopback (`http://[::1]:3000`) as local HTTP.
38
+ - `in-game-purchases` skill: uses only engine APIs that exist. It no longer calls `Summer.client.store.request_sparks_purchase`, `check_sparks_purchase_readiness` or `Summer.authority.items.consume`, which the engine does not have. Short players get Sparks in the Summer app; an authority grants a paid effect after checking `Summer.authority.items.inventory_for_session` and recording the redemption in the player's secret player data.
39
+ - `summer_api_docs`: the offline class reference is rebuilt from the engine's current class XML (1282 classes), so it now includes `SummerRuntime` (`Summer`), `Summer.client.*`, `Summer.authority.*` and the Summer SDK types.
40
+
41
+ ## [3.3.0] - 2026-10-09
42
+
43
+ Your agent can now take a game from the editor to the Summer Games store:
44
+
45
+ - Export for every platform the store takes: iPhone, Android, Mac, Windows and the web, as a summer.games bundle or as a store download.
46
+ - Install the export templates for your engine version with one tool call. Each file is checked before it is installed.
47
+ - Sign in to the store from the terminal with `summer login --store`.
48
+ - Upload a build and publish it with `summer_publish_build`, after you confirm the game, file and version.
49
+ - 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.
50
+
51
+ ### Added
52
+ - `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.
53
+ - `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.
54
+ - `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.
55
+ - `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.
56
+ - `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.
57
+ - 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.
58
+ - `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.
59
+
60
+ ### Fixed
61
+ - `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.
62
+
63
+ ### Deprecated
64
+ - `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`.
65
+
5
66
  ## [3.2.1] - 2026-10-07
6
67
 
7
68
  ### Changed
package/README.md CHANGED
@@ -97,7 +97,7 @@ The first invocation downloads the npm package transparently to npx's cache (~3
97
97
 
98
98
  Read the JSON output. **Top-level `ok: true` means "no check failed" — it does NOT mean Summer is installed.** A machine with no skills, no MCP config, and no login can report `ok: true` (those checks warn, they do not fail). So never skip Step 1 on `ok`: it is idempotent and fast. Use the `checks` array (each entry: `id`, `label`, `status` of `ok` / `warning` / `fail`, `message`, optional `details`) only to decide whether the expensive steps — engine download (Step 2) and browser login (Step 3) — are needed.
99
99
 
100
- The check ids are `node-version`, `cli-version`, `cli-version-current`, `skills-version-stale`, `login`, `engine-install`, `local-api`, `project-memory`, `mcp-boot`, and `mcp-tools-list`. For any check whose `status` is not `ok`, run the action in the table below, then re-run doctor.
100
+ The check ids are `node-version`, `cli-version`, `cli-version-current`, `skills-version-stale`, `login`, `store-access`, `engine-install`, `local-api`, `project-memory`, `mcp-boot`, and `mcp-tools-list`. For any check whose `status` is not `ok`, run the action in the table below, then re-run doctor.
101
101
 
102
102
  | Check id | If `status` is `ok` | Action when attention is needed |
103
103
  |---|---|---|
@@ -106,6 +106,7 @@ The check ids are `node-version`, `cli-version`, `cli-version-current`, `skills-
106
106
  | `cli-version-current` | continue | run `npx clear-npx-cache && npx -y summer-engine@latest doctor --json` (forces a fresh resolve) |
107
107
  | `skills-version-stale` | run Step 1 anyway (idempotent) | run Step 1 (`--force` is already in the command) |
108
108
  | `login` | skip Step 3 | run Step 3 |
109
+ | `store-access` | continue | only for publishing: surface the `message` (it carries the store's own reason); signing in again does not fix a refusal the store gives a valid sign-in |
109
110
  | `engine-install` | skip Step 2 | run Step 2 |
110
111
  | `local-api` | skip Step 5b wait-loop | expected before `summer run`; run the wait-loop after it |
111
112
  | `project-memory` | continue | if a project is open, use the `brainstorm-game` skill before building |
@@ -226,7 +227,7 @@ Only skip brainstorm if the user explicitly said "skip brainstorm" or "just buil
226
227
  |---|---|---|
227
228
  | **Create** | Available | Scaffold from a pinned template, build scenes and scripts through MCP, generate 2D/3D/audio/video assets, guided by the library. |
228
229
  | **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. |
230
+ | **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
231
  | **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
232
 
232
233
  ## What's in this repo
@@ -321,6 +322,7 @@ We tell you before we touch your disk.
321
322
  | Summer Engine app | ~1 GB (engine + bundled Git/runtime tools) | `npx -y summer-engine@latest install` | Summer's signed releases |
322
323
  | Auth token | ~1 KB | `npx -y summer-engine@latest login` | Browser to `~/.summer/auth-token` |
323
324
  | 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 |
325
+ | 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
326
  | Skill files | small, bundled | in the npm package | no extra network call |
325
327
  | 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
328
  | URL imports | varies | only on explicit `summer_import_from_url` calls | the URL you provide |
@@ -348,10 +350,11 @@ matchmaking are not promised by this package.
348
350
  |---|---|
349
351
  | `summer install [--yes]` | Download Summer Engine. Prints URL and size first; never replaces an installed engine without confirmation. |
350
352
  | `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. |
353
+ | `summer login --store` | Browser sign-in to the Summer store so agents can upload builds (`summer_publish_build`). |
354
+ | `summer login --creator` | Deprecated with `summer publish`: connect a separate publish-scoped creator token for the legacy creator API. |
352
355
  | `summer logout` | Clear auth tokens. |
353
356
  | `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. |
357
+ | `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
358
  | `summer releases [--cursor <value>]` | List real creator-owned release history. |
356
359
  | `summer status` | Engine state, port, auth. |
357
360
  | `summer doctor` | Diagnose Node, login, engine, project memory, MCP. |
Binary file
@@ -44,6 +44,16 @@ export declare function replaceMacApp(mountPoint: string, destApp: string, exec:
44
44
  * setup.exe CLI). The old NSIS flags (/S, /D=) are rejected by the Velopack
45
45
  * installer with "unexpected argument '/S' found" — this is the wizard bug. */
46
46
  export declare function windowsInstallerArgs(customPath?: string): string;
47
+ /** Printed after an install: the first start of a new engine is slow and silent. */
48
+ export declare const FIRST_START_NOTE: string;
49
+ /** Where the Velopack installer put Summer.exe: <dir>/current/Summer.exe for --path, else the default locations. */
50
+ export declare function windowsInstalledBinary(customPath?: string, exists?: (path: string) => boolean): string | null;
51
+ /**
52
+ * Download progress: rewrites one line on a terminal; elsewhere (an agent,
53
+ * a log file) one line per 10%, so a 1 GB download is about ten lines
54
+ * instead of hundreds of kilobytes.
55
+ */
56
+ export declare function createProgressReporter(isTTY: boolean, write: (text: string) => void): (downloaded: number, total: number) => void;
47
57
  export declare const installCommand: Command;
48
58
  export declare function downloadFile(url: string, dest: string): Promise<{
49
59
  sha256: string;
@@ -6,8 +6,8 @@ import { chmodSync, createWriteStream, existsSync, mkdirSync, readdirSync, renam
6
6
  import { pipeline } from "stream/promises";
7
7
  import { Readable } from "stream";
8
8
  import { tmpdir, platform } from "os";
9
- import { join, resolve } from "path";
10
- import { ENGINE_BINARY_ENV, LINUX_ENGINE_BINARY_NAME, findExtractedEngineBinary, linuxArchiveKind, linuxEngineInstallDir, pickLinuxReleaseAsset, resolveLinuxInstallSource, } from "../../core/engine-install.js";
9
+ import { dirname, join, resolve } from "path";
10
+ import { ENGINE_BINARY_ENV, LINUX_ENGINE_BINARY_NAME, macInstallDestination, recordEngineInstall, windowsEnginePaths, findExtractedEngineBinary, linuxArchiveKind, linuxEngineInstallDir, pickLinuxReleaseAsset, resolveLinuxInstallSource, } from "../../core/engine-install.js";
11
11
  const RELEASES_URL = "https://www.summerengine.com/api/desktop/releases";
12
12
  /** Guard a download URL from the releases endpoint. A missing/empty URL (an
13
13
  * outdated or misconfigured endpoint) otherwise becomes a cryptic
@@ -116,9 +116,42 @@ async function confirm(question) {
116
116
  export function windowsInstallerArgs(customPath) {
117
117
  return customPath ? `--silent --installto "${customPath}"` : "--silent";
118
118
  }
119
+ /** Printed after an install: the first start of a new engine is slow and silent. */
120
+ export const FIRST_START_NOTE = "The first start of a new engine version can take several minutes with no output " +
121
+ "(the system checks the new app and the engine builds its caches). Later starts are fast.";
122
+ /** Where the Velopack installer put Summer.exe: <dir>/current/Summer.exe for --path, else the default locations. */
123
+ export function windowsInstalledBinary(customPath, exists = existsSync) {
124
+ const candidates = customPath
125
+ ? [join(customPath, "current", "Summer.exe"), join(customPath, "Summer.exe")]
126
+ : windowsEnginePaths();
127
+ return candidates.find((path) => exists(path)) ?? null;
128
+ }
129
+ /**
130
+ * Download progress: rewrites one line on a terminal; elsewhere (an agent,
131
+ * a log file) one line per 10%, so a 1 GB download is about ten lines
132
+ * instead of hundreds of kilobytes.
133
+ */
134
+ export function createProgressReporter(isTTY, write) {
135
+ let lastStep = -1;
136
+ return (downloaded, total) => {
137
+ if (total <= 0)
138
+ return;
139
+ const pct = Math.min(100, Math.floor((downloaded / total) * 100));
140
+ const mb = (downloaded / 1024 / 1024).toFixed(1);
141
+ if (isTTY) {
142
+ write(`\r ${pct}% (${mb}MB)`);
143
+ return;
144
+ }
145
+ const step = Math.floor(pct / 10);
146
+ if (step > lastStep) {
147
+ lastStep = step;
148
+ write(` ${pct}% (${mb}MB)\n`);
149
+ }
150
+ };
151
+ }
119
152
  export const installCommand = new Command("install")
120
153
  .description("Download and install Summer Engine")
121
- .option("--path <dir>", "Custom install directory")
154
+ .option("--path <dir>", "Custom install directory (macOS: the engine goes in <dir>/Summer.app). summer remembers it, so later commands find this engine")
122
155
  .option("--yes", "Replace an already-installed engine without prompting")
123
156
  .action(async (opts) => {
124
157
  const os = platform();
@@ -160,7 +193,8 @@ async function installMac(releases, customPath, yes = false) {
160
193
  }
161
194
  const dmgUrl = requireDownloadUrl(info.dmg_url, "macOS DMG");
162
195
  console.log(`Latest version: ${info.version}`);
163
- const destApp = customPath || "/Applications/Summer.app";
196
+ const destApp = macInstallDestination(customPath);
197
+ const destBinary = join(destApp, "Contents", "MacOS", "Summer");
164
198
  const exists = existsSync(destApp);
165
199
  const installedVersion = exists ? readMacBundleVersion(destApp) : null;
166
200
  const plan = planMacInstall({
@@ -171,6 +205,7 @@ async function installMac(releases, customPath, yes = false) {
171
205
  isTTY: Boolean(process.stdin.isTTY),
172
206
  });
173
207
  if (plan.action === "up-to-date") {
208
+ await recordEngineInstall(destBinary, plan.version);
174
209
  console.log(`Summer Engine v${plan.version} is already installed at ${destApp} (up to date).`);
175
210
  return;
176
211
  }
@@ -218,6 +253,7 @@ async function installMac(releases, customPath, yes = false) {
218
253
  }
219
254
  try {
220
255
  console.log("Installing to " + destApp + "...");
256
+ mkdirSync(dirname(destApp), { recursive: true });
221
257
  replaceMacApp(mountPoint, destApp, (command) => execSync(command, { stdio: "ignore" }));
222
258
  console.log("Done!");
223
259
  }
@@ -235,7 +271,9 @@ async function installMac(releases, customPath, yes = false) {
235
271
  catch { }
236
272
  releaseSignals();
237
273
  }
274
+ await recordEngineInstall(destBinary, info.version);
238
275
  console.log(`\nSummer Engine v${info.version} installed to ${destApp}`);
276
+ console.log(FIRST_START_NOTE);
239
277
  console.log("\nNext steps:");
240
278
  console.log(" summer login # Sign in to your account");
241
279
  console.log(" summer run # Launch the engine");
@@ -276,7 +314,11 @@ async function installWindows(releases, customPath) {
276
314
  execSync(`del "${exePath}"`, { stdio: "ignore" });
277
315
  }
278
316
  catch { }
279
- console.log(`\nSummer Engine v${info.version} installed!`);
317
+ const installed = windowsInstalledBinary(customPath);
318
+ if (installed)
319
+ await recordEngineInstall(installed, info.version);
320
+ console.log(`\nSummer Engine v${info.version} installed${installed ? ` to ${installed}` : "!"}`);
321
+ console.log(FIRST_START_NOTE);
280
322
  console.log("\nNext steps:");
281
323
  console.log(" summer login # Sign in to your account");
282
324
  console.log(" summer run # Launch the engine");
@@ -338,6 +380,7 @@ async function installLinux(customPath) {
338
380
  const source = resolveLinuxInstallSource();
339
381
  if (source.kind === "binary") {
340
382
  registerExistingLinuxBinary(source.path, destDir, destBinary);
383
+ await recordEngineInstall(destBinary, null);
341
384
  printLinuxNextSteps(destBinary);
342
385
  return;
343
386
  }
@@ -409,7 +452,9 @@ async function installLinux(customPath) {
409
452
  finally {
410
453
  rmSync(downloadPath, { force: true });
411
454
  }
455
+ await recordEngineInstall(destBinary, versionLabel === "custom" ? null : versionLabel);
412
456
  console.log(`\nSummer Engine (${versionLabel}) installed to ${destBinary}`);
457
+ console.log(FIRST_START_NOTE);
413
458
  printLinuxNextSteps(destBinary);
414
459
  }
415
460
  function printLinuxNextSteps(binary) {
@@ -433,15 +478,15 @@ export async function downloadFile(url, dest) {
433
478
  const hash = createHash("sha256");
434
479
  let downloaded = 0;
435
480
  const total = parseInt(res.headers.get("content-length") || "0", 10);
481
+ const isTTY = Boolean(process.stdout.isTTY);
482
+ const report = createProgressReporter(isTTY, (text) => process.stdout.write(text));
436
483
  readable.on("data", (chunk) => {
437
484
  hash.update(chunk);
438
485
  downloaded += chunk.length;
439
- if (total > 0) {
440
- const pct = Math.round((downloaded / total) * 100);
441
- process.stdout.write(`\r ${pct}% (${(downloaded / 1024 / 1024).toFixed(1)}MB)`);
442
- }
486
+ report(downloaded, total);
443
487
  });
444
488
  await pipeline(readable, fileStream);
445
- process.stdout.write("\n");
489
+ if (isTTY)
490
+ process.stdout.write("\n");
446
491
  return { sha256: hash.digest("hex") };
447
492
  }
@@ -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,
@@ -1,5 +1,12 @@
1
1
  import { Command } from "commander";
2
2
  import { type ToolDispatchEntry } from "../../core/capabilities/tool-dispatch.js";
3
+ import { callHostedToolForCli, listHostedToolsForCli, type HostedToolsListing } from "../../core/hosted-mcp.js";
4
+ /** The hosted store and publishing tools (Summer Engine MCP); replaceable in tests. */
5
+ export declare const hostedCli: {
6
+ list: typeof listHostedToolsForCli;
7
+ call: typeof callHostedToolForCli;
8
+ };
9
+ export declare function formatHostedToolList(listing: HostedToolsListing): string;
3
10
  /** Resolve a name through the compiled registry index when it exists —
4
11
  * accepts full ids ("tool/add-node") and legacy aliases, returning the slug
5
12
  * the dispatch table knows. Returns null when the index is absent or the
@@ -14,6 +14,25 @@ import { PACKAGE_ROOT } from "../../core/package-root.js";
14
14
  import { Command, Option } from "commander";
15
15
  import { ToolDispatchError, ToolResultError, dispatchTool, listToolDispatches, resolveToolDispatch, } from "../../core/capabilities/tool-dispatch.js";
16
16
  import { c } from "../../core/format.js";
17
+ import { callHostedToolForCli, hostedResultPayload, listHostedToolsForCli, } from "../../core/hosted-mcp.js";
18
+ /** The hosted store and publishing tools (Summer Engine MCP); replaceable in tests. */
19
+ export const hostedCli = { list: listHostedToolsForCli, call: callHostedToolForCli };
20
+ const STORE_SIGN_IN_HINT = "Store and publishing tools (summer_store_*, summer_upload_image_*, summer_list_projects, ...) come from the hosted Summer Engine MCP: run 'summer login --store' to use them here.";
21
+ export function formatHostedToolList(listing) {
22
+ if (listing.status === "not_signed_in")
23
+ return c.dim(STORE_SIGN_IN_HINT);
24
+ if (listing.status === "unavailable")
25
+ return c.dim(`Store and publishing tools: the hosted Summer Engine MCP did not answer (${listing.message}).`);
26
+ const local = new Set(listToolDispatches().map((entry) => `summer_${entry.slug.replace(/-/g, "_")}`));
27
+ const tools = listing.tools.filter((tool) => !local.has(tool.name)).sort((a, b) => a.name.localeCompare(b.name));
28
+ if (!tools.length)
29
+ return c.dim("Store and publishing tools: none listed by the hosted Summer Engine MCP.");
30
+ const width = Math.max(...tools.map((tool) => tool.name.length));
31
+ return [
32
+ c.bold(`Store and publishing tools (${tools.length}, hosted, with your store sign-in)`),
33
+ ...tools.map((tool) => ` ${tool.name.padEnd(width)} ${(tool.description ?? "").split(/(?<=\.)\s/)[0].slice(0, 120)}`),
34
+ ].join("\n");
35
+ }
17
36
  /** Resolve a name through the compiled registry index when it exists —
18
37
  * accepts full ids ("tool/add-node") and legacy aliases, returning the slug
19
38
  * the dispatch table knows. Returns null when the index is absent or the
@@ -86,6 +105,8 @@ export const toolCommand = new Command("tool")
86
105
  .action(async (name, options) => {
87
106
  if (options.list || name === undefined) {
88
107
  console.log(formatToolList(listToolDispatches()));
108
+ console.log("");
109
+ console.log(formatHostedToolList(await hostedCli.list()));
89
110
  if (name === undefined && !options.list) {
90
111
  console.log("");
91
112
  console.log(c.dim("Pass a tool name to run one."));
@@ -94,7 +115,21 @@ export const toolCommand = new Command("tool")
94
115
  }
95
116
  const entry = resolveToolForCli(name);
96
117
  if (!entry) {
97
- throw new ToolDispatchError(`Unknown tool "${name}". Run 'summer tool --list' to see all ${listToolDispatches().length} tools.`);
118
+ // Not a local tool: the hosted store and publishing tools, with the store sign-in.
119
+ const hosted = await hostedCli.call(name, parseJsonArgs(options.args ?? options.json));
120
+ if (hosted.status === "called") {
121
+ const payload = hostedResultPayload(hosted.result);
122
+ console.log(payload.json ? JSON.stringify(payload.json, null, 2) : payload.text);
123
+ if (payload.isError)
124
+ process.exitCode = 1;
125
+ return;
126
+ }
127
+ const why = hosted.status === "not_signed_in"
128
+ ? ` ${STORE_SIGN_IN_HINT}`
129
+ : hosted.status === "unavailable"
130
+ ? ` The hosted Summer Engine MCP did not answer: ${hosted.message}.`
131
+ : "";
132
+ throw new ToolDispatchError(`Unknown tool "${name}". Run 'summer tool --list' to see every tool.${why}`);
98
133
  }
99
134
  if (options.json !== undefined && options.args === undefined) {
100
135
  console.error("Note: 'summer tool --json <args>' is deprecated; use --args <json>.");
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;