summer-engine 1.4.0 → 2.0.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 (63) hide show
  1. package/.claude-plugin/plugin.json +18 -10
  2. package/.codex-plugin/plugin.json +36 -8
  3. package/.cursor-plugin/plugin.json +19 -11
  4. package/.opencode/INSTALL.md +69 -0
  5. package/.opencode/plugins/summer.js +9 -4
  6. package/CHANGELOG.md +31 -1
  7. package/README.md +268 -86
  8. package/dist/bin/summer.js +0 -0
  9. package/dist/commands/assets.d.ts +2 -0
  10. package/dist/commands/assets.js +189 -0
  11. package/dist/commands/create.js +55 -17
  12. package/dist/commands/debug.d.ts +2 -0
  13. package/dist/commands/debug.js +127 -0
  14. package/dist/commands/list.js +24 -5
  15. package/dist/commands/project.d.ts +2 -0
  16. package/dist/commands/project.js +170 -0
  17. package/dist/commands/scene.d.ts +2 -0
  18. package/dist/commands/scene.js +290 -0
  19. package/dist/lib/banner.js +2 -2
  20. package/dist/lib/log-filters.d.ts +53 -0
  21. package/dist/lib/log-filters.js +130 -0
  22. package/dist/lib/plugin-manifests.test.d.ts +1 -0
  23. package/dist/lib/plugin-manifests.test.js +134 -0
  24. package/dist/lib/remote-templates.d.ts +25 -0
  25. package/dist/lib/remote-templates.js +86 -0
  26. package/dist/lib/skills-registry.d.ts +33 -1
  27. package/dist/lib/skills-registry.js +56 -1
  28. package/dist/lib/telemetry.d.ts +13 -0
  29. package/dist/lib/telemetry.js +63 -0
  30. package/dist/lib/with-engine.d.ts +14 -0
  31. package/dist/lib/with-engine.js +109 -0
  32. package/dist/mcp/tools/asset-tools.js +12 -13
  33. package/dist/mcp/tools/debug-tools.js +32 -9
  34. package/dist/mcp/tools/with-engine.js +4 -0
  35. package/gemini-extension.json +2 -2
  36. package/hooks/pre-commit-doctor.sh +0 -0
  37. package/hooks/run-hook.cmd +0 -0
  38. package/hooks/session-start.sh +0 -0
  39. package/marketplace.json +2 -2
  40. package/package.json +3 -3
  41. package/skills/README.md +1 -1
  42. package/skills/_meta/skill-create/SKILL.md +1 -1
  43. package/skills/_meta/skill-improve/SKILL.md +1 -1
  44. package/skills/_meta/skill-test/SKILL.md +1 -1
  45. package/skills/_meta/using-summer/SKILL.md +130 -0
  46. package/skills/_tests/specs/design-npc.md +43 -12
  47. package/skills/_tests/specs/fps-controller.md +33 -20
  48. package/skills/_tests/specs/host-authoritative-state.md +104 -0
  49. package/skills/_tests/specs/vfx.md +56 -38
  50. package/skills/ai-and-npcs/design-npc/SKILL.md +264 -122
  51. package/skills/asset-pipeline/asset-strategy/SKILL.md +1 -1
  52. package/skills/catalog.yaml +21 -4
  53. package/skills/character-controllers/fps-controller/SKILL.md +260 -79
  54. package/skills/debugging/debug/SKILL.md +102 -82
  55. package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +332 -0
  56. package/skills/rendering-and-lighting/3d-lighting/SKILL.md +1 -1
  57. package/skills/scene-and-project/browse-templates/SKILL.md +105 -0
  58. package/skills/scene-and-project/make-game/SKILL.md +159 -346
  59. package/skills/scene-and-project/new-project/SKILL.md +106 -0
  60. package/skills/scene-and-project/scene-composition/SKILL.md +1 -1
  61. package/skills/scripting-patterns/gdscript-patterns/SKILL.md +1 -1
  62. package/skills/ui-and-ux/ui-basics/SKILL.md +1 -1
  63. package/skills/visual-effects/vfx/SKILL.md +233 -134
package/README.md CHANGED
@@ -1,103 +1,237 @@
1
- # Summer Engine CLI
1
+ # Summer
2
2
 
3
- CLI and MCP tools for [Summer Engine](https://summerengine.com) — the AI-native game engine. MIT licensed.
3
+ **Summer Engine is the AI game engine.** 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
- ## Install
5
+ This repo is **Summer's open-source agent layer** — a skills framework that gives any coding agent superpowers for game dev. Install once, works everywhere: Claude Code, Cursor, Codex CLI / App, Gemini CLI, OpenCode, Factory Droid, GitHub Copilot CLI, Windsurf. MIT licensed.
6
+
7
+ It just works. Open your agent, say "let's make an FPS in Summer Engine," and it does.
8
+
9
+ ---
10
+
11
+ ## Install Summer in your agent
12
+
13
+ Pick your tool. If you use more than one, install for each.
14
+
15
+ | Agent | Command |
16
+ |---|---|
17
+ | **[Claude Code](#claude-code)** | `claude /plugin install summer@summer-marketplace` |
18
+ | **[Codex CLI](#codex-cli)** | `/plugins` → search `summer` → install |
19
+ | **[Codex App](#codex-app)** | Plugins → Coding → Summer → `+` |
20
+ | **[Cursor](#cursor)** | `/add-plugin summer` |
21
+ | **[Factory Droid](#factory-droid)** | `droid plugin install summer@summer-marketplace` |
22
+ | **[Gemini CLI](#gemini-cli)** | `gemini extensions install https://github.com/SummerEngine/summer` |
23
+ | **[GitHub Copilot CLI](#github-copilot-cli)** | `copilot plugin install summer@summer-marketplace` |
24
+ | **[OpenCode](#opencode)** | Tell it: *"Fetch and follow https://raw.githubusercontent.com/SummerEngine/summer/main/.opencode/INSTALL.md"* |
25
+ | **[Windsurf / others](#windsurf-and-others)** | `npm i -g summer-engine && summer setup <agent> --yes` |
26
+
27
+ Then talk to your agent:
28
+
29
+ > Let's make an FPS in Summer Engine.
30
+
31
+ It loads the right skills, asks what you want, and starts building. That's it.
32
+
33
+ ---
34
+
35
+ ## You'll also need Summer Engine
36
+
37
+ Most skills need the engine running locally.
6
38
 
7
39
  ```bash
8
40
  npm install -g summer-engine
41
+ summer install # downloads Summer Engine — see "What gets downloaded" below
42
+ summer login
43
+ summer create 3d-basic my-game
44
+ summer run my-game
9
45
  ```
10
46
 
11
- Or use without installing:
47
+ Or download it directly: **[summerengine.com/download](https://summerengine.com/download)**.
48
+
49
+ You can install the agent plugin first and the engine later — most tools tell you what to do when the engine isn't running.
50
+
51
+ ---
52
+
53
+ ## What gets downloaded
54
+
55
+ We tell you before we touch your disk.
56
+
57
+ | What | Size | When | Source |
58
+ |---|---|---|---|
59
+ | `summer-engine` npm package | ~3 MB | `npm install -g summer-engine` | [npmjs.com/package/summer-engine](https://www.npmjs.com/package/summer-engine) |
60
+ | Summer Engine app | ~145 MB | `summer install` | Summer's signed releases |
61
+ | Auth token | ~1 KB | `summer login` | Browser → `~/.summer/auth-token` |
62
+ | Skill files | < 50 KB | bundled in the npm package | no network call |
63
+ | Generated assets (3D / image / audio / video) | varies | only on explicit `summer_generate_*` calls | Summer Engine Studio |
64
+ | URL imports | varies | only on explicit `summer_import_from_url` calls | the URL you provide |
65
+
66
+ Not downloaded:
67
+ - No background telemetry. Diagnostics stay local.
68
+ - No silent engine updates. You run `summer update` manually.
69
+ - No model weights or AI binaries. Generation runs in Summer Engine Studio.
70
+
71
+ Every install command takes `--dry-run`. Print the URL, target path, and SHA before anything moves.
72
+
73
+ ---
74
+
75
+ ## What's open and what's not
76
+
77
+ | Thing | License | Source |
78
+ |---|---|---|
79
+ | **Summer** (this repo: skills, MCP server, CLI, hooks, plugin manifests) | **MIT** | [SummerEngine/summer](https://github.com/SummerEngine/summer) |
80
+ | **Summer Engine** (the engine binary, editor, runtime) | proprietary, free to use | [summerengine.com/download](https://summerengine.com/download) |
81
+ | **Summer Engine Studio** (asset generation, cloud) | proprietary, paid plans | [summerengine.com/pricing](https://summerengine.com/pricing) |
82
+
83
+ The engine is the moat. The agent layer is open so you can audit it, fork it, extend the skills, and contribute back.
84
+
85
+ ---
86
+
87
+ ## How it works
88
+
89
+ Two pieces, plus the glue.
90
+
91
+ **Skills.** Twenty-four markdown files. Each one is a discipline guide for the agent. They auto-fire on natural language:
92
+
93
+ - "Let's brainstorm a game" → `summer:brainstorm-game`
94
+ - "It crashes when I press play" → `summer:debug`
95
+ - "Add an FPS controller" → `summer:fps-controller`
96
+ - "Make it look prettier" → `summer:art-direction`
97
+ - "Set up multiplayer" → `summer:setup-multiplayer` → `summer:host-authoritative-state`
98
+
99
+ Skills don't list steps. They encode the **order of operations**: diagnose before editing, scope before building, ask before guessing. [Agent Skills](https://agentskills.io) format, so any conformant tool picks them up.
100
+
101
+ **MCP bridge.** The `summer-engine` MCP server gives the agent 37 tools that talk to your local engine on `localhost:6550`:
102
+
103
+ | | |
104
+ |---|---|
105
+ | Scene | `summer_add_node`, `summer_set_prop`, `summer_replace_node`, `summer_get_scene_tree`, `summer_inspect_node`, `summer_batch` |
106
+ | Diagnostics | `summer_get_script_errors`, `summer_get_diagnostics`, `summer_get_console`, `summer_get_debugger_errors` |
107
+ | Runtime | `summer_play`, `summer_stop`, `summer_is_running` |
108
+ | Project | `summer_get_project_context`, `summer_open_main_scene`, `summer_project_setting`, `summer_input_map_bind` |
109
+ | Assets | `summer_search_assets`, `summer_import_asset`, `summer_import_from_url`, `summer_generate_image`, `summer_generate_3d`, `summer_generate_audio`, `summer_generate_video` |
110
+
111
+ File ops, git, shell, grep — your agent already has those. We don't shadow them.
112
+
113
+ **Lifecycle hooks.** A `session-start` hook detects whether you're in a Summer Engine project and feeds the agent a one-line orientation. An opt-in `pre-commit doctor` runs `summer doctor` before `git commit` and blocks on failure.
114
+
115
+ For the full architecture, see [docs/OVERVIEW.md](docs/OVERVIEW.md).
116
+
117
+ ---
118
+
119
+ ## The basic workflow
120
+
121
+ 1. **using-summer** loads on session start. Sets workflow priority and the red-flag list.
122
+ 2. **brainstorm-game** scopes a new project. One question, one page, one direction.
123
+ 3. **scene-composition** picks the right hierarchy before any node lands.
124
+ 4. **fps-controller / design-mechanic / design-level / setup-multiplayer / vfx** produce the artifact.
125
+ 5. **gdscript-patterns** guides every `.gd` write.
126
+ 6. **play** runs the game and reports clean or broken.
127
+ 7. **debug** runs the cheapest diagnostic, forms one specific hypothesis, asks before editing, re-verifies after the fix.
128
+ 8. **export-and-ship** runs the pre-flight checklist before producing a release build.
129
+
130
+ Twenty-four skills replace "agent flailing through tutorials" with measurable craft.
131
+
132
+ ---
133
+
134
+ ## What's inside
135
+
136
+ **Process** — `using-summer`, `brainstorm-game`, `debug`, `play`
137
+
138
+ **Project setup** — `new-project`, `browse-templates`, `make-game`, `scene-composition`
139
+
140
+ **Build** — `fps-controller`, `design-mechanic`, `design-level`, `design-npc`
141
+
142
+ **Multiplayer** — `setup-multiplayer`, `host-authoritative-state`, `peer-to-peer-multiplayer`
143
+
144
+ **Look & feel** — `art-direction`, `audio-direction`, `3d-lighting`, `vfx`, `ui-basics`
145
+
146
+ **Code & assets** — `gdscript-patterns`, `asset-strategy`
147
+
148
+ **Performance & ship** — `tune-performance`, `export-and-ship`
149
+
150
+ **Skill authoring** — `skill-create`, `skill-improve`, `skill-test`
151
+
152
+ C# is supported by the engine. A `summer:csharp-patterns` skill is on the roadmap; for now write C# from Godot 4.5 docs.
153
+
154
+ Full catalog with HAVE / NEXT / LATER status: [`skills/catalog.yaml`](./skills/catalog.yaml).
155
+
156
+ ## Philosophy
157
+
158
+ - Skills auto-fire on natural language. No slash command required.
159
+ - Diagnose before guessing. Read the error before grepping the code.
160
+ - Process skills run before build skills.
161
+ - Fewer tools, sharper tools.
162
+ - The user owns decisions. The agent diagnoses and proposes.
163
+
164
+ ---
165
+
166
+ ## Install — full instructions per harness
167
+
168
+ ### Claude Code
12
169
 
13
170
  ```bash
14
- npx summer-engine <command>
171
+ claude /plugin marketplace add SummerEngine/summer-marketplace
172
+ claude /plugin install summer@summer-marketplace
15
173
  ```
16
174
 
17
- ## Quickstart (under 2 minutes)
175
+ When Summer lands on Anthropic's official marketplace, also:
18
176
 
19
177
  ```bash
20
- summer install # Download the engine
21
- summer login # Sign in via browser
22
- summer create 3d-basic my-game # Create a starter project
23
- summer run my-game # Open it in the engine
24
- summer setup claude-code --yes # Configure MCP + install recommended skills
178
+ claude /plugin install summer@claude-plugins-official
25
179
  ```
26
180
 
27
- Replace `claude-code` with `codex`, `cursor`, or `windsurf`. Add `--scope project` to keep the configuration inside the project.
181
+ ### Codex CLI
28
182
 
29
- Verify:
183
+ ```
184
+ /plugins
185
+ ```
30
186
 
31
- ```bash
32
- summer doctor
187
+ Search `summer`, install.
188
+
189
+ ### Codex App
190
+
191
+ Sidebar → **Plugins** → **Coding** → click `+` next to **Summer**.
192
+
193
+ ### Cursor
194
+
195
+ ```
196
+ /add-plugin summer
33
197
  ```
34
198
 
35
- Then open your agent and try one of the slash commands:
199
+ Or search `summer` in the Cursor plugin marketplace.
36
200
 
37
- | Command | What it does |
38
- |---|---|
39
- | `/debug` | Triage and fix a bug end-to-end (reads engine errors, locates code, proposes fix) |
40
- | `/play` | Run the game and report state (clean run, warnings, or crash) |
41
-
42
- Or just describe what you want — the specialist skills (FPS controller, lighting, GDScript patterns, scene composition, UI, asset strategy) auto-trigger on natural language: "make me an FPS", "add lighting", "I need a HUD".
43
-
44
- ## Commands
45
-
46
- | Command | Description |
47
- |---------|-------------|
48
- | `summer install` | Download and install Summer Engine |
49
- | `summer login` | Sign in via browser (Google/GitHub) |
50
- | `summer logout` | Clear auth tokens |
51
- | `summer status` | Check engine status, port, auth state |
52
- | `summer doctor` | Diagnose Node, login, engine, local API, MCP boot |
53
- | `summer run [path]` | Launch engine (optionally with a project) |
54
- | `summer open <path>` | Open a project in the running engine |
55
- | `summer create <template> [name]` | Create new project from template |
56
- | `summer list templates \| projects` | List available templates or local projects |
57
- | `summer skills list` | Show available skills |
58
- | `summer skills install <name>` | Install one skill |
59
- | `summer skills install --recommended --agent <agent>` | Install the recommended set |
60
- | `summer mcp` | Start the MCP server (used by Codex/Cursor/Claude Code/Windsurf) |
61
- | `summer mcp setup <agent>` | Write MCP config for an agent |
62
- | `summer setup <agent>` | One shot: MCP config + recommended skills + doctor |
63
-
64
- Supported agents: `codex`, `claude-code`, `cursor`, `windsurf`. Supported scopes: `user` (default), `project`.
65
-
66
- ## Plugin install (Claude Code)
201
+ ### Factory Droid
67
202
 
68
203
  ```bash
69
- claude /plugin install summer-engine
204
+ droid plugin marketplace add https://github.com/SummerEngine/summer-marketplace
205
+ droid plugin install summer@summer-marketplace
70
206
  ```
71
207
 
72
- That registers Summer as a plugin under the `summer:` namespace. Skills appear in the slash menu as `summer:brainstorm-game`, `summer:debug`, `summer:play`, etc. The plugin also bundles:
208
+ ### Gemini CLI
73
209
 
74
- - A `summer-engine` MCP server (configured automatically — no manual `~/.claude.json` edit needed).
75
- - Lifecycle hooks: a `session-start` greeter that detects Godot/Summer projects and reads `.summer/GameSoul.md`; a `pre-commit-doctor` hook (opt-in) that runs `summer doctor` before commits.
210
+ ```bash
211
+ gemini extensions install https://github.com/SummerEngine/summer
212
+ ```
76
213
 
77
- For Cursor, Codex, OpenCode, and Gemini, see [docs/CURSOR.md](docs/CURSOR.md), [docs/CODEX.md](docs/CODEX.md), and the manifests at `.cursor-plugin/`, `.codex-plugin/`, `.opencode/`, `gemini-extension.json` respectively.
214
+ Update later: `gemini extensions update summer`.
78
215
 
79
- ## MCP Integration
216
+ ### GitHub Copilot CLI
80
217
 
81
- `summer setup <agent>` writes the right config in the right place. If you need to do it by hand:
218
+ ```bash
219
+ copilot plugin marketplace add SummerEngine/summer-marketplace
220
+ copilot plugin install summer@summer-marketplace
221
+ ```
82
222
 
83
- **Cursor** (`.cursor/mcp.json` per project, or `~/.cursor/mcp.json` user-wide):
223
+ ### OpenCode
84
224
 
85
- ```json
86
- {
87
- "mcpServers": {
88
- "summer-engine": {
89
- "command": "npx",
90
- "args": ["summer-engine", "mcp"]
91
- }
92
- }
93
- }
225
+ ```bash
226
+ npm install --save-dev summer-engine
94
227
  ```
95
228
 
96
- **Claude Code** (`~/.claude.json` user-wide, or `.mcp.json` per project):
229
+ Add to `opencode.json`:
97
230
 
98
231
  ```json
99
232
  {
100
- "mcpServers": {
233
+ "plugin": ["summer-engine/.opencode/plugins/summer.js"],
234
+ "mcp": {
101
235
  "summer-engine": {
102
236
  "command": "npx",
103
237
  "args": ["summer-engine", "mcp"]
@@ -106,46 +240,94 @@ For Cursor, Codex, OpenCode, and Gemini, see [docs/CURSOR.md](docs/CURSOR.md), [
106
240
  }
107
241
  ```
108
242
 
109
- **Codex** (`~/.codex/config.toml`):
243
+ Restart. Full guide: [`.opencode/INSTALL.md`](./.opencode/INSTALL.md).
110
244
 
111
- ```toml
112
- [mcp_servers.summer-engine]
113
- command = "npx"
114
- args = ["summer-engine", "mcp"]
245
+ ### Windsurf and others
246
+
247
+ ```bash
248
+ npm install -g summer-engine
249
+ summer setup <agent> --yes
250
+ summer doctor
115
251
  ```
116
252
 
117
- The MCP server exposes focused tools for scene manipulation, inspector/resource ops, project settings, asset import, play/stop, diagnostics, and asset search/generation. Tools the host agent already has natively (file ops, git, shell, grep) are intentionally not exposed.
253
+ ---
254
+
255
+ ## CLI reference
256
+
257
+ | Command | What it does |
258
+ |---|---|
259
+ | `summer install` | Download Summer Engine. Transparent — prints URL + size first. |
260
+ | `summer login` | Browser-based sign-in. |
261
+ | `summer logout` | Clear auth tokens. |
262
+ | `summer status` | Engine state, port, auth. |
263
+ | `summer doctor` | Diagnose Node, login, engine, MCP. |
264
+ | `summer run [path]` | Launch the engine. |
265
+ | `summer open <path>` | Open a project in a running engine. |
266
+ | `summer create <template> [name]` | Scaffold a project. |
267
+ | `summer list templates` / `projects` | Browse. |
268
+ | `summer skills list` | Show all skills. |
269
+ | `summer skills install <name>` | Install one. |
270
+ | `summer skills install --recommended --agent <agent>` | Install the recommended set. |
271
+ | `summer mcp` | Start the MCP server. |
272
+ | `summer mcp setup <agent>` | Write MCP config for an agent. |
273
+ | `summer setup <agent> [--yes]` | One shot: MCP config + recommended skills + doctor. |
274
+
275
+ Agents: `claude-code`, `codex`, `cursor`, `gemini`, `opencode`, `windsurf`. Scopes: `--scope user` (default), `--scope project`.
276
+
277
+ ---
278
+
279
+ ## Verify
118
280
 
119
- **Visual feedback** (viewport and game screenshots) is currently available in the Summer Engine app via the built-in Summer Agent. MCP support for screenshots is on the MVP2 roadmap, gated on host clients reliably consuming image content.
281
+ In a fresh agent session:
120
282
 
121
- ## How It Works
283
+ > Let's make an FPS in Summer Engine.
122
284
 
123
- 1. Summer Engine runs a local API server on `localhost:6550`.
124
- 2. The MCP server (`npx summer-engine mcp`) connects to that local API via a per-machine auth token (`~/.summer/api-token`) and exposes engine ops as MCP tools.
125
- 3. Agents call the MCP tools and edit `.gd`/`.cs`/`.json`/`.md` files directly with their own file tools. Scenes (`.tscn`) flow through MCP.
285
+ The agent should auto-load `summer:fps-controller` before writing code. If it doesn't, run `summer doctor`.
126
286
 
127
- The engine must be running for MCP tools that touch scenes/assets/diagnostics. If it isn't, tools return a clear error pointing at `summer run`.
287
+ ---
128
288
 
129
- ## Per-Agent Docs
289
+ ## Templates
290
+
291
+ | Template | What you get |
292
+ |---|---|
293
+ | `empty` | Empty 3D project with a root node |
294
+ | `3d-basic` | 3D scene with camera, light, floor |
295
+
296
+ More coming.
297
+
298
+ ---
299
+
300
+ ## Contributing
301
+
302
+ Skills evolve fast. Two ways to help:
303
+
304
+ 1. **Open an issue** if a skill misfires. Quote the prompt and the response.
305
+ 2. **Submit a SKILL.md** for one of the `NEXT` entries in [`skills/catalog.yaml`](./skills/catalog.yaml). Run `summer:skill-test` against it before opening the PR.
306
+
307
+ [`docs/DEVELOPMENT.md`](./docs/DEVELOPMENT.md) is the contributor guide.
308
+
309
+ ---
310
+
311
+ ## Per-harness docs
130
312
 
131
- - [Agent Kit overview](docs/AGENT_KIT.md)
132
313
  - [Claude Code](docs/CLAUDE_CODE.md)
133
314
  - [Codex](docs/CODEX.md)
134
315
  - [Cursor](docs/CURSOR.md)
316
+ - [OpenCode](.opencode/INSTALL.md)
135
317
  - [Skills overview](docs/SKILLS.md)
136
- - [Templates overview](docs/TEMPLATES.md)
137
-
138
- ## Templates
318
+ - [Templates](docs/TEMPLATES.md)
319
+ - [Architecture overview](docs/OVERVIEW.md)
139
320
 
140
- Built-in templates:
321
+ ---
141
322
 
142
- - `empty` — Empty 3D project with a root node
143
- - `3d-basic` — 3D scene with camera, light, and floor
323
+ ## License
144
324
 
145
- More templates coming soon.
325
+ MIT for everything in this repo. Summer Engine itself is proprietary. See [What's open and what's not](#whats-open-and-whats-not).
146
326
 
147
327
  ## Links
148
328
 
149
329
  - [Website](https://summerengine.com)
330
+ - [Download Summer Engine](https://summerengine.com/download)
150
331
  - [Documentation](https://summerengine.com/docs)
151
332
  - [Community](https://summerengine.com/community)
333
+ - [Issues](https://github.com/SummerEngine/summer/issues)
File without changes
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const assetsCommand: Command;
@@ -0,0 +1,189 @@
1
+ import { Command } from "commander";
2
+ import { getAuthToken } from "../lib/auth.js";
3
+ import { getClient } from "../lib/with-engine.js";
4
+ import { outputResult, outputError, isJsonMode } from "../lib/format.js";
5
+ const GATEWAY_URL = process.env.SUMMER_GATEWAY_URL || "https://www.summerengine.com";
6
+ const KENNEY_URL_PATTERN = /\/kenney\/3d\/([^/]+)\//;
7
+ function getPackSlugFromUrl(fileUrl) {
8
+ return fileUrl.match(KENNEY_URL_PATTERN)?.[1] ?? null;
9
+ }
10
+ function buildKenneyTextureUrl(fileUrl) {
11
+ const lastSlash = fileUrl.lastIndexOf("/");
12
+ const base = lastSlash >= 0 ? fileUrl.slice(0, lastSlash) : fileUrl;
13
+ return `${base}/Textures/colormap.png`;
14
+ }
15
+ async function textureExists(url) {
16
+ try {
17
+ const res = await fetch(url, {
18
+ method: "HEAD",
19
+ signal: AbortSignal.timeout(5000),
20
+ });
21
+ return res.ok;
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ async function buildKenneyImportEntries(fileUrl, packSlug, fileName) {
28
+ const textureUrl = buildKenneyTextureUrl(fileUrl);
29
+ const hasTexture = await textureExists(textureUrl);
30
+ if (!hasTexture) {
31
+ return [
32
+ {
33
+ url: fileUrl,
34
+ path: `res://assets/models/kenney/${packSlug}/${fileName}`,
35
+ },
36
+ ];
37
+ }
38
+ const glbPath = `res://assets/models/kenney/${packSlug}/${fileName}`;
39
+ const glbDir = glbPath.replace(/\/[^/]+$/, "");
40
+ const texturePath = `${glbDir}/Textures/colormap.png`;
41
+ return [
42
+ { url: textureUrl, path: texturePath },
43
+ { url: fileUrl, path: glbPath },
44
+ ];
45
+ }
46
+ async function searchAssetsApi(params) {
47
+ const token = await getAuthToken();
48
+ if (!token) {
49
+ return {
50
+ error: "Not logged in",
51
+ message: "Not signed in. Run: summer login\nOr open: https://www.summerengine.com/login\nAsset search requires a Summer Engine account (free to create).",
52
+ };
53
+ }
54
+ const searchParams = new URLSearchParams();
55
+ searchParams.set("query", params.query);
56
+ if (params.assetType && params.assetType !== "all") {
57
+ searchParams.set("assetType", params.assetType);
58
+ }
59
+ if (params.limit) {
60
+ searchParams.set("limit", String(params.limit));
61
+ }
62
+ const res = await fetch(`${GATEWAY_URL}/api/mcp/assets?${searchParams}`, {
63
+ headers: { Authorization: `Bearer ${token}` },
64
+ signal: AbortSignal.timeout(15000),
65
+ });
66
+ const data = (await res.json());
67
+ if (!res.ok) {
68
+ if (res.status === 402) {
69
+ return {
70
+ error: "upgrade_required",
71
+ message: (data.message || "Asset search requires a Pro subscription.") +
72
+ "\nUpgrade at: https://www.summerengine.com/pricing",
73
+ plan: data.plan,
74
+ };
75
+ }
76
+ if (res.status === 401) {
77
+ return {
78
+ error: "unauthorized",
79
+ message: (data.message || "Auth token expired.") +
80
+ " Run: summer login --force",
81
+ };
82
+ }
83
+ return {
84
+ error: data.error || "Search failed",
85
+ message: data.message || "Asset search failed",
86
+ };
87
+ }
88
+ return data;
89
+ }
90
+ export const assetsCommand = new Command("assets").description("Search and import assets from the Summer Engine library");
91
+ assetsCommand
92
+ .command("search <query>")
93
+ .description('Search the asset library (e.g. summer assets search "low-poly tree")')
94
+ .option("--type <type>", "Filter: 2d_image, animation, 3d_model, audio, music, all", "all")
95
+ .option("--limit <n>", "Max results (1-20)", "10")
96
+ .action(async (query, opts, cmd) => {
97
+ const fmt = isJsonMode(cmd);
98
+ try {
99
+ const result = await searchAssetsApi({
100
+ query,
101
+ assetType: opts.type,
102
+ limit: Math.min(parseInt(opts.limit, 10), 20),
103
+ });
104
+ if (result.error) {
105
+ outputError(result.message || result.error, fmt);
106
+ }
107
+ outputResult(result, fmt);
108
+ }
109
+ catch (err) {
110
+ outputError(err instanceof Error ? err.message : String(err), fmt);
111
+ }
112
+ });
113
+ assetsCommand
114
+ .command("import <query>")
115
+ .description("Search and import the best match into the project in one step")
116
+ .option("--parent <path>", "Parent node to add the asset under (e.g. ./World)")
117
+ .option("--type <type>", "Preferred type: 2d_image, animation, 3d_model, audio, music, all", "3d_model")
118
+ .action(async (query, opts, cmd) => {
119
+ const fmt = isJsonMode(cmd);
120
+ try {
121
+ const searchResult = await searchAssetsApi({
122
+ query,
123
+ assetType: opts.type,
124
+ limit: 5,
125
+ });
126
+ if (searchResult.error) {
127
+ outputError(searchResult.message || searchResult.error, fmt);
128
+ }
129
+ const assets = searchResult.assets || [];
130
+ if (assets.length === 0) {
131
+ outputError(`No assets found for "${query}". Try different keywords.`, fmt);
132
+ }
133
+ const best = assets[0];
134
+ const fileUrl = best.fileUrl;
135
+ if (!fileUrl) {
136
+ outputError("Asset has no download URL.", fmt);
137
+ }
138
+ const fileName = fileUrl.split("/").pop()?.split("?")[0] || "asset";
139
+ const packSlug = best.packSlug ?? getPackSlugFromUrl(fileUrl) ?? "misc";
140
+ let imports;
141
+ if (best.type === "3d_model" && fileUrl.includes("kenney/3d/")) {
142
+ imports = await buildKenneyImportEntries(fileUrl, packSlug, fileName);
143
+ }
144
+ else {
145
+ const path = best.type === "3d_model"
146
+ ? `res://assets/models/${fileName}`
147
+ : `res://assets/${fileName}`;
148
+ imports = [{ url: fileUrl, path }];
149
+ }
150
+ const importPath = imports[imports.length - 1].path;
151
+ const client = await getClient();
152
+ const importResult = imports.length === 1
153
+ ? await client.executeOps([
154
+ {
155
+ op: "ImportFromUrl",
156
+ url: imports[0].url,
157
+ path: imports[0].path,
158
+ },
159
+ ])
160
+ : await client.executeOps([
161
+ { op: "ImportFromUrlBatch", imports },
162
+ ]);
163
+ const ok = importResult?.results?.[0]?.ok;
164
+ if (!ok) {
165
+ outputError(`Import failed for "${best.title}". Check engine logs.`, fmt);
166
+ }
167
+ if (opts.parent && best.type === "3d_model") {
168
+ await client.executeOps([
169
+ {
170
+ op: "InstantiateScene",
171
+ parent: opts.parent,
172
+ scene: importPath,
173
+ name: best.title.replace(/\s+/g, "_"),
174
+ },
175
+ ]);
176
+ }
177
+ outputResult({
178
+ success: true,
179
+ asset: best.title,
180
+ type: best.type,
181
+ importedTo: importPath,
182
+ addedToScene: !!opts.parent,
183
+ parent: opts.parent || null,
184
+ }, fmt);
185
+ }
186
+ catch (err) {
187
+ outputError(err instanceof Error ? err.message : String(err), fmt);
188
+ }
189
+ });