@genex-ai/cli-demo 1.36.12-dev.999 → 1.36.13-dev.1018
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 +3 -1
- package/dist/index.js +100 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,7 +92,9 @@ the original folder can't be found.
|
|
|
92
92
|
`dist/` to R2 through a short-lived scoped upload token and flips a live pointer;
|
|
93
93
|
the editable source is pushed to the repo's single `main` branch (for Remix). Game
|
|
94
94
|
bytes never pass through our API. Pass `--no-build` to deploy whatever is already
|
|
95
|
-
built.
|
|
95
|
+
built. Pass `--source <dir>` (also on `make-remixable`) when the game's own files live
|
|
96
|
+
in another folder than the one you deploy from: that folder is pushed as the source,
|
|
97
|
+
while the project, the build and `dist/` are still read from here.
|
|
96
98
|
|
|
97
99
|
- **`genex preview`** uploads the current build to the project's hosted draft URL
|
|
98
100
|
(`https://<slug>.genex.technology/`) without listing it publicly — re-run it
|
package/dist/index.js
CHANGED
|
@@ -1031,6 +1031,7 @@ var LFS_PATTERNS = [
|
|
|
1031
1031
|
"*.vrm",
|
|
1032
1032
|
"*.fbx",
|
|
1033
1033
|
"*.obj",
|
|
1034
|
+
"*.blend",
|
|
1034
1035
|
// textures / images
|
|
1035
1036
|
"*.png",
|
|
1036
1037
|
"*.jpg",
|
|
@@ -1041,13 +1042,39 @@ var LFS_PATTERNS = [
|
|
|
1041
1042
|
"*.hdr",
|
|
1042
1043
|
"*.exr",
|
|
1043
1044
|
"*.tga",
|
|
1045
|
+
"*.psd",
|
|
1046
|
+
"*.tif",
|
|
1047
|
+
"*.tiff",
|
|
1044
1048
|
// audio / video
|
|
1045
1049
|
"*.mp3",
|
|
1046
1050
|
"*.ogg",
|
|
1047
1051
|
"*.wav",
|
|
1048
1052
|
"*.m4a",
|
|
1049
1053
|
"*.mp4",
|
|
1050
|
-
"*.webm"
|
|
1054
|
+
"*.webm",
|
|
1055
|
+
"*.aif",
|
|
1056
|
+
"*.aiff",
|
|
1057
|
+
"*.flac",
|
|
1058
|
+
"*.mov",
|
|
1059
|
+
"*.avi",
|
|
1060
|
+
// fonts
|
|
1061
|
+
"*.ttf",
|
|
1062
|
+
"*.otf",
|
|
1063
|
+
// engine packages and packed assets (Unity, Unreal, Godot)
|
|
1064
|
+
"*.unitypackage",
|
|
1065
|
+
"*.bundle",
|
|
1066
|
+
"*.uasset",
|
|
1067
|
+
"*.umap",
|
|
1068
|
+
"*.pck",
|
|
1069
|
+
// native libraries and plugins
|
|
1070
|
+
"*.dll",
|
|
1071
|
+
"*.so",
|
|
1072
|
+
"*.dylib",
|
|
1073
|
+
"*.a",
|
|
1074
|
+
"*.lib",
|
|
1075
|
+
// archives
|
|
1076
|
+
"*.zip",
|
|
1077
|
+
"*.7z"
|
|
1051
1078
|
];
|
|
1052
1079
|
async function writeGitattributes(dir, log) {
|
|
1053
1080
|
const file = path4.join(dir, ".gitattributes");
|
|
@@ -5944,8 +5971,9 @@ async function deployGame(ctx, opts, log) {
|
|
|
5944
5971
|
return false;
|
|
5945
5972
|
}
|
|
5946
5973
|
let sourceCommitSha;
|
|
5974
|
+
const sourceDir = opts.sourceDir ?? cwd;
|
|
5947
5975
|
const pushed = await pushSource(
|
|
5948
|
-
|
|
5976
|
+
sourceDir,
|
|
5949
5977
|
ctx,
|
|
5950
5978
|
log,
|
|
5951
5979
|
opts.channel === "staging" ? "preview" : "main",
|
|
@@ -5959,11 +5987,14 @@ async function deployGame(ctx, opts, log) {
|
|
|
5959
5987
|
const published = await callPublish(ctx, commit, opts, log, sourceCommitSha, capabilities);
|
|
5960
5988
|
if (!published) return false;
|
|
5961
5989
|
if (opts.channel === "staging") {
|
|
5962
|
-
const
|
|
5990
|
+
const pushedHere = opts.sourceDir === void 0;
|
|
5991
|
+
const tree = pushedHere ? await sourceTreeHash(cwd) : null;
|
|
5963
5992
|
const current = await readProject(cwd);
|
|
5964
5993
|
if (current) {
|
|
5994
|
+
const { sourceTree: recorded, ...rest } = current;
|
|
5995
|
+
const kept = pushedHere && recorded ? { sourceTree: recorded } : {};
|
|
5965
5996
|
await writeProject(
|
|
5966
|
-
{ ...
|
|
5997
|
+
{ ...rest, ...kept, stagingCommit: commit, ...tree ? { sourceTree: tree } : {} },
|
|
5967
5998
|
cwd
|
|
5968
5999
|
).catch(() => {
|
|
5969
6000
|
});
|
|
@@ -6229,13 +6260,13 @@ async function callPublish(ctx, commit, opts, log, sourceCommitSha, capabilities
|
|
|
6229
6260
|
}
|
|
6230
6261
|
return { url: body?.url ?? "" };
|
|
6231
6262
|
}
|
|
6232
|
-
async function pushSource(
|
|
6263
|
+
async function pushSource(sourceDir, ctx, log, branch = "main", expectStagingCommit, onCommit) {
|
|
6233
6264
|
const target = await fetchPushUrl(ctx, log, expectStagingCommit);
|
|
6234
6265
|
if (target === "stale") return "stale";
|
|
6235
6266
|
if (!target) return false;
|
|
6236
6267
|
const ref = target.managed ? branch : "main";
|
|
6237
6268
|
const first = await pushWorktree(
|
|
6238
|
-
|
|
6269
|
+
sourceDir,
|
|
6239
6270
|
target.pushUrl,
|
|
6240
6271
|
target.managed,
|
|
6241
6272
|
log,
|
|
@@ -6253,7 +6284,7 @@ async function pushSource(cwd, ctx, log, branch = "main", expectStagingCommit, o
|
|
|
6253
6284
|
if (fresh === "stale") return "stale";
|
|
6254
6285
|
if (!fresh) return false;
|
|
6255
6286
|
return await pushWorktree(
|
|
6256
|
-
|
|
6287
|
+
sourceDir,
|
|
6257
6288
|
fresh.pushUrl,
|
|
6258
6289
|
fresh.managed,
|
|
6259
6290
|
log,
|
|
@@ -6263,6 +6294,34 @@ async function pushSource(cwd, ctx, log, branch = "main", expectStagingCommit, o
|
|
|
6263
6294
|
fresh.sourceLimits
|
|
6264
6295
|
) === true;
|
|
6265
6296
|
}
|
|
6297
|
+
async function resolveSourceDir(dir, cwd = process.cwd()) {
|
|
6298
|
+
const abs = path17.resolve(cwd, dir);
|
|
6299
|
+
const stat = await fs17.lstat(abs).catch(() => null);
|
|
6300
|
+
if (!stat) return { refused: `--source ${abs} does not exist.` };
|
|
6301
|
+
if (stat.isSymbolicLink()) {
|
|
6302
|
+
return { refused: `--source ${abs} is a symbolic link. Pass the folder itself.` };
|
|
6303
|
+
}
|
|
6304
|
+
if (!stat.isDirectory()) return { refused: `--source ${abs} is not a folder.` };
|
|
6305
|
+
const real = await fs17.realpath(abs);
|
|
6306
|
+
const project = await fs17.realpath(cwd).catch(() => path17.resolve(cwd));
|
|
6307
|
+
const genex = path17.join(project, ".genex");
|
|
6308
|
+
const genexTarget = await fs17.realpath(genex).catch(() => genex);
|
|
6309
|
+
for (const meta of /* @__PURE__ */ new Set([genex, genexTarget])) {
|
|
6310
|
+
if (real === meta) {
|
|
6311
|
+
return { refused: `--source ${abs} is this project's .genex folder, not the game's source.` };
|
|
6312
|
+
}
|
|
6313
|
+
if (isInside(meta, real)) {
|
|
6314
|
+
return {
|
|
6315
|
+
refused: `--source ${abs} holds this project's .genex folder. Pass a separate folder with the game's own files.`
|
|
6316
|
+
};
|
|
6317
|
+
}
|
|
6318
|
+
}
|
|
6319
|
+
return { dir: real };
|
|
6320
|
+
}
|
|
6321
|
+
function isInside(child, parent) {
|
|
6322
|
+
const rel = path17.relative(parent, child);
|
|
6323
|
+
return rel !== "" && rel !== ".." && !rel.startsWith(`..${path17.sep}`) && !path17.isAbsolute(rel);
|
|
6324
|
+
}
|
|
6266
6325
|
var WORKSPACE_SOURCE_REF = "workspace";
|
|
6267
6326
|
function gitLfsInstallCommand(platform) {
|
|
6268
6327
|
if (platform === "darwin") {
|
|
@@ -6274,7 +6333,7 @@ function gitLfsInstallCommand(platform) {
|
|
|
6274
6333
|
}
|
|
6275
6334
|
return { bin: "sudo", args: ["-n", "apt-get", "install", "-y", "git-lfs"], env: {} };
|
|
6276
6335
|
}
|
|
6277
|
-
async function pushWorktree(
|
|
6336
|
+
async function pushWorktree(workTree, pushUrl, managed, log, branch = "main", onCommit, skipSizeCheck = false, limits) {
|
|
6278
6337
|
const EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
6279
6338
|
const failed = () => {
|
|
6280
6339
|
log.error("Couldn't save your game's source \u2014 please try again.");
|
|
@@ -6296,7 +6355,7 @@ async function pushWorktree(cwd, pushUrl, managed, log, branch = "main", onCommi
|
|
|
6296
6355
|
try {
|
|
6297
6356
|
if ((await run("git", ["init", "-q"], base)).code !== 0) return failed();
|
|
6298
6357
|
await fs17.writeFile(path17.join(gitDir, "info", "exclude"), excludeFile());
|
|
6299
|
-
const env = { ...base, GIT_WORK_TREE:
|
|
6358
|
+
const env = { ...base, GIT_WORK_TREE: workTree, GIT_INDEX_FILE: path17.join(gitDir, "index-source") };
|
|
6300
6359
|
let lfs = (await run("git", ["lfs", "version"], base)).code !== 0 ? false : true;
|
|
6301
6360
|
if (!lfs) {
|
|
6302
6361
|
log.step("Installing git-lfs (keeps large binary assets out of the source push)\u2026");
|
|
@@ -6310,7 +6369,7 @@ async function pushWorktree(cwd, pushUrl, managed, log, branch = "main", onCommi
|
|
|
6310
6369
|
}
|
|
6311
6370
|
}
|
|
6312
6371
|
if (lfs) {
|
|
6313
|
-
await writeGitattributes(
|
|
6372
|
+
await writeGitattributes(workTree, log);
|
|
6314
6373
|
const filters = [
|
|
6315
6374
|
["filter.lfs.clean", "git-lfs clean -- %f"],
|
|
6316
6375
|
["filter.lfs.smudge", "git-lfs smudge -- %f"],
|
|
@@ -6325,7 +6384,7 @@ async function pushWorktree(cwd, pushUrl, managed, log, branch = "main", onCommi
|
|
|
6325
6384
|
log.error("Nothing to publish \u2014 the project has no files.");
|
|
6326
6385
|
return "failed";
|
|
6327
6386
|
}
|
|
6328
|
-
const payload = await measurePayload(
|
|
6387
|
+
const payload = await measurePayload(workTree, staged);
|
|
6329
6388
|
log.dim(`Source: ${payload.files} files, ${formatBytes2(payload.bytes)}.`);
|
|
6330
6389
|
const ceiling = limits ?? FALLBACK_SOURCE_LIMITS;
|
|
6331
6390
|
if (!skipSizeCheck && isOversized(payload, ceiling)) {
|
|
@@ -6939,6 +6998,12 @@ async function runPreview(opts) {
|
|
|
6939
6998
|
process.exitCode = 1;
|
|
6940
6999
|
return;
|
|
6941
7000
|
}
|
|
7001
|
+
const source = opts.sourceDir === void 0 ? void 0 : await resolveSourceDir(opts.sourceDir);
|
|
7002
|
+
if (source && "refused" in source) {
|
|
7003
|
+
log.error(`${source.refused} Nothing was uploaded.`);
|
|
7004
|
+
process.exitCode = 1;
|
|
7005
|
+
return;
|
|
7006
|
+
}
|
|
6942
7007
|
const apiUrl = getApiUrl(meta.apiUrl);
|
|
6943
7008
|
const token = await readUserToken(opts.envPath, apiUrl);
|
|
6944
7009
|
if (!token) {
|
|
@@ -6965,6 +7030,7 @@ async function runPreview(opts) {
|
|
|
6965
7030
|
channel: "staging",
|
|
6966
7031
|
noBuild: opts.noBuild,
|
|
6967
7032
|
force: opts.force,
|
|
7033
|
+
sourceDir: source?.dir,
|
|
6968
7034
|
matchmaking: detections.matchmaking,
|
|
6969
7035
|
embedSdkVersion: detections.embedSdkVersion,
|
|
6970
7036
|
multiplayer: detections.multiplayer,
|
|
@@ -8271,6 +8337,12 @@ async function runMakeRemixable(opts) {
|
|
|
8271
8337
|
process.exitCode = 1;
|
|
8272
8338
|
return;
|
|
8273
8339
|
}
|
|
8340
|
+
const source = opts.sourceDir === void 0 ? void 0 : await resolveSourceDir(opts.sourceDir);
|
|
8341
|
+
if (source && "refused" in source) {
|
|
8342
|
+
log.error(`${source.refused} Nothing was pushed.`);
|
|
8343
|
+
process.exitCode = 1;
|
|
8344
|
+
return;
|
|
8345
|
+
}
|
|
8274
8346
|
const apiUrl = getApiUrl(opts.apiUrl ?? meta.apiUrl);
|
|
8275
8347
|
const token = await readUserToken(opts.envPath, apiUrl);
|
|
8276
8348
|
if (!token) {
|
|
@@ -8312,7 +8384,7 @@ async function runMakeRemixable(opts) {
|
|
|
8312
8384
|
return;
|
|
8313
8385
|
}
|
|
8314
8386
|
log.step("Copying your game's source to the public repo\u2026");
|
|
8315
|
-
if (await pushWorktree(process.cwd(), data.pushUrl, true, log) !== true) {
|
|
8387
|
+
if (await pushWorktree(source?.dir ?? process.cwd(), data.pushUrl, true, log) !== true) {
|
|
8316
8388
|
process.exitCode = 1;
|
|
8317
8389
|
return;
|
|
8318
8390
|
}
|
|
@@ -8763,6 +8835,12 @@ async function runPublish(opts) {
|
|
|
8763
8835
|
process.exitCode = 1;
|
|
8764
8836
|
return;
|
|
8765
8837
|
}
|
|
8838
|
+
const source = opts.sourceDir === void 0 ? void 0 : await resolveSourceDir(opts.sourceDir);
|
|
8839
|
+
if (source && "refused" in source) {
|
|
8840
|
+
log.error(`${source.refused} Nothing was uploaded.`);
|
|
8841
|
+
process.exitCode = 1;
|
|
8842
|
+
return;
|
|
8843
|
+
}
|
|
8766
8844
|
const apiUrl = getApiUrl(opts.apiUrl ?? meta.apiUrl);
|
|
8767
8845
|
const token = opts.token ?? await readUserToken(opts.envPath, apiUrl);
|
|
8768
8846
|
if (!token) {
|
|
@@ -8783,6 +8861,7 @@ async function runPublish(opts) {
|
|
|
8783
8861
|
channel: "staging",
|
|
8784
8862
|
noBuild: opts.noBuild,
|
|
8785
8863
|
force: opts.force,
|
|
8864
|
+
sourceDir: source?.dir,
|
|
8786
8865
|
matchmaking: detections.matchmaking,
|
|
8787
8866
|
embedSdkVersion: detections.embedSdkVersion,
|
|
8788
8867
|
multiplayer: detections.multiplayer,
|
|
@@ -28852,6 +28931,9 @@ ${c.bold("Options for `rename`")}
|
|
|
28852
28931
|
|
|
28853
28932
|
${c.bold("Options for `preview` / `publish`")}
|
|
28854
28933
|
--no-build Skip the build step; deploy whatever is already built.
|
|
28934
|
+
--source <dir> Push <dir> as the game's editable source instead of this
|
|
28935
|
+
folder. The project, the build and dist/ still come from
|
|
28936
|
+
here. Also on 'make-remixable'.
|
|
28855
28937
|
--no-push (publish) Skip build + push; only flip the gallery flag.
|
|
28856
28938
|
--title <title> (publish) Gallery title.
|
|
28857
28939
|
--description <text> (publish) Gallery description.
|
|
@@ -29494,6 +29576,9 @@ function parseArgs(argv) {
|
|
|
29494
29576
|
...Object.keys(UI_NUMBER_FLAGS),
|
|
29495
29577
|
"--source-repo-url",
|
|
29496
29578
|
"--source-author",
|
|
29579
|
+
// `preview` / `publish` / `make-remixable --source <dir>`: the folder pushed as the
|
|
29580
|
+
// game's source when it is not the one the command runs in.
|
|
29581
|
+
"--source",
|
|
29497
29582
|
"--license",
|
|
29498
29583
|
"--purchase-url",
|
|
29499
29584
|
"--product-name",
|
|
@@ -30258,6 +30343,9 @@ function applyValueFlag(options, flag, value) {
|
|
|
30258
30343
|
case "--src":
|
|
30259
30344
|
options.src = value;
|
|
30260
30345
|
break;
|
|
30346
|
+
case "--source":
|
|
30347
|
+
options.sourceDir = value;
|
|
30348
|
+
break;
|
|
30261
30349
|
case "--clip":
|
|
30262
30350
|
options.clipPath = value;
|
|
30263
30351
|
break;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genex-ai/cli-demo",
|
|
3
|
-
"version": "1.36.
|
|
3
|
+
"version": "1.36.13-dev.1018",
|
|
4
4
|
"description": "Set up your project's agent workspace (.claude/.codex/.cursor in the game folder), authorize, create a game project, generate AI assets, and publish (genex CLI).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|