summer-engine 2.6.0 → 2.6.3

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/README.md CHANGED
@@ -2,21 +2,48 @@
2
2
 
3
3
  Build real 2D and 3D games through conversation. No coding required. Export to Steam, desktop, mobile, and web. Built on the Godot team's work, customized and honed so AI agents and humans can collaborate on great games.
4
4
 
5
- **Summer** is the MIT open-source agent layer that connects your AI coding agent to Summer Engine: CLI, MCP server, skills, hooks, and plugin manifests. First-class setup works in Claude Code, Cursor, Codex, Windsurf, Cline, Roo Code, Gemini CLI, GitHub Copilot CLI, GitHub Copilot in VS Code, and OpenCode. Factory Droid uses the plugin marketplace path.
5
+ **Summer** is the MIT open-source agent layer that connects your AI coding agent to Summer Engine. It is the **Summer CLI**, the **Summer MCP** server, and the **Summer agent** skills, hooks, and plugin manifests, all in one package. First-class setup works in Claude Code, Cursor, Codex, Devin Desktop (formerly Windsurf), Cline, Roo Code, Gemini CLI, GitHub Copilot CLI, GitHub Copilot in VS Code, and OpenCode. Factory Droid uses the plugin marketplace path.
6
6
 
7
7
  - **Source:** [github.com/SummerEngine/summer-engine-agent](https://github.com/SummerEngine/summer-engine-agent)
8
- - **Docs:** [summerengine.com/docs](https://summerengine.com/docs)
9
- - **MCP setup:** [summerengine.com/mcp](https://summerengine.com/mcp)
8
+ - **CLI setup:** [www.summerengine.com/cli](https://www.summerengine.com/cli)
9
+ - **MCP setup:** [www.summerengine.com/mcp](https://www.summerengine.com/mcp)
10
+ - **Docs:** [docs.summerengine.com](https://docs.summerengine.com)
10
11
 
11
12
  It just works. Open your agent, say *"let's make an FPS in Summer Engine,"* and it does.
12
13
 
13
14
  ---
14
15
 
16
+ ## Summer CLI, Summer MCP, and the Summer agent
17
+
18
+ Three names, one npm package (`summer-engine`):
19
+
20
+ - **Summer CLI** (`npx -y summer-engine@latest`): installs the engine, signs you in, scaffolds and runs projects, and writes your agent's config. See [www.summerengine.com/cli](https://www.summerengine.com/cli).
21
+ - **Summer MCP**: the local MCP server that gives your agent 44 engine tools to build, run, and debug a real game. See [www.summerengine.com/mcp](https://www.summerengine.com/mcp).
22
+ - **Summer agent layer**: the game-dev skills, hooks, and plugin manifests that give your AI agent judgment, not just a chat box.
23
+
24
+ All MIT, all free to use. One paste sets up all three.
25
+
26
+ ## Summer Cloud (new in 2.6.0)
27
+
28
+ `summer cloud` syncs your whole game project across machines: scenes, scripts, settings, and the big binary assets that never fit in git. Files are stored by content hash, every push becomes a restorable version, and local checkpoints are taken before anything destructive touches your disk.
29
+
30
+ ```bash
31
+ summer cloud init # bind this project to your account
32
+ summer cloud push # upload what changed (only missing bytes travel)
33
+ summer cloud pull # make this machine match the cloud, verified by hash
34
+ summer cloud status # what differs between here and the cloud
35
+ summer cloud restore # roll the project back to any version
36
+ ```
37
+
38
+ The same operations are available to agents as MCP tools (`summer_cloud_push`, `summer_cloud_pull`, and friends). See [www.summerengine.com/cloud](https://www.summerengine.com/cloud).
39
+
40
+ ---
41
+
15
42
  ## Get started: one prompt
16
43
 
17
- Open your AI agent (Claude Code, Cursor, Codex, Copilot, Windsurf, etc.) and paste:
44
+ Open your AI agent (Claude Code, Cursor, Codex, Copilot, Devin Desktop, etc.) and paste:
18
45
 
19
- > Install Summer Engine and let's make a game.
46
+ > Install Summer Engine and let's make a game. Read github.com/SummerEngine/summer-engine-agent, check what I already have installed, install whatever is missing, log me in, and scaffold a starter project so we can start building.
20
47
 
21
48
  That's it. The agent reads this README, detects what's already on your machine, and runs only what's missing via Bash. **No `/plugin` slash commands. No manual installs. One paste.**
22
49
 
@@ -75,7 +102,7 @@ The relevant check ids are `node-version`, `cli-version`, `cli-version-current`,
75
102
  npx -y summer-engine@latest setup claude-code --yes --force
76
103
  ```
77
104
 
78
- Replace `claude-code` with the user's actual agent: `codex`, `cursor`, `windsurf`, `cline`, `roo-code`, `gemini`, `github-copilot`, `vscode-copilot`, or `opencode`. Use `github-copilot` for Copilot CLI and `vscode-copilot` for GitHub Copilot Chat/Agent in VS Code. Factory Droid still uses the plugin marketplace path in the install section below. This writes the current Summer skill bundle to `~/.claude/skills/<name>/SKILL.md` (or the agent's equivalent user-skill directory) AND writes the MCP server config so the agent can talk to the engine. The `--force` flag wipes any stale skill content first, so re-runs always end up with the latest copy.
105
+ Replace `claude-code` with the user's actual agent: `codex`, `cursor`, `windsurf`, `cline`, `roo-code`, `kilo-code`, `gemini`, `github-copilot`, `vscode-copilot`, `opencode`, or `lm-studio`. Use `github-copilot` for Copilot CLI and `vscode-copilot` for GitHub Copilot Chat/Agent in VS Code. Factory Droid still uses the plugin marketplace path in the install section below. This writes the current Summer skill bundle to `~/.claude/skills/<name>/SKILL.md` (or the agent's equivalent user-skill directory) AND writes the MCP server config so the agent can talk to the engine. The `--force` flag wipes any stale skill content first, so re-runs always end up with the latest copy.
79
106
 
80
107
  **First-install detection:** if `~/.claude/skills/` didn't exist before this command, Claude Code wasn't watching it and won't auto-detect the new files this session. Tell the user **once**: "Skills installed - restart your agent so they load." On subsequent installs (directory already existed), skills auto-detect mid-session and no restart is needed. **You can detect first-install vs upgrade by checking if `~/.claude/skills/` existed before Step 1; record the result before running setup.**
81
108
 
@@ -165,7 +192,7 @@ Only skip brainstorm if the user explicitly said "skip brainstorm" or "just buil
165
192
  - **Don't loop `summer login` if it times out at 120s.** Re-run it once and tell the user to be quicker; loop forever and the user is stuck.
166
193
  - **Don't jump straight into `summer create` from a vague prompt.** Invoke `summer:brainstorm-game` first (Step 6). The build skills assume `.summer/GameSoul.md` exists.
167
194
 
168
- **Using a different agent?** Replace `claude-code` with any supported agent in Step 1: `codex`, `cursor`, `windsurf`, `cline`, `roo-code`, `gemini`, `github-copilot`, `vscode-copilot`, or `opencode`. Skill targets vary per agent (Cursor uses `.cursor/rules/`, Windsurf uses `.windsurfrules`, Cline + Roo use `.clinerules/`, Copilot uses `~/.copilot/skills` or `.github/skills`, OpenCode uses agent definitions, etc.). The CLI handles the difference. After install, **Cline and Roo Code users should restart VS Code** so the extension reloads its MCP config. **Gemini users** may need to run `gemini extensions enable summer-engine` after the first install. **VS Code Copilot users** should start the `summer-engine` MCP server from Agent mode if VS Code does not autostart it. **Factory Droid** still has its own plugin path below.
195
+ **Using a different agent?** Replace `claude-code` with any supported agent in Step 1: `codex`, `cursor`, `windsurf`, `cline`, `roo-code`, `kilo-code`, `gemini`, `github-copilot`, `vscode-copilot`, `opencode`, or `lm-studio`. (`devin` is also accepted as an alias for `windsurf`.) Skill targets vary per agent (Cursor uses `.cursor/rules/`, Devin Desktop uses `.windsurfrules`, Cline + Roo use `.clinerules/`, Copilot uses `~/.copilot/skills` or `.github/skills`, OpenCode uses agent definitions, etc.). The CLI handles the difference. After install, **Cline and Roo Code users should restart VS Code** so the extension reloads its MCP config. **Gemini users** may need to run `gemini extensions enable summer-engine` after the first install. **VS Code Copilot users** should start the `summer-engine` MCP server from Agent mode if VS Code does not autostart it. **Factory Droid** still has its own plugin path below.
169
196
 
170
197
  **Power-user note:** if the user specifically wants `summer` on their `PATH` for everyday terminal use outside the AI agent, a global npm install is still possible. The agent flow doesn't need it.
171
198
 
@@ -363,7 +390,15 @@ Writes the MCP server config to VS Code's globalStorage for the Cline extension
363
390
  npx -y summer-engine@latest setup roo-code --yes
364
391
  ```
365
392
 
366
- Same shape as Cline (Roo Code is a Cline fork): writes globalStorage MCP config and `.clinerules/` files. **Restart VS Code** afterward.
393
+ Same shape as Cline (Roo Code is a Cline fork): writes globalStorage MCP config and `.clinerules/` files. **Restart VS Code** afterward. Note: Roo Code shut down in May 2026 — prefer Kilo Code, its maintained successor.
394
+
395
+ ### Kilo Code (VS Code)
396
+
397
+ ```bash
398
+ npx -y summer-engine@latest setup kilo-code --yes
399
+ ```
400
+
401
+ Writes the MCP server config to VS Code's globalStorage for the Kilo Code extension (project scope writes `.kilocode/mcp.json`) and drops rules into `.kilocode/rules/`. **Restart VS Code** so Kilo reloads its MCP config.
367
402
 
368
403
  ### Gemini CLI
369
404
 
@@ -397,7 +432,19 @@ npx -y summer-engine@latest setup opencode --yes
397
432
 
398
433
  Writes the MCP server entry into `opencode.json` (`~/.config/opencode/opencode.json` for user scope, `./opencode.json` for project) using the array-shaped `command: ["npx", "-y", "summer-engine@latest", "mcp"]` format. Restart OpenCode. Full guide: [`.opencode/INSTALL.md`](./.opencode/INSTALL.md).
399
434
 
400
- ### Windsurf and others
435
+ ### LM Studio (local models)
436
+
437
+ ```bash
438
+ npx -y summer-engine@latest setup lm-studio --yes
439
+ ```
440
+
441
+ Writes the MCP server entry into `~/.lmstudio/mcp.json` (app-global; there is no project scope). In LM Studio, toggle the `summer-engine` server on in the **Program** tab, and raise the loaded model's context length to **32k or higher** — MCP tool schemas overflow small contexts silently. LM Studio has no rules/skills folder; the MCP server's `summer_get_agent_playbook` tool covers in-chat guidance. Pair with a tool-calling-reliable local model (gpt-oss-20b on 12–16 GB VRAM, Qwen3-Coder-30B on 24 GB).
442
+
443
+ ### Ollama (local models)
444
+
445
+ Ollama is the model backend, not an MCP client — pair it with OpenCode, Kilo Code, or Goose and point that agent's provider at `http://localhost:11434/v1`. Before connecting MCP, raise Ollama's context window (defaults to 4k under 24 GB VRAM): start with `OLLAMA_CONTEXT_LENGTH=65536 ollama serve`, then `ollama ps` to confirm the model still fits on the GPU.
446
+
447
+ ### Devin Desktop (formerly Windsurf) and others
401
448
 
402
449
  ```bash
403
450
  npx -y summer-engine@latest setup <agent> --yes --force
@@ -429,7 +476,7 @@ npx -y summer-engine@latest doctor
429
476
  | `summer mcp setup <agent>` | Write MCP config for an agent. |
430
477
  | `summer setup <agent> [--yes]` | One shot: MCP config + recommended skills + doctor. |
431
478
 
432
- Agents: `claude-code`, `codex`, `cursor`, `windsurf`, `cline`, `roo-code`, `gemini`, `opencode`. Scopes: `--scope user` (default), `--scope project`.
479
+ Agents: `claude-code`, `codex`, `cursor`, `windsurf`, `cline`, `roo-code`, `kilo-code`, `gemini`, `github-copilot`, `vscode-copilot`, `opencode`, `lm-studio`. (`devin` and `devin-desktop` are accepted as aliases for `windsurf`.) Scopes: `--scope user` (default), `--scope project`.
433
480
 
434
481
  ---
435
482
 
@@ -56,7 +56,7 @@ function printIntro(version) {
56
56
  console.log(` ${sym.arrow()} ${c.bold("Summer Engine")} ${c.dim("v" + version)} ${c.dim("·")} AI-native game engine`);
57
57
  console.log("");
58
58
  console.log(` ${c.bold("Setup wizard")}`);
59
- console.log(` Open Claude Code, Cursor, Codex, Copilot, Windsurf, or another supported agent and paste:`);
59
+ console.log(` Open Claude Code, Cursor, Codex, Copilot, Devin Desktop (formerly Windsurf), or another supported agent and paste:`);
60
60
  console.log(` ${c.brand("\"Install Summer Engine and let's make a game.\"")}`);
61
61
  console.log("");
62
62
  console.log(` ${c.bold("Manual commands")}`);
@@ -10,13 +10,15 @@ const AGENT_LABEL = {
10
10
  "claude-code": "Claude Code",
11
11
  codex: "Codex",
12
12
  cursor: "Cursor",
13
- windsurf: "Windsurf",
13
+ windsurf: "Devin Desktop (Windsurf)",
14
14
  cline: "Cline",
15
15
  "roo-code": "Roo Code",
16
+ "kilo-code": "Kilo Code",
16
17
  gemini: "Gemini CLI",
17
18
  "github-copilot": "GitHub Copilot CLI",
18
19
  "vscode-copilot": "GitHub Copilot in VS Code",
19
20
  opencode: "OpenCode",
21
+ "lm-studio": "LM Studio",
20
22
  };
21
23
  export const setupCommand = new Command("setup")
22
24
  .description("Configure Summer Engine for an AI agent and run diagnostics")
@@ -76,6 +78,12 @@ function resolveScope(scopeOpt) {
76
78
  return parsed;
77
79
  }
78
80
  function setupRecommendedSkills(agent, options) {
81
+ if (agent === "lm-studio") {
82
+ return {
83
+ status: "skipped",
84
+ message: "LM Studio has no rules or skills folder. The MCP server ships summer_get_agent_playbook, so the model can pull Summer guidance in-chat.",
85
+ };
86
+ }
79
87
  const invocation = skillInstallInvocation(agent, { force: options.force });
80
88
  if (!invocation) {
81
89
  return {
@@ -113,7 +113,8 @@ function resolveScope(agent, opts) {
113
113
  if (agent === "cursor" ||
114
114
  agent === "windsurf" ||
115
115
  agent === "cline" ||
116
- agent === "roo-code") {
116
+ agent === "roo-code" ||
117
+ agent === "kilo-code") {
117
118
  return "project";
118
119
  }
119
120
  return "user";
@@ -127,11 +128,13 @@ function agentLabel(agent) {
127
128
  case "cursor":
128
129
  return "Cursor";
129
130
  case "windsurf":
130
- return "Windsurf";
131
+ return "Devin Desktop (Windsurf)";
131
132
  case "cline":
132
133
  return "Cline";
133
134
  case "roo-code":
134
135
  return "Roo Code";
136
+ case "kilo-code":
137
+ return "Kilo Code";
135
138
  case "gemini":
136
139
  return "Gemini CLI";
137
140
  case "github-copilot":
@@ -152,7 +155,7 @@ function resolveInstallLocation(agent, scope) {
152
155
  if (agent === "windsurf") {
153
156
  return { kind: "windsurf-rule-file", path: join(overrideDir, ".windsurfrules") };
154
157
  }
155
- if (agent === "cline" || agent === "roo-code") {
158
+ if (agent === "cline" || agent === "roo-code" || agent === "kilo-code") {
156
159
  return { kind: "cline-rule-dir", path: overrideDir };
157
160
  }
158
161
  if (agent === "gemini") {
@@ -187,6 +190,13 @@ function resolveInstallLocation(agent, scope) {
187
190
  ? rooCodeUserRulesDir()
188
191
  : join(process.cwd(), ".clinerules"),
189
192
  };
193
+ case "kilo-code":
194
+ return {
195
+ kind: "cline-rule-dir",
196
+ path: scope === "user"
197
+ ? join(homedir(), ".kilocode", "rules")
198
+ : join(process.cwd(), ".kilocode", "rules"),
199
+ };
190
200
  case "gemini":
191
201
  return {
192
202
  kind: "gemini-skill-dir",
@@ -390,7 +400,7 @@ function printInstallSummary(count, agent, scope, location) {
390
400
  console.log("Restart OpenCode so it picks up the new agent definitions.");
391
401
  }
392
402
  else {
393
- console.log(`Windsurf rules are in ${tildeified}`);
403
+ console.log(`Devin Desktop (formerly Windsurf) rules are in ${tildeified}`);
394
404
  }
395
405
  }
396
406
  export const skillsCommand = new Command("skills")
@@ -484,7 +494,7 @@ function installClaudeCommands(scope, force) {
484
494
  }
485
495
  /**
486
496
  * Drop a `.summer-version` marker into the install dir so doctor's
487
- * `skills-version-stale` check can detect drift later. Windsurf writes a
497
+ * `skills-version-stale` check can detect drift later. Devin Desktop (formerly Windsurf) writes a
488
498
  * single rules file with no surrounding dir, so we skip it there.
489
499
  */
490
500
  function writeMarkerForLocation(location) {
@@ -1,5 +1,5 @@
1
1
  export declare const SUMMER_MCP_SERVER_NAME = "summer-engine";
2
- export declare const supportedAgents: readonly ["codex", "claude-code", "cursor", "windsurf", "cline", "roo-code", "gemini", "github-copilot", "vscode-copilot", "opencode"];
2
+ export declare const supportedAgents: readonly ["codex", "claude-code", "cursor", "windsurf", "cline", "roo-code", "kilo-code", "gemini", "github-copilot", "vscode-copilot", "opencode", "lm-studio"];
3
3
  export type SupportedAgent = (typeof supportedAgents)[number];
4
4
  export type ConfigScope = "user" | "project";
5
5
  export interface StdioMcpServerConfig {
@@ -11,10 +11,12 @@ export const supportedAgents = [
11
11
  "windsurf",
12
12
  "cline",
13
13
  "roo-code",
14
+ "kilo-code",
14
15
  "gemini",
15
16
  "github-copilot",
16
17
  "vscode-copilot",
17
18
  "opencode",
19
+ "lm-studio",
18
20
  ];
19
21
  const agentAliases = {
20
22
  claude: "claude-code",
@@ -22,10 +24,16 @@ const agentAliases = {
22
24
  codex: "codex",
23
25
  cursor: "cursor",
24
26
  windsurf: "windsurf",
27
+ devin: "windsurf",
28
+ "devin-desktop": "windsurf",
29
+ devindesktop: "windsurf",
25
30
  cline: "cline",
26
31
  "roo-code": "roo-code",
27
32
  roo: "roo-code",
28
33
  roocode: "roo-code",
34
+ kilo: "kilo-code",
35
+ kilocode: "kilo-code",
36
+ "kilo-code": "kilo-code",
29
37
  gemini: "gemini",
30
38
  "gemini-cli": "gemini",
31
39
  copilot: "github-copilot",
@@ -39,6 +47,9 @@ const agentAliases = {
39
47
  "github-copilot-vscode": "vscode-copilot",
40
48
  opencode: "opencode",
41
49
  "open-code": "opencode",
50
+ lmstudio: "lm-studio",
51
+ "lm-studio": "lm-studio",
52
+ "lm_studio": "lm-studio",
42
53
  };
43
54
  export function parseAgent(value) {
44
55
  if (!value)
@@ -148,7 +159,7 @@ function resolveConfigTarget(agent, scope, cwd, env) {
148
159
  const warnings = [];
149
160
  if (override) {
150
161
  if (scope === "project" &&
151
- (agent === "cline" || agent === "roo-code" || agent === "gemini")) {
162
+ (agent === "cline" || agent === "roo-code" || agent === "gemini" || agent === "lm-studio")) {
152
163
  warnings.push(`${agent} MCP config has no project scope today; treating as user scope.`);
153
164
  }
154
165
  return {
@@ -212,6 +223,25 @@ function resolveConfigTarget(agent, scope, cwd, env) {
212
223
  warnings,
213
224
  };
214
225
  }
226
+ if (agent === "kilo-code") {
227
+ return {
228
+ path: scope === "user"
229
+ ? vsCodeGlobalStoragePath(env, "kilocode.kilo-code", "mcp_settings.json")
230
+ : join(cwd, ".kilocode", "mcp.json"),
231
+ format: "json",
232
+ warnings,
233
+ };
234
+ }
235
+ if (agent === "lm-studio") {
236
+ if (scope === "project") {
237
+ warnings.push("LM Studio's MCP config is app-global (~/.lmstudio/mcp.json); treating as user scope.");
238
+ }
239
+ return {
240
+ path: join(homedir(), ".lmstudio", "mcp.json"),
241
+ format: "json",
242
+ warnings,
243
+ };
244
+ }
215
245
  if (agent === "gemini") {
216
246
  if (scope === "project") {
217
247
  warnings.push("Gemini extensions are user-scoped today; writing to ~/.gemini/extensions/summer-engine/ instead of project.");
@@ -250,7 +280,7 @@ function resolveConfigTarget(agent, scope, cwd, env) {
250
280
  };
251
281
  }
252
282
  if (scope === "project") {
253
- warnings.push("Windsurf documents MCP configuration as user-scoped; project scope writes .windsurf/mcp_config.json for teams that load workspace config.");
283
+ warnings.push("Devin Desktop (formerly Windsurf) documents MCP configuration as user-scoped; project scope writes .windsurf/mcp_config.json for teams that load workspace config.");
254
284
  }
255
285
  return {
256
286
  path: scope === "user"
@@ -260,18 +290,18 @@ function resolveConfigTarget(agent, scope, cwd, env) {
260
290
  warnings,
261
291
  };
262
292
  }
263
- function vsCodeGlobalStoragePath(env, extensionId) {
293
+ function vsCodeGlobalStoragePath(env, extensionId, fileName = "cline_mcp_settings.json") {
264
294
  const os = platform();
265
295
  if (os === "win32") {
266
296
  const appData = env.APPDATA ?? join(homedir(), "AppData", "Roaming");
267
- return join(appData, "Code", "User", "globalStorage", extensionId, "settings", "cline_mcp_settings.json");
297
+ return join(appData, "Code", "User", "globalStorage", extensionId, "settings", fileName);
268
298
  }
269
299
  if (os === "darwin") {
270
- return join(homedir(), "Library", "Application Support", "Code", "User", "globalStorage", extensionId, "settings", "cline_mcp_settings.json");
300
+ return join(homedir(), "Library", "Application Support", "Code", "User", "globalStorage", extensionId, "settings", fileName);
271
301
  }
272
302
  // Linux and other Unix
273
303
  const xdg = env.XDG_CONFIG_HOME ?? join(homedir(), ".config");
274
- return join(xdg, "Code", "User", "globalStorage", extensionId, "settings", "cline_mcp_settings.json");
304
+ return join(xdg, "Code", "User", "globalStorage", extensionId, "settings", fileName);
275
305
  }
276
306
  function opencodeUserConfigPath(env) {
277
307
  const os = platform();
@@ -305,6 +335,10 @@ function getConfigPathOverride(agent, env) {
305
335
  return env.SUMMER_CLINE_CONFIG_FILE;
306
336
  if (agent === "roo-code")
307
337
  return env.SUMMER_ROO_CODE_CONFIG_FILE;
338
+ if (agent === "kilo-code")
339
+ return env.SUMMER_KILO_CODE_CONFIG_FILE;
340
+ if (agent === "lm-studio")
341
+ return env.SUMMER_LM_STUDIO_CONFIG_FILE;
308
342
  if (agent === "gemini")
309
343
  return env.SUMMER_GEMINI_CONFIG_FILE;
310
344
  if (agent === "github-copilot")
@@ -558,15 +592,19 @@ function createNextSteps(agent, scope, path) {
558
592
  ? "Restart VS Code so Cline reloads its MCP config."
559
593
  : agent === "roo-code"
560
594
  ? "Restart VS Code so Roo Code reloads its MCP config."
561
- : agent === "gemini"
562
- ? "Run `gemini extensions enable summer-engine` (if not already enabled), then restart Gemini CLI."
563
- : agent === "github-copilot"
564
- ? "Restart Copilot CLI, or run /mcp reload and /skills reload in the active session."
565
- : agent === "vscode-copilot"
566
- ? "Restart VS Code or run MCP: List Servers, then start summer-engine in Copilot Agent mode."
567
- : agent === "opencode"
568
- ? "Restart OpenCode so it reloads opencode.json."
569
- : "Restart Windsurf and refresh MCP servers from Cascade settings.";
595
+ : agent === "kilo-code"
596
+ ? "Restart VS Code so Kilo Code reloads its MCP config."
597
+ : agent === "lm-studio"
598
+ ? "Open LM Studio, toggle on the summer-engine MCP server in the Program tab, and raise the loaded model's context length to 32k or higher."
599
+ : agent === "gemini"
600
+ ? "Run `gemini extensions enable summer-engine` (if not already enabled), then restart Gemini CLI."
601
+ : agent === "github-copilot"
602
+ ? "Restart Copilot CLI, or run /mcp reload and /skills reload in the active session."
603
+ : agent === "vscode-copilot"
604
+ ? "Restart VS Code or run MCP: List Servers, then start summer-engine in Copilot Agent mode."
605
+ : agent === "opencode"
606
+ ? "Restart OpenCode so it reloads opencode.json."
607
+ : "Restart Devin Desktop (formerly Windsurf) and refresh MCP servers from the agent settings.";
570
608
  const projectTrust = scope === "project" && agent === "codex"
571
609
  ? "Codex only loads project .codex/config.toml from trusted projects."
572
610
  : null;
@@ -2,6 +2,10 @@ export type EngineSnapshot = {
2
2
  ok: boolean;
3
3
  localPath?: string;
4
4
  path?: string;
5
+ /** Raw image bytes, base64-encoded. Carried so a caller (e.g. the MCP
6
+ * screenshot tool) can return an MCP image content block to a vision-capable
7
+ * client without re-reading localPath off disk. */
8
+ base64?: string;
5
9
  width?: number;
6
10
  height?: number;
7
11
  format?: string;
@@ -50,4 +54,17 @@ export declare class EngineApiClient {
50
54
  viewportSnapshot(): Promise<EngineSnapshot>;
51
55
  gameSnapshot(): Promise<EngineSnapshot>;
52
56
  getPort(): number;
57
+ /**
58
+ * Cheap drift probe for the MCP client cache. The engine mints a fresh
59
+ * api-token on every launch (local_api_server.cpp::_generate_api_token) and can
60
+ * bind a different port (tool_net_thread.cpp::start increments 6550..6565 when
61
+ * the old socket lingers), so a client built before an engine restart holds
62
+ * dead credentials. Re-read the on-disk creds and report whether they no longer
63
+ * match this client's snapshot.
64
+ *
65
+ * Empty / unreadable creds (engine mid-write, or just closed) are treated as
66
+ * "no drift" so a transient read never thrashes the cache — the live request
67
+ * will fail and trigger a reconnect+retry if the client really is stale.
68
+ */
69
+ credentialsChanged(): Promise<boolean>;
53
70
  }
@@ -172,7 +172,10 @@ export class EngineApiClient {
172
172
  }
173
173
  async play(scene) {
174
174
  // Cold-load on large projects can take 25-40s. 60s budget.
175
- return this._requestQueued("POST", "/api/play", scene ? { scene } : {}, 60_000);
175
+ // The engine reads play params from body.options (tool_net_thread.cpp:503),
176
+ // and the play handler reads options["scene"] — a top-level { scene } is
177
+ // dropped, so the scene MUST be nested inside options.
178
+ return this._requestQueued("POST", "/api/play", scene ? { options: { scene } } : {}, 60_000);
176
179
  }
177
180
  async stop() {
178
181
  return this._requestQueued("POST", "/api/stop", undefined, 15_000);
@@ -237,6 +240,7 @@ export class EngineApiClient {
237
240
  ok: payload.ok !== false,
238
241
  localPath,
239
242
  path: localPath,
243
+ base64,
240
244
  width: numberFrom(payload.width),
241
245
  height: numberFrom(payload.height),
242
246
  format,
@@ -257,4 +261,27 @@ export class EngineApiClient {
257
261
  getPort() {
258
262
  return this.port;
259
263
  }
264
+ /**
265
+ * Cheap drift probe for the MCP client cache. The engine mints a fresh
266
+ * api-token on every launch (local_api_server.cpp::_generate_api_token) and can
267
+ * bind a different port (tool_net_thread.cpp::start increments 6550..6565 when
268
+ * the old socket lingers), so a client built before an engine restart holds
269
+ * dead credentials. Re-read the on-disk creds and report whether they no longer
270
+ * match this client's snapshot.
271
+ *
272
+ * Empty / unreadable creds (engine mid-write, or just closed) are treated as
273
+ * "no drift" so a transient read never thrashes the cache — the live request
274
+ * will fail and trigger a reconnect+retry if the client really is stale.
275
+ */
276
+ async credentialsChanged() {
277
+ try {
278
+ const [port, token] = await Promise.all([getApiPort(), getApiToken()]);
279
+ if (!token)
280
+ return false;
281
+ return port !== this.port || token !== this.token;
282
+ }
283
+ catch {
284
+ return false;
285
+ }
286
+ }
260
287
  }