@genex-ai/cli-demo 1.36.2 → 1.36.3-dev.784
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/{blender-mcp-NRJ5FI22.js → blender-mcp-WSURPZET.js} +8 -7
- package/dist/{blender-serve-66OHC4ML.js → blender-serve-EH2MOW3U.js} +1 -1
- package/dist/{chunk-GOP5FRSJ.js → chunk-EABIVAGT.js} +217 -12
- package/dist/{chunk-QI7FIYBY.js → chunk-K4EHXOZK.js} +1 -1
- package/dist/index.js +600 -266
- package/package.json +1 -1
- package/templates/skills/genex-game-director/SKILL.md +1 -1
- package/templates/skills/genex-getting-started/SKILL.md +2 -2
- package/templates/skills/genex-llm-in-games/SKILL.md +209 -72
- package/templates/skills/genex-llm-in-games/references/pricing.md +126 -85
- package/templates/skills/genex-tool-llm/SKILL.md +11 -9
- package/templates/skills/genex-updates/SKILL.md +1 -1
|
@@ -6,11 +6,12 @@ import {
|
|
|
6
6
|
blenderSetupHint,
|
|
7
7
|
isRenderMode,
|
|
8
8
|
sceneSummary,
|
|
9
|
-
sheetOf
|
|
10
|
-
|
|
9
|
+
sheetOf,
|
|
10
|
+
writeSafely
|
|
11
|
+
} from "./chunk-EABIVAGT.js";
|
|
11
12
|
import {
|
|
12
13
|
getCliVersion
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-K4EHXOZK.js";
|
|
14
15
|
|
|
15
16
|
// src/commands/blender-mcp.ts
|
|
16
17
|
import fs from "fs/promises";
|
|
@@ -145,7 +146,7 @@ ${r.error.trimEnd()}`);
|
|
|
145
146
|
}
|
|
146
147
|
];
|
|
147
148
|
function write(msg) {
|
|
148
|
-
process.stdout
|
|
149
|
+
writeSafely(process.stdout, `${JSON.stringify(msg)}
|
|
149
150
|
`);
|
|
150
151
|
}
|
|
151
152
|
function reply(id, result) {
|
|
@@ -192,11 +193,11 @@ async function handle(msg) {
|
|
|
192
193
|
fail(id, -32601, `Method not found: ${method}`);
|
|
193
194
|
}
|
|
194
195
|
var stderrLog = {
|
|
195
|
-
step: (m) => process.stderr
|
|
196
|
+
step: (m) => writeSafely(process.stderr, `[genex-blender-mcp] ${m}
|
|
196
197
|
`),
|
|
197
|
-
warn: (m) => process.stderr
|
|
198
|
+
warn: (m) => writeSafely(process.stderr, `[genex-blender-mcp] ${m}
|
|
198
199
|
`),
|
|
199
|
-
error: (m) => process.stderr
|
|
200
|
+
error: (m) => writeSafely(process.stderr, `[genex-blender-mcp] ${m}
|
|
200
201
|
`)
|
|
201
202
|
};
|
|
202
203
|
async function mcpEndpoint() {
|
|
@@ -10,7 +10,189 @@ import {
|
|
|
10
10
|
getGenexEnvPath,
|
|
11
11
|
normalizeApiOrigin,
|
|
12
12
|
originKey
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-K4EHXOZK.js";
|
|
14
|
+
|
|
15
|
+
// src/lib/printed.ts
|
|
16
|
+
var printed = /* @__PURE__ */ new WeakSet();
|
|
17
|
+
function markPrinted(err) {
|
|
18
|
+
if (typeof err === "object" && err !== null) printed.add(err);
|
|
19
|
+
return err;
|
|
20
|
+
}
|
|
21
|
+
function wasPrinted(err) {
|
|
22
|
+
return typeof err === "object" && err !== null && printed.has(err);
|
|
23
|
+
}
|
|
24
|
+
var expected = /* @__PURE__ */ new WeakSet();
|
|
25
|
+
function markExpected(err) {
|
|
26
|
+
if (typeof err === "object" && err !== null) expected.add(err);
|
|
27
|
+
return err;
|
|
28
|
+
}
|
|
29
|
+
function isExpected(err) {
|
|
30
|
+
return typeof err === "object" && err !== null && expected.has(err);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/lib/error-kinds.ts
|
|
34
|
+
function asErrorLike(value) {
|
|
35
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
36
|
+
}
|
|
37
|
+
var NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
38
|
+
"ECONNREFUSED",
|
|
39
|
+
"ECONNRESET",
|
|
40
|
+
"ECONNABORTED",
|
|
41
|
+
"ETIMEDOUT",
|
|
42
|
+
"ENOTFOUND",
|
|
43
|
+
"EAI_AGAIN",
|
|
44
|
+
"ENETUNREACH",
|
|
45
|
+
"ENETDOWN",
|
|
46
|
+
"EHOSTUNREACH",
|
|
47
|
+
"EHOSTDOWN",
|
|
48
|
+
"EPIPE"
|
|
49
|
+
]);
|
|
50
|
+
function isNetworkCode(code) {
|
|
51
|
+
return typeof code === "string" && (NETWORK_ERROR_CODES.has(code) || code.startsWith("UND_ERR_"));
|
|
52
|
+
}
|
|
53
|
+
function networkErrorCode(err, depth = 0) {
|
|
54
|
+
const e = asErrorLike(err);
|
|
55
|
+
if (!e || depth > 4) return null;
|
|
56
|
+
if (isNetworkCode(e.code)) return e.code;
|
|
57
|
+
if (Array.isArray(e.errors)) {
|
|
58
|
+
for (const inner of e.errors) {
|
|
59
|
+
const code = networkErrorCode(inner, depth + 1);
|
|
60
|
+
if (code) return code;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return networkErrorCode(e.cause, depth + 1);
|
|
64
|
+
}
|
|
65
|
+
function isNetworkFetchFailure(err) {
|
|
66
|
+
const e = asErrorLike(err);
|
|
67
|
+
return e !== null && e.message === "fetch failed" && networkErrorCode(e.cause) !== null;
|
|
68
|
+
}
|
|
69
|
+
function networkFailureMessage(code) {
|
|
70
|
+
return `Couldn't reach Genex (${code}) \u2014 check your connection and re-run this command.`;
|
|
71
|
+
}
|
|
72
|
+
var FS_PERMISSION_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EROFS"]);
|
|
73
|
+
var FS_SYSCALLS = /* @__PURE__ */ new Set([
|
|
74
|
+
"access",
|
|
75
|
+
"chmod",
|
|
76
|
+
"chown",
|
|
77
|
+
"close",
|
|
78
|
+
"copyfile",
|
|
79
|
+
"cp",
|
|
80
|
+
"fchmod",
|
|
81
|
+
"fchown",
|
|
82
|
+
"fdatasync",
|
|
83
|
+
"fsync",
|
|
84
|
+
"ftruncate",
|
|
85
|
+
"futime",
|
|
86
|
+
"lchown",
|
|
87
|
+
"link",
|
|
88
|
+
"lstat",
|
|
89
|
+
"lutimes",
|
|
90
|
+
"mkdir",
|
|
91
|
+
"mkdtemp",
|
|
92
|
+
"open",
|
|
93
|
+
"opendir",
|
|
94
|
+
"read",
|
|
95
|
+
"readlink",
|
|
96
|
+
"realpath",
|
|
97
|
+
"rename",
|
|
98
|
+
"rm",
|
|
99
|
+
"rmdir",
|
|
100
|
+
"scandir",
|
|
101
|
+
"stat",
|
|
102
|
+
"symlink",
|
|
103
|
+
"truncate",
|
|
104
|
+
"unlink",
|
|
105
|
+
"utime",
|
|
106
|
+
"write",
|
|
107
|
+
"writev"
|
|
108
|
+
]);
|
|
109
|
+
function fsPermissionInfo(err) {
|
|
110
|
+
const e = asErrorLike(err);
|
|
111
|
+
if (!e || typeof e.code !== "string" || !FS_PERMISSION_CODES.has(e.code)) return null;
|
|
112
|
+
if (typeof e.syscall !== "string" || !FS_SYSCALLS.has(e.syscall)) return null;
|
|
113
|
+
const where = typeof e.dest === "string" ? e.dest : typeof e.path === "string" ? e.path : void 0;
|
|
114
|
+
return { code: e.code, syscall: e.syscall, ...where ? { path: where } : {} };
|
|
115
|
+
}
|
|
116
|
+
function fsPermissionAdvice(code, platform) {
|
|
117
|
+
if (code === "EROFS") return "it is on a read-only volume; run genex from a folder on a writable disk.";
|
|
118
|
+
if (platform === "win32") {
|
|
119
|
+
return "Windows refused; close any program that has it open and make sure your account may write there (antivirus or Controlled Folder Access can block it too), then re-run.";
|
|
120
|
+
}
|
|
121
|
+
if (platform === "darwin" && code === "EPERM") {
|
|
122
|
+
return "macOS blocked it; give your terminal or agent app access to this folder (System Settings \u2192 Privacy & Security \u2192 Files and Folders, or Full Disk Access) or allow the path in your agent's sandbox, then re-run.";
|
|
123
|
+
}
|
|
124
|
+
return "permission denied; make sure your user owns it (an earlier `sudo` run can leave it owned by root) and that your agent's sandbox, if any, allows writing there, then re-run.";
|
|
125
|
+
}
|
|
126
|
+
var READ_SYSCALLS = /* @__PURE__ */ new Set([
|
|
127
|
+
"access",
|
|
128
|
+
"lstat",
|
|
129
|
+
"opendir",
|
|
130
|
+
"read",
|
|
131
|
+
"readlink",
|
|
132
|
+
"realpath",
|
|
133
|
+
"scandir",
|
|
134
|
+
"stat"
|
|
135
|
+
]);
|
|
136
|
+
function fsPermissionMessage(info, target, platform = process.platform) {
|
|
137
|
+
const where = target ?? info.path ?? "a file it needs";
|
|
138
|
+
const verb = target !== void 0 ? "write" : READ_SYSCALLS.has(info.syscall) ? "read" : info.syscall === "open" ? "open" : "write";
|
|
139
|
+
return `Genex couldn't ${verb} ${where} (${info.code}) \u2014 ${fsPermissionAdvice(info.code, platform)}`;
|
|
140
|
+
}
|
|
141
|
+
var FsPermissionError = class extends Error {
|
|
142
|
+
code;
|
|
143
|
+
syscall;
|
|
144
|
+
path;
|
|
145
|
+
constructor(info, message, cause) {
|
|
146
|
+
super(message, { cause });
|
|
147
|
+
this.name = "FsPermissionError";
|
|
148
|
+
this.code = info.code;
|
|
149
|
+
this.syscall = info.syscall;
|
|
150
|
+
if (info.path) this.path = info.path;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
function explainFsPermission(err, target) {
|
|
154
|
+
const info = fsPermissionInfo(err);
|
|
155
|
+
if (!info) return null;
|
|
156
|
+
return markExpected(new FsPermissionError(info, fsPermissionMessage(info, target), err));
|
|
157
|
+
}
|
|
158
|
+
function describeError(err, platform = process.platform) {
|
|
159
|
+
if (isNetworkFetchFailure(err)) return networkFailureMessage(networkErrorCode(err) ?? "network");
|
|
160
|
+
if (!(err instanceof FsPermissionError)) {
|
|
161
|
+
const info = fsPermissionInfo(err);
|
|
162
|
+
if (info) return fsPermissionMessage(info, void 0, platform);
|
|
163
|
+
}
|
|
164
|
+
return err instanceof Error ? err.message : String(err);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/utils/stdio.ts
|
|
168
|
+
var broken = /* @__PURE__ */ new WeakSet();
|
|
169
|
+
function isBrokenPipe(err) {
|
|
170
|
+
if (typeof err !== "object" || err === null) return false;
|
|
171
|
+
const { code, message } = err;
|
|
172
|
+
if (code === "EPIPE") return true;
|
|
173
|
+
return typeof message === "string" && /\bEPIPE\b/.test(message);
|
|
174
|
+
}
|
|
175
|
+
function writeSafely(stream, text) {
|
|
176
|
+
if (broken.has(stream)) return;
|
|
177
|
+
try {
|
|
178
|
+
stream.write(text);
|
|
179
|
+
} catch (err) {
|
|
180
|
+
if (!isBrokenPipe(err)) throw err;
|
|
181
|
+
broken.add(stream);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function guardStdio(streams = [process.stdout, process.stderr]) {
|
|
185
|
+
for (const stream of streams) {
|
|
186
|
+
stream.on("error", (err) => {
|
|
187
|
+
const code = err?.code;
|
|
188
|
+
if (isBrokenPipe(err) || code === "ERR_STREAM_DESTROYED") {
|
|
189
|
+
broken.add(stream);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
throw err;
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
14
196
|
|
|
15
197
|
// src/lib/terms.ts
|
|
16
198
|
import readline from "readline";
|
|
@@ -310,7 +492,7 @@ async function runAccept(opts) {
|
|
|
310
492
|
|
|
311
493
|
// src/lib/api.ts
|
|
312
494
|
var stderrLogger = /* @__PURE__ */ (() => {
|
|
313
|
-
const err = (s) =>
|
|
495
|
+
const err = (s) => writeSafely(process.stderr, s + "\n");
|
|
314
496
|
return {
|
|
315
497
|
info: err,
|
|
316
498
|
success: (m) => err(`${c.green("\u2713")} ${m}`),
|
|
@@ -360,7 +542,7 @@ function shortDate(iso) {
|
|
|
360
542
|
return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
361
543
|
}
|
|
362
544
|
function formatInsufficientCredits(body) {
|
|
363
|
-
const message = body.message ?? `this generation costs ${body.price ?? "?"} credits; your balance is ${body.balance ?? 0}
|
|
545
|
+
const message = body.message ?? (body.price === void 0 && typeof body.requiredCredits === "number" ? `this call reserves up to ${body.requiredCredits} credits; ${body.spendableCredits ?? 0} are spendable.` : `this generation costs ${body.price ?? "?"} credits; your balance is ${body.balance ?? 0}.`);
|
|
364
546
|
const lines = [`${c.red("\u2717")} Out of credits \u2014 ${lowerFirst(message)}`];
|
|
365
547
|
if (body.refillAt && body.refillTo) {
|
|
366
548
|
lines.push(` Credits refill to ${body.refillTo} on ${shortDate(body.refillAt)}.`);
|
|
@@ -404,7 +586,13 @@ async function apiFetch(url, init = {}, opts = {}) {
|
|
|
404
586
|
}
|
|
405
587
|
const bearer = headers.get("authorization")?.replace(/^Bearer\s+/i, "");
|
|
406
588
|
if (bearer) assertTokenDestination(bearer, url);
|
|
407
|
-
|
|
589
|
+
let res;
|
|
590
|
+
try {
|
|
591
|
+
res = await fetch(url, { ...init, headers, redirect: "error" });
|
|
592
|
+
} catch (err) {
|
|
593
|
+
if (networkErrorCode(err) !== null) markExpected(err);
|
|
594
|
+
throw err;
|
|
595
|
+
}
|
|
408
596
|
if (res.status === 403 && !opts.noTermsWait && await isTermsRefusal(res)) {
|
|
409
597
|
const log = stderrLogger;
|
|
410
598
|
reportTermsRefusal(log, await termsRefusalUrl(res));
|
|
@@ -539,15 +727,19 @@ async function restrictFilePermissions(filePath) {
|
|
|
539
727
|
|
|
540
728
|
// src/lib/secret-file.ts
|
|
541
729
|
async function writeSecretFile(file, content, exclusive = false) {
|
|
542
|
-
await fs3.mkdir(path3.dirname(file), { recursive: true, mode: 448 });
|
|
543
|
-
const temporary = `${file}.${randomUUID()}.tmp`;
|
|
544
730
|
try {
|
|
545
|
-
await fs3.
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
731
|
+
await fs3.mkdir(path3.dirname(file), { recursive: true, mode: 448 });
|
|
732
|
+
const temporary = `${file}.${randomUUID()}.tmp`;
|
|
733
|
+
try {
|
|
734
|
+
await fs3.writeFile(temporary, content, { mode: 384, flag: "wx" });
|
|
735
|
+
await restrictFilePermissions(temporary);
|
|
736
|
+
if (exclusive) await fs3.link(temporary, file);
|
|
737
|
+
else await fs3.rename(temporary, file);
|
|
738
|
+
} finally {
|
|
739
|
+
await fs3.rm(temporary, { force: true });
|
|
740
|
+
}
|
|
741
|
+
} catch (err) {
|
|
742
|
+
throw explainFsPermission(err, file) ?? err;
|
|
551
743
|
}
|
|
552
744
|
}
|
|
553
745
|
|
|
@@ -944,6 +1136,19 @@ async function releaseCliSeat(opts) {
|
|
|
944
1136
|
}
|
|
945
1137
|
|
|
946
1138
|
export {
|
|
1139
|
+
markPrinted,
|
|
1140
|
+
wasPrinted,
|
|
1141
|
+
markExpected,
|
|
1142
|
+
isExpected,
|
|
1143
|
+
networkErrorCode,
|
|
1144
|
+
isNetworkFetchFailure,
|
|
1145
|
+
FS_PERMISSION_CODES,
|
|
1146
|
+
fsPermissionInfo,
|
|
1147
|
+
explainFsPermission,
|
|
1148
|
+
describeError,
|
|
1149
|
+
isBrokenPipe,
|
|
1150
|
+
writeSafely,
|
|
1151
|
+
guardStdio,
|
|
947
1152
|
excludeFile,
|
|
948
1153
|
run,
|
|
949
1154
|
readRemoteSource,
|
|
@@ -38,7 +38,7 @@ import fs from "fs";
|
|
|
38
38
|
import os from "os";
|
|
39
39
|
import path from "path";
|
|
40
40
|
import { fileURLToPath } from "url";
|
|
41
|
-
var RAW_CHANNEL = "
|
|
41
|
+
var RAW_CHANNEL = "dev";
|
|
42
42
|
var CLI_CHANNEL = RAW_CHANNEL === "dev" ? "dev" : "latest";
|
|
43
43
|
var STANDS = {
|
|
44
44
|
prod: { api: "https://api.genex.games", dashboard: "https://genex.games" },
|