@genex-ai/cli-demo 0.7.0 → 0.10.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 (28) hide show
  1. package/README.md +13 -12
  2. package/dist/index.js +410 -154
  3. package/package.json +10 -11
  4. package/templates/README.md +8 -7
  5. package/templates/skills/genex-ai-model/SKILL.md +5 -5
  6. package/templates/skills/genex-ai-sfx/SKILL.md +1 -1
  7. package/templates/skills/genex-ai-skybox/SKILL.md +2 -2
  8. package/templates/skills/genex-ai-texture/SKILL.md +1 -1
  9. package/templates/skills/genex-getting-started/SKILL.md +10 -6
  10. package/templates/skills/genex-threejs-embed-auth/SKILL.md +174 -0
  11. package/templates/skills/genex-threejs-multiplayer/SKILL.md +193 -100
  12. package/templates/skills/genex-threejs-multiplayer/references/genre-recipes.md +115 -0
  13. package/templates/skills/genex-threejs-multiplayer/references/realtime-patterns.md +138 -123
  14. package/templates/skills/genex-threejs-precipitation-surfaces/SKILL.md +59 -0
  15. package/templates/skills/genex-threejs-precipitation-surfaces/references/precipitation-surfaces.md +181 -0
  16. package/templates/skills/genex-threejs-procedural-architecture/SKILL.md +2 -1
  17. package/templates/skills/genex-threejs-procedural-architecture/references/architecture-systems.md +1 -1
  18. package/templates/skills/genex-threejs-procedural-fields/SKILL.md +0 -5
  19. package/templates/skills/genex-threejs-procedural-geometry/SKILL.md +0 -5
  20. package/templates/skills/genex-threejs-procedural-materials/SKILL.md +2 -17
  21. package/templates/skills/genex-threejs-procedural-vegetation/SKILL.md +11 -1
  22. package/templates/skills/genex-threejs-procedural-vfx/SKILL.md +3 -1
  23. package/templates/skills/genex-threejs-shadow-systems/SKILL.md +0 -5
  24. package/templates/skills/genex-threejs-skill-router/SKILL.md +10 -5
  25. package/templates/skills/genex-threejs-skill-router/references/routing-map.md +9 -6
  26. package/templates/skills/genex-threejs-spectral-ocean/SKILL.md +11 -1
  27. package/templates/skills/genex-threejs-temporal-surfaces/SKILL.md +3 -1
  28. package/templates/skills/genex-threejs-water-optics/SKILL.md +14 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genex-ai/cli-demo",
3
- "version": "0.7.0",
3
+ "version": "0.10.0",
4
4
  "description": "Set up your ~/.claude workspace, authorize, create a game project, generate AI assets, and publish (genex CLI).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -15,14 +15,6 @@
15
15
  "engines": {
16
16
  "node": ">=20"
17
17
  },
18
- "scripts": {
19
- "build": "tsup",
20
- "prepack": "pnpm build",
21
- "start": "node src/index.ts",
22
- "dev": "node --watch src/index.ts",
23
- "typecheck": "tsc --noEmit",
24
- "test": "node --test test/*.test.ts"
25
- },
26
18
  "keywords": [
27
19
  "cli",
28
20
  "claude",
@@ -46,5 +38,12 @@
46
38
  "bugs": {
47
39
  "url": "https://github.com/me-ai-org/genex-demo/issues"
48
40
  },
49
- "homepage": "https://github.com/me-ai-org/genex-demo/tree/main/apps/cli#readme"
50
- }
41
+ "homepage": "https://github.com/me-ai-org/genex-demo/tree/main/apps/cli#readme",
42
+ "scripts": {
43
+ "build": "tsup",
44
+ "start": "node src/index.ts",
45
+ "dev": "node --watch src/index.ts",
46
+ "typecheck": "tsc --noEmit",
47
+ "test": "node --test test/*.test.ts"
48
+ }
49
+ }
@@ -1,15 +1,16 @@
1
1
  # Genex workspace
2
2
 
3
- These files were installed into your `~/.claude` directory by `genex init`.
4
- They give your coding agent a starter workspace for making 3D games in the
5
- browser.
3
+ These files were installed by `genex init` into your coding agent's workspace
4
+ Claude Code (`~/.claude`), Codex (`~/.codex/skills`), and Cursor
5
+ (`~/.cursor/skills`), whichever it detected. They give your agent superpowers
6
+ for making 3D games in the browser.
6
7
 
7
8
  Genex is built around agent superpowers for browser games: Three.js skills,
8
- one-click publishing, multiplayer-ready architecture, and team workflows. The
9
- installed files are yours to edit, extend, and keep with each project.
9
+ one-click publishing, multiplayer-ready architecture, and team workflows.
10
10
 
11
- Existing files are never overwritten. Re-running `genex init` only adds files
12
- you do not already have.
11
+ Files whose names start with `genex-` are managed by Genex: re-running
12
+ `genex init` refreshes them to the latest version. Anything you add yourself is
13
+ never touched.
13
14
 
14
15
  - `skills/` - reusable Genex skills for 3D game creation.
15
16
  - `agents/` - example subagent definitions.
@@ -54,8 +54,8 @@ i.e. "looking forward"). A hero whose nose points sideways reads as broken at a
54
54
 
55
55
  ## Load it into the scene
56
56
 
57
- Use Three.js `GLTFLoader` with the **relative** path (so it works under the
58
- published subpath `https://<user>.github.io/<slug>/`):
57
+ Use Three.js `GLTFLoader` (the game serves at the domain root
58
+ `https://<slug>.genex.technology/`, so relative or absolute paths both work):
59
59
 
60
60
  ```ts
61
61
  import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
@@ -73,12 +73,12 @@ To place many copies, `model.clone()` per instance. For animated GLBs, drive
73
73
 
74
74
  ## Publish checklist (so players see the model)
75
75
 
76
- - Reference assets with **relative** paths (`./assets/...`), never absolute
77
- (`/assets/...`) GitHub Pages serves the game at a subpath.
76
+ - Reference assets with **relative** paths (`./assets/...`); absolute
77
+ (`/assets/...`) also resolves since the game serves at the domain root.
78
78
  - Set `base: "./"` in `vite.config.ts` before `npm run build` (see the scaffold
79
79
  prompt's publish step).
80
80
  - Keep generated assets under `public/assets/` — Vite only ships files under `public/`
81
- (or files you `import`); `npx genex publish` commits and pushes that folder with the game.
81
+ (or files you `import`); `npx genex publish` ships that folder with the game.
82
82
 
83
83
  ## Options
84
84
 
@@ -56,7 +56,7 @@ Reuse one loaded `buffer` across many plays; create a fresh `Audio`/`PositionalA
56
56
  ## Publish checklist
57
57
 
58
58
  - Relative path `./assets/sfx/...`; `base: "./"` in `vite.config.ts`; files live under
59
- `public/assets/` so Vite ships them; `npx genex publish` commits and pushes them.
59
+ `public/assets/` so Vite ships them; `npx genex publish` ships them to R2.
60
60
 
61
61
  ## Troubleshooting
62
62
 
@@ -61,10 +61,10 @@ texture.dispose; // (dispose the PMREM source later if you stop using it)
61
61
 
62
62
  ## Publish checklist
63
63
 
64
- - Use the **relative** path `./assets/skybox/...` (GitHub Pages serves at a subpath).
64
+ - Use the **relative** path `./assets/skybox/...` (absolute `/assets/...` also works — the game serves at the domain root).
65
65
  - `base: "./"` in `vite.config.ts` before `npm run build`.
66
66
  - Generated files live under `public/assets/` so Vite ships them; `npx genex publish`
67
- commits and pushes that folder with the game.
67
+ ships that folder with the game.
68
68
 
69
69
  ## Troubleshooting
70
70
 
@@ -68,7 +68,7 @@ scene.add(ground);
68
68
  ## Publish checklist
69
69
 
70
70
  - Relative path `./assets/textures/...`; `base: "./"` in `vite.config.ts`; files live under
71
- `public/assets/` so Vite ships them; `npx genex publish` commits and pushes them.
71
+ `public/assets/` so Vite ships them; `npx genex publish` ships them to R2.
72
72
 
73
73
  ## Troubleshooting
74
74
 
@@ -23,12 +23,14 @@ are never touched).
23
23
 
24
24
  Start with `$genex-threejs-skill-router` for broad game or graphics requests.
25
25
  It routes the agent to focused skills for cameras, procedural geometry,
26
- materials, atmosphere, water, VFX, post-processing, and visual validation.
26
+ materials, atmosphere, water, weather, VFX, post-processing, and visual
27
+ validation.
27
28
 
28
29
  ## Generating real assets
29
30
 
30
31
  Beyond procedural code, Genex can generate **real, AI-made assets** from a prompt
31
- and drop them into `./assets/` (committed when you publish):
32
+ and drop them into `public/assets/` (shipped with your published game; load them
33
+ as `./assets/...` — the `public/` prefix is stripped when served):
32
34
 
33
35
  ```bash
34
36
  npx genex model "weathered wooden barrel" # a 3D mesh (GLB)
@@ -43,18 +45,20 @@ npx genex texture "mossy cobblestone" --terrain # a tiling surface texture
43
45
  Each has a focused skill with the exact loader code — `$genex-ai-model`,
44
46
  `$genex-ai-skybox`, `$genex-ai-sfx`, `$genex-ai-texture`.
45
47
 
46
- Your existing files were left untouched. `genex init` only adds what is missing.
48
+ Your own files were left untouched. `genex init` only adds missing files and
49
+ refreshes the genex-owned ones.
47
50
 
48
51
  ## Re-running setup
49
52
 
50
- Safe to run any time; it never overwrites your files:
53
+ Safe to run any time genex-owned skills are refreshed to the latest version,
54
+ and your own files are never touched:
51
55
 
52
56
  ```bash
53
57
  npx @genex-ai/cli-demo@latest init
54
58
  ```
55
59
 
56
- Use `--force` only if you intentionally want to overwrite installed templates
57
- with the latest versions.
60
+ Use `--force` only if you intentionally want your own existing files overwritten
61
+ by the bundled templates too.
58
62
 
59
63
  ## Authorization
60
64
 
@@ -0,0 +1,174 @@
1
+ ---
2
+ name: genex-threejs-embed-auth
3
+ description: Wire up signed-in identity for a Genex game via @genex-ai/embed-sdk. Load this UNCONDITIONALLY for every game, multiplayer or not, BEFORE writing any boot code — identity is required for play, saving progress, and multiplayer; there is no anonymous mode.
4
+ ---
5
+
6
+ # Genex Three.js Embed Auth
7
+
8
+ `@genex-ai/embed-sdk` is how a Genex game learns **who is playing it**. Every
9
+ game needs it — there is **no anonymous play**: without a signed-in identity
10
+ the game is not playable, cannot save progress, and cannot join multiplayer.
11
+ The SDK handles both contexts with one `initEmbed(...)` call:
12
+
13
+ - **Embedded in the Genex dashboard (an iframe):** a silent handshake with the
14
+ dashboard signs the player in within a couple of seconds — no login screen.
15
+ - **Standalone (someone opens the game's link directly):** the SDK redirects
16
+ through Genex sign-in (first-time visitors sign up there) and returns to the
17
+ game automatically. This is a real page navigation, by design — game code
18
+ does not need to handle any of it.
19
+
20
+ While identity is resolving (or missing) the SDK shows its own full-screen
21
+ overlay over the game, so never build a separate "connecting" screen for auth.
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ npm i @genex-ai/embed-sdk @sentry/browser
27
+ ```
28
+
29
+ (`@sentry/browser` powers the crash reporting + session replay wiring below —
30
+ it's an optional peer of the SDK, and every Genex game installs it. Already
31
+ installed if you followed Step 3 of the scaffold; repeated here so this skill
32
+ is self-contained.)
33
+
34
+ ## Bootstrap (required, every game)
35
+
36
+ ```ts
37
+ // main.ts — the FIRST things in the boot sequence, before any other game code
38
+ import { initGameSentry } from "@genex-ai/embed-sdk/sentry";
39
+ import { initEmbed } from "@genex-ai/embed-sdk";
40
+ import { GENEX } from "./genex.config";
41
+
42
+ // Crash reporting + session replay FIRST — so even a failure inside the auth
43
+ // boot below gets reported. One required field; never pass tokens to it.
44
+ initGameSentry({ slug: GENEX.slug });
45
+
46
+ initEmbed({
47
+ slug: GENEX.slug,
48
+ apiUrl: GENEX.apiUrl,
49
+ dashboardOrigins: GENEX.dashboardOrigins,
50
+ });
51
+ ```
52
+
53
+ Scene setup and asset loading may continue immediately after this call — auth
54
+ never blocks rendering. Gate the **identity-dependent** parts (multiplayer
55
+ connect, saving/loading progress, showing the player's name) on `waitForAuth()`:
56
+
57
+ ```ts
58
+ import { waitForAuth, getColyseusAuth, getEmbedToken } from "@genex-ai/embed-sdk";
59
+
60
+ const { user } = await waitForAuth(); // resolves when signed in; rejects if blocked
61
+ // user.id / user.name are the real Genex identity
62
+ ```
63
+
64
+ ## API surface (exact — do not invent methods)
65
+
66
+ - `initEmbed({ slug, apiUrl, dashboardOrigins })` — call once, first. All three
67
+ fields required (from `genex.config.ts`).
68
+ - `waitForAuth()` → `Promise<{ user }>` — THE gate for `connect()` and `/state`
69
+ calls. Rejects if the session ends up blocked — catch it and let the SDK's
70
+ overlay handle the UX (don't build your own sign-in UI).
71
+ - `isEmbedded()` → `boolean` — structural "is in an iframe" check; NOT the same
72
+ question as "is signed in".
73
+ - `getAuthState()` → `"pending" | "authenticated" | "blocked"` — synchronous.
74
+ - `getUser()` → `{ id, name, image? } | null` — non-null only when authenticated.
75
+ - `getEmbedToken()` → `string | undefined` — for `Authorization: Bearer` on
76
+ `GET`/`PUT ${GENEX.apiUrl}/api/projects/${GENEX.slug}/state` (both REQUIRE it).
77
+ - `getColyseusAuth()` → `{ embedToken } | undefined` — pass as `connect()`'s
78
+ `auth` option (REQUIRED — the relay rejects tokenless joins). Read it fresh
79
+ at every `connect()` call; tokens rotate automatically (~every 10 minutes).
80
+ - `on(event, cb)` → unsubscribe fn. Events: `"authenticated"`, `"blocked"`,
81
+ `"error"`.
82
+
83
+ From `@genex-ai/embed-sdk/sentry` (crash reporting; exactly these two):
84
+
85
+ - `initGameSentry({ slug, dsn?, environment? })` — call once, BEFORE
86
+ `initEmbed()`. Only `slug` is required; the shared Genex Sentry project DSN
87
+ is built in. Errors, tracing, and session replay all start here; the signed-in
88
+ user is attached automatically after auth (no code needed).
89
+ - `sentryCanvasSnapshot(canvas)` — session replay records the DOM, not the 3D
90
+ canvas; call this once per frame at the END of the render loop so replays
91
+ show actual gameplay. Works for BOTH WebGL and WebGPU renderers; internally
92
+ throttled, so calling at 60fps is fine:
93
+
94
+ ```ts
95
+ function animate() {
96
+ requestAnimationFrame(animate);
97
+ // ...game update...
98
+ renderer.render(scene, camera);
99
+ sentryCanvasSnapshot(renderer.domElement); // AFTER render, same frame
100
+ }
101
+ ```
102
+
103
+ ## Crash reporting rules
104
+
105
+ - `initGameSentry` has token scrubbing built in (the sign-in return-trip pass
106
+ in URLs is redacted automatically). Never wrap, reimplement, or bypass it —
107
+ and never add Sentry options that capture network request/response bodies.
108
+ - Don't call `Sentry.init` yourself or add a second error reporter —
109
+ `initGameSentry` is the one entry point.
110
+ - Manual capture is fine where a try/catch swallows a real bug:
111
+ `import * as Sentry from "@sentry/browser"; Sentry.captureException(err)`.
112
+
113
+ ## NEVER log the tokens
114
+
115
+ **NEVER log the return value of `getEmbedToken()` or `getColyseusAuth()` — not
116
+ to `console.log`, not to a crash-reporter or analytics breadcrumb.** The token
117
+ is bounded (15 minutes, one game, one scope), but third-party logging-service
118
+ retention can outlive that. Nothing in normal game code ever needs to print it.
119
+
120
+ ## Config wiring (already done — do NOT hand-write URLs)
121
+
122
+ **`genex init` already wrote the config files** — do not create or edit them,
123
+ and NEVER hardcode an environment URL anywhere in game code:
124
+
125
+ - `src/genex.config.ts` — a static env-reader (production URL defaults,
126
+ overridable via `VITE_GENEX_*` env vars). Import `GENEX` from it as shown
127
+ above; treat the file as read-only.
128
+ - `.env` — `VITE_GENEX_SLUG` (the game's identity; committed).
129
+ - `.env.development.local` — present only when init ran against a local/dev
130
+ stack: URL overrides that apply in `npm run dev` ONLY. A production build
131
+ (`vite build`) always uses the production defaults, so localhost values can
132
+ never ship. Gitignored via `*.local` — never commit it.
133
+
134
+ If `src/genex.config.ts` is somehow missing (e.g. it was deleted), re-run
135
+ `genex init` in the project folder rather than writing one by hand.
136
+
137
+ ## Standalone behavior (what to expect, not something to code)
138
+
139
+ Opening the game's link directly (not from the dashboard) bounces through the
140
+ Genex sign-in page and back before the game becomes playable — including during
141
+ your own local `npm run dev` checks (sign in once; the bounce is instant after
142
+ that). The return trip carries a one-time pass in the URL that the SDK consumes
143
+ and removes immediately. Don't code around any of this: no `?`/`#` URL params
144
+ of yours will be affected, and `isEmbedded()` / the return-trip handling are
145
+ internal SDK concerns.
146
+
147
+ ## Checklist
148
+
149
+ - [ ] `initGameSentry({ slug: GENEX.slug })` is the very first call in `main.ts`.
150
+ - [ ] `initEmbed(...)` follows it, with all three config fields.
151
+ - [ ] `sentryCanvasSnapshot(renderer.domElement)` runs after `renderer.render()`
152
+ in the main loop (WebGL and WebGPU alike).
153
+ - [ ] `genex.config.ts` includes `dashboardOrigins` (from `.genex/project.json`).
154
+ - [ ] Everything identity-dependent awaits `waitForAuth()` (multiplayer `connect`,
155
+ `/state` load/save, player-name UI).
156
+ - [ ] `/state` fetches send `Authorization: Bearer ${getEmbedToken()}`.
157
+ - [ ] No token value is ever logged or sent to analytics.
158
+ - [ ] No custom sign-in/anonymous-fallback UI — the SDK overlay + dashboard own that.
159
+
160
+ ## Troubleshooting
161
+
162
+ - **Game loads then immediately navigates away (standalone/local dev)** — that's
163
+ the sign-in bounce working as designed. Sign in once in the browser; it
164
+ returns to the game automatically.
165
+ - **`waitForAuth()` rejects / state is `"blocked"`** — the visitor declined or
166
+ failed sign-in, or the dashboard session ended. The SDK overlay (or the
167
+ dashboard, when embedded) shows the sign-in prompt; the game just stays
168
+ paused behind it. Don't retry in a loop.
169
+ - **Multiplayer join rejected with 401** — `connect()` ran before
170
+ `waitForAuth()` resolved, without `auth: getColyseusAuth()!`, or with a stale
171
+ cached token on reconnect (read it fresh each call).
172
+ - **`/state` returns 401/403** — missing `Authorization` header (401) or the
173
+ token belongs to a different game (403): `GENEX.slug` doesn't match this
174
+ project.