@genex-ai/cli-demo 0.46.0 → 0.47.0-dev.70
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/dist/index.js +70 -1
- package/package.json +1 -1
- package/templates/skills/genex-ai-image/SKILL.md +1 -1
- package/templates/skills/genex-ai-model/SKILL.md +1 -1
- package/templates/skills/genex-ai-sfx/SKILL.md +1 -1
- package/templates/skills/genex-ai-skybox/SKILL.md +1 -1
- package/templates/skills/genex-ai-texture/SKILL.md +1 -1
- package/templates/skills/genex-ai-video/SKILL.md +1 -1
- package/templates/skills/genex-explore/SKILL.md +1 -1
- package/templates/skills/genex-getting-started/SKILL.md +2 -2
- package/templates/skills/genex-updates/SKILL.md +1 -1
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import fs from "fs";
|
|
|
8
8
|
import os from "os";
|
|
9
9
|
import path from "path";
|
|
10
10
|
import { fileURLToPath } from "url";
|
|
11
|
-
var RAW_CHANNEL = "
|
|
11
|
+
var RAW_CHANNEL = "dev";
|
|
12
12
|
var CLI_CHANNEL = RAW_CHANNEL === "dev" ? "dev" : "latest";
|
|
13
13
|
var STANDS = {
|
|
14
14
|
prod: { api: "https://api.genex.games", dashboard: "https://genex.games" },
|
|
@@ -868,6 +868,49 @@ async function writeGitignore(dir, log) {
|
|
|
868
868
|
await fs4.writeFile(file, next);
|
|
869
869
|
log.dim(`Updated .gitignore (${toAdd.join(", ")}).`);
|
|
870
870
|
}
|
|
871
|
+
var LFS_PATTERNS = [
|
|
872
|
+
// models
|
|
873
|
+
"*.glb",
|
|
874
|
+
"*.gltf",
|
|
875
|
+
"*.bin",
|
|
876
|
+
"*.vrm",
|
|
877
|
+
"*.fbx",
|
|
878
|
+
"*.obj",
|
|
879
|
+
// textures / images
|
|
880
|
+
"*.png",
|
|
881
|
+
"*.jpg",
|
|
882
|
+
"*.jpeg",
|
|
883
|
+
"*.webp",
|
|
884
|
+
"*.ktx2",
|
|
885
|
+
"*.basis",
|
|
886
|
+
"*.hdr",
|
|
887
|
+
"*.exr",
|
|
888
|
+
"*.tga",
|
|
889
|
+
// audio / video
|
|
890
|
+
"*.mp3",
|
|
891
|
+
"*.ogg",
|
|
892
|
+
"*.wav",
|
|
893
|
+
"*.m4a",
|
|
894
|
+
"*.mp4",
|
|
895
|
+
"*.webm"
|
|
896
|
+
];
|
|
897
|
+
async function writeGitattributes(dir, log) {
|
|
898
|
+
const file = path4.join(dir, ".gitattributes");
|
|
899
|
+
let content = "";
|
|
900
|
+
try {
|
|
901
|
+
content = await fs4.readFile(file, "utf8");
|
|
902
|
+
} catch {
|
|
903
|
+
}
|
|
904
|
+
const present = new Set(content.split("\n").map((l) => l.trim().split(/\s+/)[0]));
|
|
905
|
+
const toAdd = LFS_PATTERNS.filter((p) => !present.has(p));
|
|
906
|
+
if (toAdd.length === 0) return;
|
|
907
|
+
let next = content;
|
|
908
|
+
if (next.length > 0 && !next.endsWith("\n")) next += "\n";
|
|
909
|
+
if (!content.trim()) next += "# Binary game assets go to Git LFS (R2) \u2014 keeps the source push small\n";
|
|
910
|
+
next += toAdd.map((p) => `${p} filter=lfs diff=lfs merge=lfs -text`).join("\n") + "\n";
|
|
911
|
+
await fs4.writeFile(file, next);
|
|
912
|
+
log.dim(`Updated .gitattributes (${toAdd.length} binary globs \u2192 Git LFS).`);
|
|
913
|
+
}
|
|
871
914
|
|
|
872
915
|
// src/lib/store.ts
|
|
873
916
|
import fs6 from "fs/promises";
|
|
@@ -1512,6 +1555,28 @@ async function pushWorktree(cwd, pushUrl, managed, log) {
|
|
|
1512
1555
|
["node_modules/", "dist/", ".git/", ".genex/", ".env", ".env.*", "!.env.example", ""].join("\n")
|
|
1513
1556
|
);
|
|
1514
1557
|
const env = { ...base, GIT_WORK_TREE: cwd, GIT_INDEX_FILE: path10.join(gitDir, "index-source") };
|
|
1558
|
+
let lfs = (await run("git", ["lfs", "version"], base)).code !== 0 ? false : true;
|
|
1559
|
+
if (!lfs) {
|
|
1560
|
+
log.step("Installing git-lfs (keeps large binary assets out of the source push)\u2026");
|
|
1561
|
+
const [bin, args] = process.platform === "darwin" ? ["brew", ["install", "git-lfs"]] : ["sudo", ["-n", "apt-get", "install", "-y", "git-lfs"]];
|
|
1562
|
+
await run(bin, args, base);
|
|
1563
|
+
lfs = (await run("git", ["lfs", "version"], base)).code === 0;
|
|
1564
|
+
if (!lfs) {
|
|
1565
|
+
log.warn(
|
|
1566
|
+
"Couldn't install git-lfs \u2014 large binary assets won't be saved to your source (the game still publishes)."
|
|
1567
|
+
);
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
if (lfs) {
|
|
1571
|
+
await writeGitattributes(cwd, log);
|
|
1572
|
+
const filters = [
|
|
1573
|
+
["filter.lfs.clean", "git-lfs clean -- %f"],
|
|
1574
|
+
["filter.lfs.smudge", "git-lfs smudge -- %f"],
|
|
1575
|
+
["filter.lfs.process", "git-lfs filter-process"],
|
|
1576
|
+
["filter.lfs.required", "true"]
|
|
1577
|
+
];
|
|
1578
|
+
for (const [key, value] of filters) await run("git", ["config", key, value], base);
|
|
1579
|
+
}
|
|
1515
1580
|
await run("git", ["add", "-A"], env);
|
|
1516
1581
|
const tree = (await run("git", ["ls-files"], env)).out.trim() ? (await run("git", ["write-tree"], env)).out.trim() : "";
|
|
1517
1582
|
if (!tree || tree === EMPTY_TREE) {
|
|
@@ -1520,6 +1585,10 @@ async function pushWorktree(cwd, pushUrl, managed, log) {
|
|
|
1520
1585
|
}
|
|
1521
1586
|
const commit = (await run("git", ["commit-tree", tree, "-m", "source"], { ...base, ...ident })).out.trim();
|
|
1522
1587
|
await run("git", ["update-ref", "refs/heads/main", commit], base);
|
|
1588
|
+
if (lfs && (await run("git", ["lfs", "push", "--all", pushUrl, "main"], base)).code !== 0) {
|
|
1589
|
+
log.error("Couldn't upload your game's binary assets to the source store.");
|
|
1590
|
+
return false;
|
|
1591
|
+
}
|
|
1523
1592
|
const push = await run(
|
|
1524
1593
|
"git",
|
|
1525
1594
|
["-c", "http.postBuffer=536870912", "push", "-q", pushUrl, "+refs/heads/main:main"],
|
package/package.json
CHANGED
|
@@ -172,7 +172,7 @@ See `$genex-threejs-multiplayer` for the `shared` channel rules and the room API
|
|
|
172
172
|
|
|
173
173
|
## Troubleshooting
|
|
174
174
|
|
|
175
|
-
- **"Not authorized"** — run `npx @genex-ai/cli-demo@
|
|
175
|
+
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
176
176
|
- **"Prompt rejected"** — the provider's content-safety filter blocked the prompt.
|
|
177
177
|
This is non-retryable; retrying the same wording fails again. Rewrite the prompt.
|
|
178
178
|
- **Decal is an opaque rectangle** — the image has no alpha. Regenerate with
|
|
@@ -107,7 +107,7 @@ scene is a ghost: players and objects pass straight through it.
|
|
|
107
107
|
|
|
108
108
|
## Troubleshooting
|
|
109
109
|
|
|
110
|
-
- **"Not authorized"** — run `npx @genex-ai/cli-demo@
|
|
110
|
+
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
111
111
|
- **"Out of credits" (`insufficient_credits`)** — the account has no credits left for
|
|
112
112
|
this model generation. Tell the user the facts the CLI printed: their balance, this
|
|
113
113
|
generation's cost, and when their credits refill. Then offer to continue the build
|
|
@@ -72,7 +72,7 @@ Reuse one loaded `buffer` across many plays; create a fresh `Audio`/`PositionalA
|
|
|
72
72
|
|
|
73
73
|
## Troubleshooting
|
|
74
74
|
|
|
75
|
-
- **"Not authorized"** — run `npx @genex-ai/cli-demo@
|
|
75
|
+
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
76
76
|
- **"Out of credits" (`insufficient_credits`)** — the account has no credits left for
|
|
77
77
|
this sound generation. Tell the user the facts the CLI printed: their balance, this
|
|
78
78
|
generation's cost, and when their credits refill. Then offer to continue the build
|
|
@@ -76,7 +76,7 @@ scene.background = texture; // keep the raw texture for the visible sky
|
|
|
76
76
|
|
|
77
77
|
## Troubleshooting
|
|
78
78
|
|
|
79
|
-
- **"Not authorized"** — run `npx @genex-ai/cli-demo@
|
|
79
|
+
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
80
80
|
- **"Out of credits" (`insufficient_credits`)** — the account has no credits left for
|
|
81
81
|
this skybox generation. Tell the user the facts the CLI printed: their balance, this
|
|
82
82
|
generation's cost, and when their credits refill. Then offer to continue the build
|
|
@@ -81,7 +81,7 @@ scene.add(ground);
|
|
|
81
81
|
|
|
82
82
|
## Troubleshooting
|
|
83
83
|
|
|
84
|
-
- **"Not authorized"** — run `npx @genex-ai/cli-demo@
|
|
84
|
+
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
85
85
|
- **"Out of credits" (`insufficient_credits`)** — the account has no credits left for
|
|
86
86
|
this texture generation. Tell the user the facts the CLI printed: their balance,
|
|
87
87
|
this generation's cost, and when their credits refill. Then offer to continue the
|
|
@@ -138,7 +138,7 @@ See `$genex-threejs-multiplayer` for the `shared` channel rules and the room API
|
|
|
138
138
|
|
|
139
139
|
## Troubleshooting
|
|
140
140
|
|
|
141
|
-
- **"Not authorized"** — run `npx @genex-ai/cli-demo@
|
|
141
|
+
- **"Not authorized"** — run `npx @genex-ai/cli-demo@dev init` first (it writes your `GENEX_TOKEN`).
|
|
142
142
|
- **"Prompt rejected"** — the provider's content-safety filter blocked the prompt.
|
|
143
143
|
This is non-retryable; retrying the same wording fails again. Rewrite the prompt.
|
|
144
144
|
- **Nothing plays / black surface** — the first `video.play()` must run inside a user
|
|
@@ -43,7 +43,7 @@ Add `--json` for machine-readable output.
|
|
|
43
43
|
**As a NEW game (start from the whole project):**
|
|
44
44
|
|
|
45
45
|
1. `git clone <clone URL from the output> <name>` — pick a short one-word name.
|
|
46
|
-
2. `cd <name>`, then `npx @genex-ai/cli-demo@
|
|
46
|
+
2. `cd <name>`, then `npx @genex-ai/cli-demo@dev init <name>` — never use
|
|
47
47
|
`--force`. This creates your own project; the original is untouched.
|
|
48
48
|
3. `npm install`, keep `base: './'` in `vite.config`, then build your changes
|
|
49
49
|
and ship with `npx genex preview`.
|
|
@@ -122,7 +122,7 @@ and re-link the clone to the same live game:
|
|
|
122
122
|
```bash
|
|
123
123
|
git clone <the game's repo url> my-game && cd my-game
|
|
124
124
|
npm install
|
|
125
|
-
npx @genex-ai/cli-demo@
|
|
125
|
+
npx @genex-ai/cli-demo@dev link <slug> # slug = the name in the play URL
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
`link` never creates a project: it signs in if needed (the browser opens once)
|
|
@@ -145,7 +145,7 @@ Safe to run any time — genex-owned skills are refreshed to the latest version,
|
|
|
145
145
|
and your own files are never touched:
|
|
146
146
|
|
|
147
147
|
```bash
|
|
148
|
-
npx @genex-ai/cli-demo@
|
|
148
|
+
npx @genex-ai/cli-demo@dev init
|
|
149
149
|
```
|
|
150
150
|
|
|
151
151
|
Use `--force` only if you intentionally want your own existing files overwritten
|
|
@@ -38,7 +38,7 @@ update, so update immediately.)
|
|
|
38
38
|
Run exactly the command the nudge printed, from the game project root:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
npm i -D @genex-ai/cli-demo@
|
|
41
|
+
npm i -D @genex-ai/cli-demo@dev # the genex CLI (a dev dependency)
|
|
42
42
|
npm i @genex-ai/embed-sdk@latest # identity/saves SDK (ships inside the game)
|
|
43
43
|
npm i @genex-ai/multiplayer@latest # multiplayer SDK (only if the game uses it)
|
|
44
44
|
```
|