summer-engine 4.5.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +3 -2
- package/.codex-plugin/plugin.json +5 -4
- package/.cursor-plugin/plugin.json +4 -3
- package/.factory-plugin/plugin.json +4 -3
- package/CHANGELOG.md +50 -0
- package/README.md +3 -3
- package/commands/start.md +1 -1
- package/dist/cli/commands/api.d.ts +43 -0
- package/dist/cli/commands/api.js +191 -0
- package/dist/cli/commands/login.d.ts +2 -5
- package/dist/cli/commands/login.js +10 -81
- package/dist/cli/commands/setup.js +175 -32
- package/dist/cli/commands/token.d.ts +17 -0
- package/dist/cli/commands/token.js +25 -0
- package/dist/cli/index.js +4 -0
- package/dist/core/api-client.d.ts +5 -1
- package/dist/core/api-client.js +21 -0
- package/dist/core/capabilities/doctor.d.ts +1 -1
- package/dist/core/capabilities/doctor.js +1 -1
- package/dist/core/capabilities/game-task-plan.d.ts +2 -2
- package/dist/core/capabilities/navigation/open.d.ts +3 -0
- package/dist/core/capabilities/navigation/open.js +53 -0
- package/dist/core/capabilities/projects-local.js +2 -1
- package/dist/core/capabilities/runtime-control.d.ts +2 -2
- package/dist/core/capabilities/seeing/args.d.ts +4 -4
- package/dist/core/capabilities/tool-dispatch.js +37 -0
- package/dist/core/capabilities/ui-control.d.ts +2 -2
- package/dist/core/capabilities/view-set.d.ts +11 -0
- package/dist/core/capabilities/view-set.js +15 -0
- package/dist/core/capability-skew.d.ts +8 -0
- package/dist/core/capability-skew.js +18 -0
- package/dist/core/cli-session.d.ts +25 -0
- package/dist/core/cli-session.js +97 -0
- package/dist/core/engine-self-start.d.ts +20 -0
- package/dist/core/engine-self-start.js +108 -5
- package/dist/core/oauth.d.ts +15 -2
- package/dist/core/oauth.js +26 -3
- package/dist/core/ops/areas.d.ts +1 -1
- package/dist/core/ops/areas.js +5 -3
- package/dist/core/ops/engine-answer.js +5 -2
- package/dist/core/ops/engine.js +6 -0
- package/dist/core/ops/save-files.d.ts +2 -0
- package/dist/core/ops/save-files.js +13 -0
- package/dist/core/ops/studio-page.d.ts +22 -0
- package/dist/core/ops/studio-page.js +63 -0
- package/dist/core/sign-in-link.d.ts +38 -0
- package/dist/core/sign-in-link.js +106 -0
- package/dist/core/store.js +19 -1
- package/dist/core/summer-api.d.ts +114 -0
- package/dist/core/summer-api.js +281 -0
- package/dist/installer/agent-config.d.ts +29 -0
- package/dist/installer/agent-config.js +75 -11
- package/dist/installer/agent-detect.d.ts +44 -0
- package/dist/installer/agent-detect.js +166 -0
- package/dist/installer/agent-table.d.ts +19 -0
- package/dist/installer/agent-table.js +130 -0
- package/dist/installer/setup-error.d.ts +19 -0
- package/dist/installer/setup-error.js +34 -0
- package/dist/installer/version-check.d.ts +5 -0
- package/dist/installer/version-check.js +21 -0
- package/dist/mcp/ops-surface.d.ts +10 -0
- package/dist/mcp/ops-surface.js +18 -1
- package/dist/mcp/server.js +16 -4
- package/dist/mcp/tool-results.d.ts +9 -0
- package/dist/mcp/tool-results.js +64 -0
- package/dist/mcp/tool-surface.js +7 -1
- package/dist/mcp/tools/api-tools.d.ts +50 -0
- package/dist/mcp/tools/api-tools.js +65 -0
- package/dist/mcp/tools/local-project-tools.d.ts +14 -0
- package/dist/mcp/tools/local-project-tools.js +13 -2
- package/dist/mcp/tools/navigation-tools.js +1 -0
- package/dist/mcp/tools/scene-tools.js +7 -0
- package/dist/project-memory/agent-instructions.js +11 -3
- package/gemini-extension.json +3 -2
- package/library/references/mcp-tools-reference/mcp-tools-reference.md +15 -2
- package/library/references/mcp-tools-reference/resource.yaml +1 -1
- package/library/skills/README.md +6 -5
- package/library/skills/design-npc/SKILL.md +1 -1
- package/library/skills/design-npc/resource.yaml +2 -1
- package/library/skills/make-game/SKILL.md +4 -4
- package/library/skills/navigate-summer/SKILL.md +23 -2
- package/library/skills/navigate-summer/resource.yaml +5 -3
- package/library/skills/summer-api/SKILL.md +198 -0
- package/library/skills/summer-api/resource.yaml +38 -0
- package/library/skills/summer-assets/SKILL.md +1 -1
- package/library/skills/summer-assets/resource.yaml +3 -2
- package/library/skills/summer-router/SKILL.md +251 -0
- package/library/skills/summer-router/resource.yaml +35 -0
- package/library/tools/api-batch/resource.yaml +82 -0
- package/library/tools/api-estimate/resource.yaml +52 -0
- package/library/tools/api-job/resource.yaml +58 -0
- package/library/tools/api-models/resource.yaml +57 -0
- package/library/tools/api-run/resource.yaml +70 -0
- package/library/tools/view-set/GUIDE.md +3 -0
- package/library/tools/view-set/resource.yaml +78 -0
- package/package.json +3 -3
- package/registry/generated/aliases.json +7 -0
- package/registry/generated/counts.json +3 -3
- package/registry/generated/gemini-extension.json +3 -2
- package/registry/generated/index.json +317 -52
- package/registry/generated/marketplace.claude.json +1 -1
- package/registry/generated/plugin.claude-directory.json +4 -3
- package/registry/generated/plugin.claude.json +3 -2
- package/registry/generated/plugin.codex.json +5 -4
- package/registry/generated/plugin.cursor.json +4 -3
- package/registry/generated/plugin.factory.json +4 -3
- package/registry/generated/server.json +2 -2
- package/registry/generated/skills-index.md +6 -5
- package/registry/generated/skills-registry.json +29 -15
- package/registry/operations/legacy-names.json +30 -0
- package/registry/operations/public-catalog.json +9169 -4926
- package/library/skills/ai-characters-in-games/SKILL.md +0 -235
- package/library/skills/ai-characters-in-games/resource.yaml +0 -30
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{
|
|
11
11
|
"name": "summer",
|
|
12
12
|
"source": "./",
|
|
13
|
-
"version": "4.
|
|
13
|
+
"version": "4.8.0",
|
|
14
14
|
"description": "The game engine built for AI. Any agent makes a multiplayer game and publishes it. A first-run guide (/summer:start), game-dev skills, and two MCP servers: the bridge to the Summer Engine desktop app, and Summer's hosted cloud server for people without it.",
|
|
15
15
|
"author": {
|
|
16
16
|
"name": "Summer Engine",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "summer",
|
|
4
4
|
"displayName": "Summer Engine",
|
|
5
|
-
"version": "4.
|
|
5
|
+
"version": "4.8.0",
|
|
6
6
|
"description": "The game engine built for AI. Any agent makes a multiplayer game and publishes it. A first-run guide (/summer:start), game-dev skills, and two MCP servers: the bridge to the Summer Engine desktop app, and Summer's hosted cloud server for people without it.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Summer Engine",
|
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
"./library/skills/3d-lighting/",
|
|
36
36
|
"./library/skills/adaptive-music/",
|
|
37
37
|
"./library/skills/agent-playtesting/",
|
|
38
|
-
"./library/skills/ai-characters-in-games/",
|
|
39
38
|
"./library/skills/ambient-bed/",
|
|
40
39
|
"./library/skills/animated-loop/",
|
|
41
40
|
"./library/skills/animation-tree/",
|
|
@@ -115,6 +114,7 @@
|
|
|
115
114
|
"./library/skills/store-art/",
|
|
116
115
|
"./library/skills/store-listing/",
|
|
117
116
|
"./library/skills/summer-analytics/",
|
|
117
|
+
"./library/skills/summer-api/",
|
|
118
118
|
"./library/skills/summer-apps/",
|
|
119
119
|
"./library/skills/summer-apps-design/",
|
|
120
120
|
"./library/skills/summer-assets/",
|
|
@@ -125,6 +125,7 @@
|
|
|
125
125
|
"./library/skills/summer-matchmaking/",
|
|
126
126
|
"./library/skills/summer-parties/",
|
|
127
127
|
"./library/skills/summer-player-data/",
|
|
128
|
+
"./library/skills/summer-router/",
|
|
128
129
|
"./library/skills/summer-store/",
|
|
129
130
|
"./library/skills/summer-world-chat/",
|
|
130
131
|
"./library/skills/summer-world-saves/",
|
|
@@ -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": "4.
|
|
5
|
-
"description": "The game engine built for AI. Any agent makes a multiplayer game and publishes it. Game-dev skills, lifecycle hooks, and a
|
|
4
|
+
"version": "4.8.0",
|
|
5
|
+
"description": "The game engine built for AI. Any agent makes a multiplayer game and publishes it. Game-dev skills, lifecycle hooks, and a 131-tool MCP bridge to the Summer Engine desktop app.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Summer Engine",
|
|
8
8
|
"email": "founders@summerengine.com",
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"./library/skills/3d-lighting/",
|
|
26
26
|
"./library/skills/adaptive-music/",
|
|
27
27
|
"./library/skills/agent-playtesting/",
|
|
28
|
-
"./library/skills/ai-characters-in-games/",
|
|
29
28
|
"./library/skills/ambient-bed/",
|
|
30
29
|
"./library/skills/animated-loop/",
|
|
31
30
|
"./library/skills/animation-tree/",
|
|
@@ -105,6 +104,7 @@
|
|
|
105
104
|
"./library/skills/store-art/",
|
|
106
105
|
"./library/skills/store-listing/",
|
|
107
106
|
"./library/skills/summer-analytics/",
|
|
107
|
+
"./library/skills/summer-api/",
|
|
108
108
|
"./library/skills/summer-apps/",
|
|
109
109
|
"./library/skills/summer-apps-design/",
|
|
110
110
|
"./library/skills/summer-assets/",
|
|
@@ -115,6 +115,7 @@
|
|
|
115
115
|
"./library/skills/summer-matchmaking/",
|
|
116
116
|
"./library/skills/summer-parties/",
|
|
117
117
|
"./library/skills/summer-player-data/",
|
|
118
|
+
"./library/skills/summer-router/",
|
|
118
119
|
"./library/skills/summer-store/",
|
|
119
120
|
"./library/skills/summer-world-chat/",
|
|
120
121
|
"./library/skills/summer-world-saves/",
|
|
@@ -148,7 +149,7 @@
|
|
|
148
149
|
"interface": {
|
|
149
150
|
"displayName": "Summer Engine",
|
|
150
151
|
"shortDescription": "Make games with AI",
|
|
151
|
-
"longDescription": "Summer Engine is the game engine built for AI. Codex builds a full multiplayer game in it, plays and tests it, and publishes it on summer.games. The plugin adds game-dev skills, lifecycle hooks, and a
|
|
152
|
+
"longDescription": "Summer Engine is the game engine built for AI. Codex builds a full multiplayer game in it, plays and tests it, and publishes it on summer.games. The plugin adds game-dev skills, lifecycle hooks, and a 131-tool MCP bridge to the Summer Engine desktop app: project files, scenes, asset import, play mode, screenshots, diagnostics, asset generation and the store. Git, shell, and grep stay with Codex. Session-start orients each session. The pre-commit doctor (opt-in) blocks bad commits.",
|
|
152
153
|
"developerName": "Summer Labs, Inc.",
|
|
153
154
|
"category": "Developer Tools",
|
|
154
155
|
"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 Engine",
|
|
6
|
-
"version": "4.
|
|
7
|
-
"description": "The game engine built for AI. Any agent makes a multiplayer game and publishes it. Game-dev skills, lifecycle hooks, and a
|
|
6
|
+
"version": "4.8.0",
|
|
7
|
+
"description": "The game engine built for AI. Any agent makes a multiplayer game and publishes it. Game-dev skills, lifecycle hooks, and a 131-tool MCP bridge to the Summer Engine desktop app.",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Summer Engine",
|
|
10
10
|
"email": "founders@summerengine.com"
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
"./library/skills/3d-lighting/",
|
|
39
39
|
"./library/skills/adaptive-music/",
|
|
40
40
|
"./library/skills/agent-playtesting/",
|
|
41
|
-
"./library/skills/ai-characters-in-games/",
|
|
42
41
|
"./library/skills/ambient-bed/",
|
|
43
42
|
"./library/skills/animated-loop/",
|
|
44
43
|
"./library/skills/animation-tree/",
|
|
@@ -118,6 +117,7 @@
|
|
|
118
117
|
"./library/skills/store-art/",
|
|
119
118
|
"./library/skills/store-listing/",
|
|
120
119
|
"./library/skills/summer-analytics/",
|
|
120
|
+
"./library/skills/summer-api/",
|
|
121
121
|
"./library/skills/summer-apps/",
|
|
122
122
|
"./library/skills/summer-apps-design/",
|
|
123
123
|
"./library/skills/summer-assets/",
|
|
@@ -128,6 +128,7 @@
|
|
|
128
128
|
"./library/skills/summer-matchmaking/",
|
|
129
129
|
"./library/skills/summer-parties/",
|
|
130
130
|
"./library/skills/summer-player-data/",
|
|
131
|
+
"./library/skills/summer-router/",
|
|
131
132
|
"./library/skills/summer-store/",
|
|
132
133
|
"./library/skills/summer-world-chat/",
|
|
133
134
|
"./library/skills/summer-world-saves/",
|
|
@@ -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": "The game engine built for AI. Any agent makes a multiplayer game and publishes it. Game-dev skills, lifecycle hooks, and a
|
|
5
|
-
"version": "4.
|
|
4
|
+
"description": "The game engine built for AI. Any agent makes a multiplayer game and publishes it. Game-dev skills, lifecycle hooks, and a 131-tool MCP bridge to the Summer Engine desktop app.",
|
|
5
|
+
"version": "4.8.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Summer Engine",
|
|
8
8
|
"email": "founders@summerengine.com",
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"./library/skills/3d-lighting/",
|
|
23
23
|
"./library/skills/adaptive-music/",
|
|
24
24
|
"./library/skills/agent-playtesting/",
|
|
25
|
-
"./library/skills/ai-characters-in-games/",
|
|
26
25
|
"./library/skills/ambient-bed/",
|
|
27
26
|
"./library/skills/animated-loop/",
|
|
28
27
|
"./library/skills/animation-tree/",
|
|
@@ -102,6 +101,7 @@
|
|
|
102
101
|
"./library/skills/store-art/",
|
|
103
102
|
"./library/skills/store-listing/",
|
|
104
103
|
"./library/skills/summer-analytics/",
|
|
104
|
+
"./library/skills/summer-api/",
|
|
105
105
|
"./library/skills/summer-apps/",
|
|
106
106
|
"./library/skills/summer-apps-design/",
|
|
107
107
|
"./library/skills/summer-assets/",
|
|
@@ -112,6 +112,7 @@
|
|
|
112
112
|
"./library/skills/summer-matchmaking/",
|
|
113
113
|
"./library/skills/summer-parties/",
|
|
114
114
|
"./library/skills/summer-player-data/",
|
|
115
|
+
"./library/skills/summer-router/",
|
|
115
116
|
"./library/skills/summer-store/",
|
|
116
117
|
"./library/skills/summer-world-chat/",
|
|
117
118
|
"./library/skills/summer-world-saves/",
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,56 @@ All notable changes to summer-engine will be documented here. Following [Keep a
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [4.8.0] - 2026-10-24
|
|
8
|
+
|
|
9
|
+
The Summer API with the Summer sign-in (no static API keys), Studio inside the Summer app, and agents that show the person what they work on. 4.7.0 and the 2026-10-22 4.8.0 draft were never published; this 4.8.0 includes them (sections below).
|
|
10
|
+
|
|
11
|
+
- **`engine.view_set` (`summer_view_set`) shows the person what the agent works on**: the Summer app's view (home, chat, 3D, 2D, script, game, Studio), the right rail, the focus and the nodes to frame, through the engine's `SetView` operation. Needs Summer Engine 4.6 or newer.
|
|
12
|
+
- **`studio.radio`**: agents read and play Summer Radio in the person's open Studio tab (state, play, stop, station, track, next, previous, volume). The operations catalog is synced from PublicSummerEngine main (262 operations).
|
|
13
|
+
- **A generated file never saves into Summer's own folders.** `out` on the generate operations, `assets.get` and `jobs.wait` refuses a game's `.summer/local` (checkpoints, project id) and `~/.summer` (sign-in, runtime), with a warning; nothing is downloaded. The game's memory beside it (`.summer/GameSoul.md`, `.summer/memory/`) is unchanged.
|
|
14
|
+
- **`projects.open_local` switches the running editor.** When Summer Engine already has another project open, that editor now opens the asked one in the same window (the engine's `SwitchProject` operation) instead of answering "another project is open". The MCP says "Opening <game>…" at once (MCP progress) and waits up to 10 s for the new editor to register, then connects to it. An editor without the operation keeps the old answer and names the open project. Other tools never switch the open project.
|
|
15
|
+
- **Signed out? Cloud tools answer with a sign-in link.** When an MCP tool needs the Summer sign-in (`not_signed_in`) or the store approval (`store_login_required`), its answer now ends with a link the agent shows to the person. The MCP starts the same browser sign-in `summer login` uses (`cli_session`) without opening anything, waits for it in the background, and saves the token to `~/.summer`, so the next call works with no restart or reinstall. Engine tools keep working signed out. One link per process until that sign-in finishes or expires (15 minutes).
|
|
16
|
+
- **`summer api` and the `summer_api_*` MCP tools use the Summer sign-in on this computer**: the same Supabase OAuth 2.1 login (PKCE, a loopback redirect on 127.0.0.1) as the store tools. It stores the refresh token in `~/.summer/oauth-token` and refreshes by itself. Each app spends the person's paid credits up to the limit they set in Connected apps.
|
|
17
|
+
- **`summer api run --batch jobs.jsonl`** queues up to 500 Summer API jobs at once (`POST /v1/batches`), one job per line (`model`, `input`, optional `idempotencyKey`), all or none: when paid credits or the app's limit cannot cover them all, nothing runs and the error says how many fit. `--wait` follows every job, `--download [dir]` saves their files, and the JSON summary prints when piped. The MCP tool `summer_api_batch` does the same. No rate limits on paid usage: jobs past the account's running slots answer `queued` and start in order.
|
|
18
|
+
- **`summer api` on Windows.** `--input "@input.json"` reads the input from a file (Windows PowerShell 5 strips the quotes inside `'{"prompt":"..."}'`, and cmd.exe has no single quotes). Batch and input files may be UTF-16 (what Windows PowerShell 5 writes with `>`) or UTF-8 with a BOM, with CRLF lines. Saved files never get a name Windows keeps for a device (`CON`, `NUL`, `COM1`...) or a `:` that would write an NTFS stream. Writing the sign-in to `~/.summer` retries for a moment while antivirus or another Summer process has the file open, and `out` refuses `~/.summer` in any letter case on Windows. CI runs the Summer API and sign-in tests on Windows, macOS and Linux.
|
|
19
|
+
- **`summer token`** prints a one-hour access token for curl: `curl -H "Authorization: Bearer $(summer token)" https://www.summerengine.com/v1/models`.
|
|
20
|
+
- **Studio page ops run in the Summer app's own Studio tab.** `summer_call` sends `studio.map`, `studio.page`, `studio.use_page`, `studio.read_form` and `studio.submit_form` to the running Summer Engine (`POST /api/studio`) when it lists them in `capabilities.studioPage`, with the same input and answers and no store sign-in. When the app has no Studio tab (`no_tab`) or is not running, they go to Summer's server as before.
|
|
21
|
+
- The operations catalog is synced from PublicSummerEngine main: `account.usage` (plan, share used and refill day, in words) and asset generations in `jobs.list`.
|
|
22
|
+
- **Studio pages open in the Summer app's Studio tab.** `studio.open` (`summer_open`, `summer open`) with a `/studio...` page sends the running Summer Engine `Navigate {target: "studio", path}` when the engine lists the `studio` destination, so the app's own Studio tab moves instead of a browser opening. With the engine off or an older engine, the browser opens as before.
|
|
23
|
+
- **Skills `summer-api` and `summer-router`.** `summer-api`: sign in, models, estimate, one job or a batch, follow and download, money refusals (`no_credits`, `over_limit`), prompts per asset type. `summer-router`: AI characters in games on Summer Games (early preview): client and server calls, the character document, tools, speech and images, caps and error tags. `ai-characters-in-games` is retired (its id points to `summer-router`).
|
|
24
|
+
- **`summer router <action>`** runs the Summer Router operations from a shell: `save-character`, `test-character`, `models`, `settings`, `set-settings`, `usage` and the rest. The operations catalog is synced from PublicSummerEngine main.
|
|
25
|
+
- `summer_api_run`, `summer_api_batch` and `summer_api_job` name `no_credits` and `over_limit`, and say that Summer API jobs run to the end once accepted.
|
|
26
|
+
- **Removed:** `summer login --api-key`, the MCP tool `summer_api_key_login` (operation `account.api_key_login`), `SUMMER_API_KEY` and `~/.summer/api-key`.
|
|
27
|
+
|
|
28
|
+
## 4.8.0 draft - 2026-10-22 (not published)
|
|
29
|
+
|
|
30
|
+
The Summer API from a shell and from MCP. 4.7.0 was not published to npm; 4.8.0 is the first release with it (the [4.7.0] section below).
|
|
31
|
+
|
|
32
|
+
- **`summer api models|estimate|run|jobs`** call the Summer API (`/v1`) with the Summer API key on this computer (`summer login --api-key`, or `SUMMER_API_KEY`). `models` lists the curated game-dev models with their input and USD price (one model by id, `--capability` to filter); `estimate <model> --input '<json>'` prices one exact job and gives a quote id; `run <model> --input '<json>'` spends the person's credits within the key's limit, with one idempotency key per run, `--quote`, `--wait` to follow the job and `--download [dir]` to save its files; `jobs <id>` reads, follows (`--wait`), downloads or `--cancel`s a job. JSON when stdout is not a terminal (or `--json`), a short summary otherwise.
|
|
33
|
+
- **MCP tools** `summer_api_models`, `summer_api_estimate`, `summer_api_run` and `summer_api_job` do the same (operations `models.list`, `models.estimate`, `models.run`, `models.job`, local), in the assets and full profiles.
|
|
34
|
+
- **Until Summer opens the API**, `summer api` and `summer login --api-key` print one line, "Summer API is not open yet.", and exit 1.
|
|
35
|
+
- The operations catalog is synced from PublicSummerEngine main.
|
|
36
|
+
|
|
37
|
+
## [4.7.0] - 2026-10-22
|
|
38
|
+
|
|
39
|
+
A Summer API key for your agent with one Allow click, and Node 22.
|
|
40
|
+
|
|
41
|
+
- **A Summer API key for your agent with one Allow click.** `summer login --api-key` (and the MCP tool `summer_api_key_login`, operation `account.api_key_login`) asks Summer for a key: the person opens the Summer page it names, checks the code matches and presses Allow, choosing the spend limit there. The key is saved to `~/.summer/api-key` (owner-only, like `auth-token`) and is never printed or returned to the agent; `SUMMER_API_KEY` wins over the file. Without a terminal, `summer login --api-key` prints JSON lines (`needs_approval` with `approve_url` and `user_code`, then `approved`, `denied`, `expired` or `failed`). `summer logout` removes the key too. Until Summer turns API keys on, the request answers `keys_unavailable`.
|
|
42
|
+
- **Node 22+** (`engines.node >= 22`, was 20). Node 20 reached end of life on 2026-04-30 and gets no security fixes. `summer doctor` now fails on Node below 22, and CI runs the CLI on Node 22.23.4 (the 2026-10-21 security release) on macOS, Windows and Ubuntu.
|
|
43
|
+
|
|
44
|
+
## [4.6.0] - 2026-10-21
|
|
45
|
+
|
|
46
|
+
A first game that looks finished, and `summer setup` for the Summer desktop app's one-click agent connect.
|
|
47
|
+
|
|
48
|
+
- **`summer setup` for installers: find the agents, read each step, run a bundled Node.js.** For the Summer desktop app's installer, which connects the person's coding agent in one click and ships its own Node.js (Claude Code and Codex install without one).
|
|
49
|
+
- **`summer setup --detect --json`** lists every supported agent: whether it is installed (`installed`, `programFound` and each hit in `detectedBy`: a command on PATH or in the usual install folders, a macOS app or Windows program, the agent's own folder, a VS Code extension), its MCP config file, and whether that file already lists `summer-engine`. It writes nothing.
|
|
50
|
+
- **`summer setup <agent> --yes --json` reports each step** in `steps`: the MCP entry, Summer Games, skills, project files and doctor, each with `ok`, a `status` and, on failure, an `error` with a `code` (`config_invalid`, `config_not_writable`, `skills_install_failed`, `runtime_not_found`, ...). A failed step no longer stops the others, and any failure exits 1. An error before setup starts (an unknown agent, a bad option) is one JSON document too. The output for people is unchanged.
|
|
51
|
+
- **`--runtime <node> --package-dir <dir>`** writes the MCP entry as `<node> <dir>/dist/bin/summer.js mcp` instead of `npx`, in every agent's file format. Setup checks that both exist and that the folder is the summer-engine package. Doctor's skills refresh keeps the bundled runtime.
|
|
52
|
+
- **First game: make it look finished.** A first game used to come out as grey boxes: the `make-game` skill told agents to build the first playable from shapes and add art later, and nothing an agent always reads said anything about looks. Now the rule sits where agents read it without choosing to:
|
|
53
|
+
- **MCP server instructions** open with it, inside the first 512 characters (Codex keeps the first 512): keep the features the person asked for and raise the look (sky and sun with shadows, fog, a texture on every surface, real models from the starter project and `summer_assets_search` first, never capsules or boxes as final art, one palette, a styled UI font), then play it and check a screenshot of the running game. They no longer open with "call summer_get_project_context first".
|
|
54
|
+
- **The project's `AGENTS.md` block** (written by `summer create` and `summer setup --yes`) has a "First game: make it look finished" section. It now says to write GDScript files directly and to create scenes and import assets through Summer, and its publishing line matches the store: a game goes live when Summer's automated checks pass, with no wait for a review.
|
|
55
|
+
- **`make-game`:** the first playable already looks good; generation still never blocks the first play (starter and library art first).
|
|
56
|
+
|
|
7
57
|
## [4.5.0] - 2026-10-19
|
|
8
58
|
|
|
9
59
|
4.4.0 was not published to npm. 4.5.0 is the first release with everything in it (the [4.4.0] section below), plus these changes.
|
package/README.md
CHANGED
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
|
|
21
21
|
## Install
|
|
22
22
|
|
|
23
|
-
- **Start a game now** (Node
|
|
23
|
+
- **Start a game now** (Node 22+): `npx -y summer-engine@latest dev`. It asks before it installs the Summer Engine app (about 660 MB, free) when it is missing, creates a starter project here (in `./my-game` when this folder has other files) and opens it, ready for your agent. No sign-in needed to build.
|
|
24
24
|
- **Chat apps** (Claude, ChatGPT, Cursor...): add `https://mcp.summerengine.com/mcp`. Nothing to install.
|
|
25
25
|
- **Homebrew:** `brew install summerengine/tap/summer`
|
|
26
|
-
- **npm** (Node
|
|
26
|
+
- **npm** (Node 22+): `npm install -g summer-engine`
|
|
27
27
|
|
|
28
28
|
**CLI only** (summer-engine 4.2.0 or newer), no MCP server: `summer setup --cli`. `summer ops search "publish my game"` finds any operation, signed in or not.
|
|
29
29
|
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
| Devin Desktop (formerly Windsurf) | add `"summer-cloud": {"serverUrl": "https://mcp.summerengine.com/mcp"}` under `mcpServers` in `~/.config/devin/mcp_config.json` (Windows `%APPDATA%\devin\mcp_config.json`) |
|
|
41
41
|
| Claude Desktop, claude.ai | Settings > Connectors > Add custom connector, then paste the URL |
|
|
42
42
|
|
|
43
|
-
**Engine work: `npx -y summer-engine@latest setup <agent> --yes`** (needs Node
|
|
43
|
+
**Engine work: `npx -y summer-engine@latest setup <agent> --yes`** (needs Node 22+). It writes the local server (`summer mcp`) into your agent's config with the skills. The local server drives the Summer Engine app on your machine: build scenes, write scripts, play the game, take screenshots, read errors. After `summer login` it also runs every cloud operation, so your agent needs one server. Or paste the prompt in [Get started](#get-started-one-prompt) and your agent does every step.
|
|
44
44
|
|
|
45
45
|
**CLI only (summer-engine 4.2.0 or newer): `npx -y summer-engine@latest setup <agent> --cli --yes`.** No MCP server: your agent runs Summer as commands in its shell. Setup installs the skills for your agent, with `summer-cli`, the guide to the commands, and writes no MCP entry. Your agent signs you in with `summer login`, finds an operation with `summer ops search "<what you want>"` and runs it as `summer <area> <action> --<field> <value>`, with `--dry-run`, `--wait` and `--json`. Engine commands (`summer engine …`) drive the Summer Engine app on your machine. Each skill ends with a table of the command for every tool it names. Add `--assets-only` for only the asset skills. `--no-mcp` is the same as `--cli`.
|
|
46
46
|
|
package/commands/start.md
CHANGED
|
@@ -17,7 +17,7 @@ $ARGUMENTS
|
|
|
17
17
|
## 1. Look before you ask (read-only, a few seconds)
|
|
18
18
|
|
|
19
19
|
- Tools you already have: the `summer-engine` server (local, drives the Summer Engine desktop app; its tools include `summer_get_project_context`) and the `summer-cloud` server (hosted, Summer's cloud; its tools include `summer_whoami`, `summer_search` and `summer_call` once the user is signed in). A server that needs sign-in shows no tools yet.
|
|
20
|
-
- `npx -y summer-engine@latest status` tells you whether the engine is running. If `npx` is missing, there is no Node: plan it first (3a) and have them install Node
|
|
20
|
+
- `npx -y summer-engine@latest status` tells you whether the engine is running. If `npx` is missing, there is no Node: plan it first (3a) and have them install Node 22 or later (nodejs.org) for the build.
|
|
21
21
|
|
|
22
22
|
Do not run `summer setup claude-code` here: this plugin already brings the MCP servers and the skills, and a second copy of the skills only crowds the list.
|
|
23
23
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { type SummerApiDependencies } from "../../core/summer-api.js";
|
|
3
|
+
/**
|
|
4
|
+
* `summer api models|estimate|run|jobs`: the Summer API (core/summer-api.ts)
|
|
5
|
+
* from a shell. JSON when stdout is not a terminal (or with --json); a short
|
|
6
|
+
* summary for people. `--wait` follows a job until it finishes; `--download
|
|
7
|
+
* [dir]` also saves its files. `run --batch file.jsonl` queues up to 500
|
|
8
|
+
* jobs at once (all or none). While Summer has not opened the API, every
|
|
9
|
+
* command prints one line, "Summer API is not open yet.", and exits 1.
|
|
10
|
+
*/
|
|
11
|
+
export interface ApiCommandIo {
|
|
12
|
+
isTTY: boolean;
|
|
13
|
+
print: (line: string) => void;
|
|
14
|
+
printError: (line: string) => void;
|
|
15
|
+
}
|
|
16
|
+
type JsonOption = {
|
|
17
|
+
json?: boolean;
|
|
18
|
+
};
|
|
19
|
+
/** A text file as any system writes it: UTF-8 with or without a BOM, or UTF-16 (Windows PowerShell 5's > and Out-File). */
|
|
20
|
+
export declare function readTextFile(file: string): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* --input: a JSON object, or "@file" with one. Windows PowerShell 5 strips the
|
|
23
|
+
* inner quotes of '{"prompt":"..."}' before the CLI sees them, and cmd.exe has
|
|
24
|
+
* no single quotes, so a file is the dependable way there (quoted: PowerShell
|
|
25
|
+
* reads a bare @ as splatting).
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseInput(text: string | undefined): Promise<Record<string, unknown>>;
|
|
28
|
+
/** Run one api command: its answer as JSON or as the summary, its errors as one line (or one JSON object). */
|
|
29
|
+
export declare function runApiAction(opts: JsonOption, work: () => Promise<{
|
|
30
|
+
data: unknown;
|
|
31
|
+
summary: string[];
|
|
32
|
+
}>, io?: ApiCommandIo): Promise<number>;
|
|
33
|
+
/** run --batch: queue every line of the file as one batch, then --wait and --download as for one job. */
|
|
34
|
+
export declare function runBatch(file: string, opts: {
|
|
35
|
+
idempotencyKey?: string;
|
|
36
|
+
wait?: boolean;
|
|
37
|
+
download?: string | boolean;
|
|
38
|
+
}, overrides?: Partial<SummerApiDependencies>): Promise<{
|
|
39
|
+
data: unknown;
|
|
40
|
+
summary: string[];
|
|
41
|
+
}>;
|
|
42
|
+
export declare const apiCommand: Command;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { API_NOT_OPEN, SummerApiError, cancelJob, createBatch, downloadBatchFiles, downloadJobFiles, estimateJob, getJob, isFinished, listModels, isBatchFinished, parseBatchLines, runJob, waitForBatch, waitForJob, } from "../../core/summer-api.js";
|
|
4
|
+
const defaultIo = () => ({
|
|
5
|
+
isTTY: process.stdout.isTTY === true,
|
|
6
|
+
print: (line) => console.log(line),
|
|
7
|
+
printError: (line) => console.error(line),
|
|
8
|
+
});
|
|
9
|
+
/** A text file as any system writes it: UTF-8 with or without a BOM, or UTF-16 (Windows PowerShell 5's > and Out-File). */
|
|
10
|
+
export async function readTextFile(file) {
|
|
11
|
+
const bytes = await readFile(file);
|
|
12
|
+
if (bytes[0] === 0xff && bytes[1] === 0xfe)
|
|
13
|
+
return bytes.subarray(2).toString("utf16le");
|
|
14
|
+
return bytes.toString("utf8").replace(/^\uFEFF/, "");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* --input: a JSON object, or "@file" with one. Windows PowerShell 5 strips the
|
|
18
|
+
* inner quotes of '{"prompt":"..."}' before the CLI sees them, and cmd.exe has
|
|
19
|
+
* no single quotes, so a file is the dependable way there (quoted: PowerShell
|
|
20
|
+
* reads a bare @ as splatting).
|
|
21
|
+
*/
|
|
22
|
+
export async function parseInput(text) {
|
|
23
|
+
if (!text)
|
|
24
|
+
return {};
|
|
25
|
+
if (text.startsWith("@")) {
|
|
26
|
+
try {
|
|
27
|
+
text = await readTextFile(text.slice(1));
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
throw new SummerApiError("invalid_input", `Cannot read the input file ${text.slice(1)}.`, 400);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
let value;
|
|
34
|
+
try {
|
|
35
|
+
value = JSON.parse(text);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
throw new SummerApiError("invalid_input", "--input must be a JSON object, e.g. --input '{\"prompt\":\"a wooden chest\"}', or a file with one: --input \"@input.json\" (in Windows PowerShell and cmd).", 400);
|
|
39
|
+
}
|
|
40
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
41
|
+
throw new SummerApiError("invalid_input", "--input must be a JSON object.", 400);
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
/** Run one api command: its answer as JSON or as the summary, its errors as one line (or one JSON object). */
|
|
45
|
+
export async function runApiAction(opts, work, io = defaultIo()) {
|
|
46
|
+
const json = opts.json === true || !io.isTTY;
|
|
47
|
+
try {
|
|
48
|
+
const { data, summary } = await work();
|
|
49
|
+
if (json)
|
|
50
|
+
io.print(JSON.stringify(data, null, 2));
|
|
51
|
+
else
|
|
52
|
+
for (const line of summary)
|
|
53
|
+
io.print(line);
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (error instanceof SummerApiError && error.code === "api_not_open") {
|
|
58
|
+
io.printError(API_NOT_OPEN);
|
|
59
|
+
return 1;
|
|
60
|
+
}
|
|
61
|
+
const code = error instanceof SummerApiError ? error.code : "request_failed";
|
|
62
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
63
|
+
// A refused batch's details say how many jobs fit and how much more is needed.
|
|
64
|
+
const details = error instanceof SummerApiError && error.body?.details && typeof error.body.details === "object" ? error.body.details : undefined;
|
|
65
|
+
if (json)
|
|
66
|
+
io.print(JSON.stringify({ ok: false, error: { code, message, ...(details ? { details } : {}) } }));
|
|
67
|
+
else
|
|
68
|
+
io.printError(message);
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function jobSummary(job, files = []) {
|
|
73
|
+
const lines = [`Job ${job.id}: ${job.state}${typeof job.price === "string" ? ` (${job.price} USD)` : typeof job.estimatedPrice === "string" ? ` (estimated ${job.estimatedPrice} USD)` : ""}`];
|
|
74
|
+
const result = (job.result && typeof job.result === "object" ? job.result : {});
|
|
75
|
+
for (const asset of (Array.isArray(result.assets) ? result.assets : [])) {
|
|
76
|
+
lines.push(` ${asset.assetId ?? "asset"}: ${asset.fileUrl ?? ""}`);
|
|
77
|
+
}
|
|
78
|
+
for (const file of files)
|
|
79
|
+
lines.push(` saved ${file}`);
|
|
80
|
+
if (!isFinished(job))
|
|
81
|
+
lines.push(` Follow it: summer api jobs ${job.id} --wait`);
|
|
82
|
+
return lines;
|
|
83
|
+
}
|
|
84
|
+
/** --wait and --download for a job that came back: follow it, then save its files. */
|
|
85
|
+
async function finish(job, opts) {
|
|
86
|
+
const follow = opts.wait === true || opts.download !== undefined;
|
|
87
|
+
const final = follow && !isFinished(job) ? await waitForJob(job) : job;
|
|
88
|
+
const dir = typeof opts.download === "string" ? opts.download : ".";
|
|
89
|
+
const files = opts.download !== undefined && final.state === "done" ? await downloadJobFiles(final, dir) : [];
|
|
90
|
+
return { data: { job: final, ...(opts.download !== undefined ? { files } : {}) }, summary: jobSummary(final, files) };
|
|
91
|
+
}
|
|
92
|
+
function batchSummary(batch, files = {}) {
|
|
93
|
+
const counts = Object.entries(batch.counts ?? {}).map(([state, count]) => `${count} ${state}`).join(", ");
|
|
94
|
+
const lines = [`Batch ${batch.id}: ${batch.jobs.length} jobs${typeof batch.estimatedPrice === "string" ? ` (estimated ${batch.estimatedPrice} USD)` : ""}${counts ? `, ${counts}` : ""}`];
|
|
95
|
+
for (const job of batch.jobs) {
|
|
96
|
+
lines.push(` ${job.id}: ${job.state}${typeof job.model === "string" ? ` ${job.model}` : ""}`);
|
|
97
|
+
for (const file of files[job.id] ?? [])
|
|
98
|
+
lines.push(` saved ${file}`);
|
|
99
|
+
}
|
|
100
|
+
if (!isBatchFinished(batch))
|
|
101
|
+
lines.push(` Follow a job: summer api jobs <id> --wait`);
|
|
102
|
+
return lines;
|
|
103
|
+
}
|
|
104
|
+
/** run --batch: queue every line of the file as one batch, then --wait and --download as for one job. */
|
|
105
|
+
export async function runBatch(file, opts, overrides = {}) {
|
|
106
|
+
let text;
|
|
107
|
+
try {
|
|
108
|
+
text = await readTextFile(file);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
throw new SummerApiError("invalid_input", `Cannot read the batch file ${file}.`, 400);
|
|
112
|
+
}
|
|
113
|
+
const batch = await createBatch(parseBatchLines(text), opts.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}, overrides);
|
|
114
|
+
const follow = opts.wait === true || opts.download !== undefined;
|
|
115
|
+
const final = follow && !isBatchFinished(batch) ? await waitForBatch(batch, {}, overrides) : batch;
|
|
116
|
+
const files = opts.download !== undefined ? await downloadBatchFiles(final, typeof opts.download === "string" ? opts.download : ".", overrides) : undefined;
|
|
117
|
+
return { data: { batch: final, ...(files ? { files } : {}) }, summary: batchSummary(final, files) };
|
|
118
|
+
}
|
|
119
|
+
const exit = (code) => {
|
|
120
|
+
if (code)
|
|
121
|
+
process.exitCode = code;
|
|
122
|
+
};
|
|
123
|
+
const modelsCommand = new Command("models")
|
|
124
|
+
.description("The Summer API's curated game-dev models, with input and price; one model with its id (no sign-in needed)")
|
|
125
|
+
.argument("[model]", "A model id or alias, e.g. 3d/default")
|
|
126
|
+
.option("--capability <capability>", "Only one kind: image, 3d, video, voice, dialogue, sound or music")
|
|
127
|
+
.option("--json", "JSON (the default when stdout is not a terminal)")
|
|
128
|
+
.action(async (model, opts) => exit(await runApiAction(opts, async () => {
|
|
129
|
+
const data = await listModels({ ...(model ? { model } : {}), ...(opts.capability ? { capability: opts.capability } : {}) });
|
|
130
|
+
const models = (Array.isArray(data.models) ? data.models : data.model ? [data.model] : []);
|
|
131
|
+
const price = (entry) => {
|
|
132
|
+
const p = (entry.price && typeof entry.price === "object" ? entry.price : {});
|
|
133
|
+
return typeof p.price === "string" ? `${p.price} USD${typeof p.unit === "string" ? ` per ${p.unit}` : ""}` : "";
|
|
134
|
+
};
|
|
135
|
+
return { data, summary: models.map((entry) => `${String(entry.id).padEnd(28)} ${String(entry.capability ?? "").padEnd(9)} ${price(entry)}`) };
|
|
136
|
+
})));
|
|
137
|
+
const estimateCommand = new Command("estimate")
|
|
138
|
+
.description("The exact price of one job before it runs, and a quote id that holds it for 15 minutes; charges nothing")
|
|
139
|
+
.argument("<model>", "A model id or alias, e.g. 3d/default")
|
|
140
|
+
.option("--input <json>", "The model's input as a JSON object, or @file.json (summer api models <model> shows its schema)")
|
|
141
|
+
.option("--json", "JSON (the default when stdout is not a terminal)")
|
|
142
|
+
.action(async (model, opts) => exit(await runApiAction(opts, async () => {
|
|
143
|
+
const data = await estimateJob(model, await parseInput(opts.input));
|
|
144
|
+
return { data, summary: [`${data.model ?? model}: ${data.atMost ? "at most " : ""}${data.price} ${data.currency ?? "USD"}${data.quoteId ? ` quote ${data.quoteId}` : ""}`] };
|
|
145
|
+
})));
|
|
146
|
+
const runSubcommand = new Command("run")
|
|
147
|
+
.description("Run one job into your Summer assets, or a batch of up to 500 with --batch; spends your paid credits within this app's limit (Connected apps)")
|
|
148
|
+
.argument("[model]", "A model id or alias, e.g. 3d/default (not with --batch)")
|
|
149
|
+
.option("--input <json>", "The model's input as a JSON object, or @file.json")
|
|
150
|
+
.option("--batch <file>", "A JSONL file, one job per line: {\"model\": ..., \"input\": {...}, \"idempotencyKey\": optional}; up to 500, all or none")
|
|
151
|
+
.option("--quote <quoteId>", "From summer api estimate: refuse to charge more than it quoted")
|
|
152
|
+
.option("--idempotency-key <key>", "Reuse to retry the same run or batch without running it twice (default: a new one)")
|
|
153
|
+
.option("--wait", "Follow the job (or every job of the batch) until it finishes")
|
|
154
|
+
.option("--download [dir]", "Follow it and save its files (default: this folder)")
|
|
155
|
+
.option("--json", "JSON (the default when stdout is not a terminal)")
|
|
156
|
+
.action(async (model, opts) => exit(await runApiAction(opts, async () => {
|
|
157
|
+
if (opts.batch) {
|
|
158
|
+
if (model || opts.input || opts.quote)
|
|
159
|
+
throw new SummerApiError("invalid_input", "--batch takes the model and input from each line of its file; leave out <model>, --input and --quote.", 400);
|
|
160
|
+
return runBatch(opts.batch, opts);
|
|
161
|
+
}
|
|
162
|
+
if (!model)
|
|
163
|
+
throw new SummerApiError("invalid_input", "Name a model (summer api run 3d/default --input '{...}'), or pass --batch file.jsonl.", 400);
|
|
164
|
+
const follow = opts.wait === true || opts.download !== undefined;
|
|
165
|
+
const job = await runJob(model, await parseInput(opts.input), {
|
|
166
|
+
...(opts.quote ? { quoteId: opts.quote } : {}),
|
|
167
|
+
...(opts.idempotencyKey ? { idempotencyKey: opts.idempotencyKey } : {}),
|
|
168
|
+
...(follow ? { waitSeconds: 60 } : {}),
|
|
169
|
+
});
|
|
170
|
+
return finish(job, opts);
|
|
171
|
+
})));
|
|
172
|
+
const jobsCommand = new Command("jobs")
|
|
173
|
+
.description("Read a job; --wait follows it, --download saves its files")
|
|
174
|
+
.argument("<jobId>", "The job id summer api run answered")
|
|
175
|
+
.option("--wait", "Follow the job until it finishes")
|
|
176
|
+
.option("--download [dir]", "Follow it and save its files (default: this folder)")
|
|
177
|
+
.option("--cancel", "Ask to stop the job (Summer API jobs, queued or running, run to the end: the answer is unsupported)")
|
|
178
|
+
.option("--json", "JSON (the default when stdout is not a terminal)")
|
|
179
|
+
.action(async (jobId, opts) => exit(await runApiAction(opts, async () => {
|
|
180
|
+
if (opts.cancel) {
|
|
181
|
+
const job = await cancelJob(jobId);
|
|
182
|
+
return { data: { job }, summary: jobSummary(job) };
|
|
183
|
+
}
|
|
184
|
+
return finish(await getJob(jobId), opts);
|
|
185
|
+
})));
|
|
186
|
+
export const apiCommand = new Command("api")
|
|
187
|
+
.description("The Summer API: game-dev models, prices, estimates and jobs, with this computer's Summer sign-in (summer login)")
|
|
188
|
+
.addCommand(modelsCommand)
|
|
189
|
+
.addCommand(estimateCommand)
|
|
190
|
+
.addCommand(runSubcommand)
|
|
191
|
+
.addCommand(jobsCommand);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
+
import { type CliSessionPollDependencies } from "../../core/cli-session.js";
|
|
2
3
|
export declare const loginCommand: Command;
|
|
3
4
|
/** How long `summer login` waits for the store's Allow click after the account sign-in. */
|
|
4
5
|
export declare const STORE_STEP_TIMEOUT_MS: number;
|
|
@@ -27,12 +28,8 @@ export declare function runLoginCommand(opts: {
|
|
|
27
28
|
store?: boolean;
|
|
28
29
|
force?: boolean;
|
|
29
30
|
}, overrides?: Partial<LoginCommandDependencies>): Promise<void>;
|
|
30
|
-
export interface LoginDependencies {
|
|
31
|
-
fetch: typeof fetch;
|
|
31
|
+
export interface LoginDependencies extends CliSessionPollDependencies {
|
|
32
32
|
openUrl: (url: string) => Promise<unknown>;
|
|
33
33
|
randomId: () => string;
|
|
34
|
-
sleep: (ms: number) => Promise<void>;
|
|
35
|
-
now: () => number;
|
|
36
|
-
log: (message: string) => void;
|
|
37
34
|
}
|
|
38
35
|
export declare function runLogin(overrides?: Partial<LoginDependencies>): Promise<void>;
|