@genex-ai/cli-demo 0.32.0 → 0.33.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.
package/dist/index.js CHANGED
@@ -567,6 +567,34 @@ function formatUpdateRequired(body) {
567
567
  const message = body.message ?? `Genex CLI ${body.clientVersion ?? getCliVersion()} is below the minimum supported version${body.minVersion ? ` ${body.minVersion}` : ""}.`;
568
568
  return [`${c.red("\u2717")} ${message}`, ` Update now \u2014 run: ${action} (then re-run this command)`];
569
569
  }
570
+ function shortDate(iso) {
571
+ const d = new Date(iso);
572
+ if (Number.isNaN(d.getTime())) return iso;
573
+ return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
574
+ }
575
+ function formatInsufficientCredits(body) {
576
+ const message = body.message ?? `this generation costs ${body.price ?? "?"} credits; your balance is ${body.balance ?? 0}.`;
577
+ const lines = [`${c.red("\u2717")} Out of credits \u2014 ${lowerFirst(message)}`];
578
+ if (body.refillAt && body.refillTo) {
579
+ lines.push(` Credits refill to ${body.refillTo} on ${shortDate(body.refillAt)}.`);
580
+ }
581
+ if (body.url) lines.push(` Get more or check your balance: ${body.url}`);
582
+ return lines;
583
+ }
584
+ function formatVerificationRequired(body) {
585
+ const lines = [
586
+ `${c.red("\u2717")} Email not verified \u2014 verify your email to unlock your free generation credits.`
587
+ ];
588
+ if (body.url) lines.push(` Verify here: ${body.url} (then re-run this command)`);
589
+ return lines;
590
+ }
591
+ function lowerFirst(s) {
592
+ return s ? s[0].toLowerCase() + s.slice(1) : s;
593
+ }
594
+ var structuredPrinted = /* @__PURE__ */ new WeakSet();
595
+ function printedStructuredError(res) {
596
+ return structuredPrinted.has(res);
597
+ }
570
598
  async function apiFetch(url, init = {}) {
571
599
  const headers = new Headers(init.headers);
572
600
  if (!headers.has(CLI_VERSION_HEADER)) headers.set(CLI_VERSION_HEADER, getCliVersion());
@@ -580,6 +608,39 @@ async function apiFetch(url, init = {}) {
580
608
  } catch {
581
609
  }
582
610
  }
611
+ if (res.status === 402) {
612
+ try {
613
+ const body = await res.clone().json();
614
+ if (body?.error === "insufficient_credits") {
615
+ for (const line of formatInsufficientCredits(body)) process.stderr.write(line + "\n");
616
+ structuredPrinted.add(res);
617
+ }
618
+ } catch {
619
+ }
620
+ }
621
+ if (res.status === 403) {
622
+ try {
623
+ const body = await res.clone().json();
624
+ if (body?.error === "email_verification_required") {
625
+ for (const line of formatVerificationRequired(body)) process.stderr.write(line + "\n");
626
+ structuredPrinted.add(res);
627
+ }
628
+ } catch {
629
+ }
630
+ }
631
+ if (res.status === 503) {
632
+ try {
633
+ const body = await res.clone().json();
634
+ if (body?.error === "generation_paused") {
635
+ process.stderr.write(
636
+ `${c.red("\u2717")} ${body.message ?? "Generation is temporarily paused platform-wide. Try again later."}
637
+ `
638
+ );
639
+ structuredPrinted.add(res);
640
+ }
641
+ } catch {
642
+ }
643
+ }
583
644
  return res;
584
645
  }
585
646
 
@@ -1664,6 +1725,10 @@ async function runGenerate(kind, opts) {
1664
1725
  process.exitCode = 1;
1665
1726
  return;
1666
1727
  }
1728
+ if (printedStructuredError(res)) {
1729
+ process.exitCode = 1;
1730
+ return;
1731
+ }
1667
1732
  if (!res.ok) {
1668
1733
  log.error(`Generation request failed (HTTP ${res.status}).`);
1669
1734
  process.exitCode = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genex-ai/cli-demo",
3
- "version": "0.32.0",
3
+ "version": "0.33.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": {
@@ -106,5 +106,14 @@ scene is a ghost: players and objects pass straight through it.
106
106
  ## Troubleshooting
107
107
 
108
108
  - **"Not authorized"** — run `npx @genex-ai/cli-demo@latest init` first (it writes your `GENEX_TOKEN`).
109
+ - **"Out of credits" (`insufficient_credits`)** — the account has no credits left for
110
+ this model generation. Tell the user the facts the CLI printed: their balance, this
111
+ generation's cost, and when their credits refill. Then offer to continue the build
112
+ with a procedurally-coded placeholder (a simple Three.js primitive-based stand-in
113
+ mesh) and mark the spot with `// TODO(genex): regenerate when credits refill` so
114
+ the real asset is one command away later. Do not stop the session over this.
115
+ - **"Email not verified" (`email_verification_required`)** — generation credits
116
+ unlock after the account's email is verified. Give the user the verify link the
117
+ CLI printed, wait for them to confirm, then re-run the command.
109
118
  - **The mesh looks low-detail / wrong** — make the prompt more specific
110
119
  (materials, style, parts) and regenerate; each run is a fresh asset.
@@ -73,6 +73,15 @@ Reuse one loaded `buffer` across many plays; create a fresh `Audio`/`PositionalA
73
73
  ## Troubleshooting
74
74
 
75
75
  - **"Not authorized"** — run `npx @genex-ai/cli-demo@latest init` first (it writes your `GENEX_TOKEN`).
76
+ - **"Out of credits" (`insufficient_credits`)** — the account has no credits left for
77
+ this sound generation. Tell the user the facts the CLI printed: their balance, this
78
+ generation's cost, and when their credits refill. Then offer to continue the build
79
+ with a procedurally-coded placeholder (a small WebAudio-synthesized stub sound)
80
+ and mark the spot with `// TODO(genex): regenerate when credits refill` so the
81
+ real asset is one command away later. Do not stop the session over this.
82
+ - **"Email not verified" (`email_verification_required`)** — generation credits
83
+ unlock after the account's email is verified. Give the user the verify link the
84
+ CLI printed, wait for them to confirm, then re-run the command.
76
85
  - **No sound** — the `AudioContext` is suspended until a user gesture; trigger the
77
86
  first play from a click/keydown. Confirm the camera has an `AudioListener`.
78
87
  - **Too quiet/loud** — `sound.setVolume(0..1)`; for positional, tune
@@ -77,6 +77,16 @@ scene.background = texture; // keep the raw texture for the visible sky
77
77
  ## Troubleshooting
78
78
 
79
79
  - **"Not authorized"** — run `npx @genex-ai/cli-demo@latest init` first (it writes your `GENEX_TOKEN`).
80
+ - **"Out of credits" (`insufficient_credits`)** — the account has no credits left for
81
+ this skybox generation. Tell the user the facts the CLI printed: their balance, this
82
+ generation's cost, and when their credits refill. Then offer to continue the build
83
+ with a procedurally-coded placeholder (a gradient/procedural sky or a plain
84
+ `scene.background` color) and mark the spot with
85
+ `// TODO(genex): regenerate when credits refill` so the real asset is one command
86
+ away later. Do not stop the session over this.
87
+ - **"Email not verified" (`email_verification_required`)** — generation credits
88
+ unlock after the account's email is verified. Give the user the verify link the
89
+ CLI printed, wait for them to confirm, then re-run the command.
80
90
  - **Sky looks too dark/bright** — adjust `renderer.toneMappingExposure`, or scale
81
91
  `scene.environment` influence via material `envMapIntensity`.
82
92
  - **Seam/pole artifacts** — that's inherent to equirect images; keep the camera
@@ -82,6 +82,16 @@ scene.add(ground);
82
82
  ## Troubleshooting
83
83
 
84
84
  - **"Not authorized"** — run `npx @genex-ai/cli-demo@latest init` first (it writes your `GENEX_TOKEN`).
85
+ - **"Out of credits" (`insufficient_credits`)** — the account has no credits left for
86
+ this texture generation. Tell the user the facts the CLI printed: their balance,
87
+ this generation's cost, and when their credits refill. Then offer to continue the
88
+ build with a procedurally-coded placeholder (a procedural Three.js material in a
89
+ matching color) and mark the spot with
90
+ `// TODO(genex): regenerate when credits refill` so the real asset is one command
91
+ away later. Do not stop the session over this.
92
+ - **"Email not verified" (`email_verification_required`)** — generation credits
93
+ unlock after the account's email is verified. Give the user the verify link the
94
+ CLI printed, wait for them to confirm, then re-run the command.
85
95
  - **Visible tiling seams** — use `--terrain` (tuned for seamless edges), lower the
86
96
  `repeat`, or blend two textures. Perfect seamlessness is a known v1 limitation.
87
97
  - **Colors look washed/dark** — ensure `map.colorSpace = THREE.SRGBColorSpace`.
@@ -9,13 +9,15 @@ Genex ships improvements continuously. The `genex` CLI tells you when something
9
9
  is stale; you (the agent) apply the update at the right moment and tell the
10
10
  user what happened. The user never manages versions themselves.
11
11
 
12
- ## The three signals in `genex` output
12
+ ## The signals in `genex` output
13
13
 
14
14
  | Line | Meaning | What you do |
15
15
  | -- | -- | -- |
16
16
  | `🔄 Genex skills updated to X.Y.Z` | Skills were auto-refreshed to match the installed CLI. | Nothing — informational. Skills stay in sync on their own. |
17
17
  | `⬆ Genex <package> X.Y.Z available (installed A.B.C) — run: <command>` | A newer npm package exists. | Run the printed command at a **safe moment** (below), then tell the user. |
18
18
  | `✗ … below the minimum supported version … Update now — run: <command>` | The API refuses this CLI version (HTTP 426, `cli_update_required`). | Run the printed command **now**, then re-run the refused genex command. |
19
+ | `✗ Out of credits — … costs N credits; your balance is M.` | The account can't cover this generation (HTTP 402, `insufficient_credits`). | Relay the printed facts (balance, cost, refill date, link) to the user; offer a procedural placeholder so the build continues — see the generation skill's Troubleshooting. |
20
+ | `✗ Email not verified — …` | Generation credits are locked until the email is verified (HTTP 403, `email_verification_required`). | Give the user the printed verify link, wait for them to confirm, then re-run the command. |
19
21
 
20
22
  ## Safe moments — when to apply a nudge
21
23