@genex-ai/cli-demo 1.9.0-dev.512 → 1.9.1-dev.514

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 (2) hide show
  1. package/dist/index.js +103 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4640,6 +4640,78 @@ async function uiAudit(opts, log) {
4640
4640
  if (opts.strict || hard.length > 0) process.exitCode = 1;
4641
4641
  }
4642
4642
 
4643
+ // src/lib/terms.ts
4644
+ import readline2 from "readline";
4645
+ var TERMS_ERROR_CODE = "terms_acceptance_required";
4646
+ async function isTermsRefusal(res) {
4647
+ if (res.status !== 403) return false;
4648
+ try {
4649
+ const body = await res.clone().json();
4650
+ return body?.error === TERMS_ERROR_CODE;
4651
+ } catch {
4652
+ return false;
4653
+ }
4654
+ }
4655
+ function reportTermsRefusal(log, authUrl) {
4656
+ log.error("Your account needs to accept the current Terms before publishing.");
4657
+ log.dim(" Nothing was deployed, and nothing on your game changed.");
4658
+ if (!inHostedSession()) {
4659
+ log.dim(` Run ${c.cyan("npx genex accept")} to read them and agree here.`);
4660
+ }
4661
+ log.dim(` Open ${c.cyan(`${getAuthUrl(authUrl)}/terms`)} and agree, then try again.`);
4662
+ }
4663
+ function askOnStdin(question) {
4664
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
4665
+ return new Promise((resolve) => {
4666
+ rl.question(question, (answer) => {
4667
+ rl.close();
4668
+ resolve(answer);
4669
+ });
4670
+ });
4671
+ }
4672
+ async function runAccept(opts) {
4673
+ const { token, log } = opts;
4674
+ const interactive = opts.interactive ?? Boolean(process.stdin.isTTY);
4675
+ const apiUrl = getApiUrl(opts.apiUrl);
4676
+ const web = getAuthUrl();
4677
+ const status = await apiFetch(`${apiUrl}/api/legal/status`, {
4678
+ headers: { Authorization: `Bearer ${token}` }
4679
+ }).catch(() => null);
4680
+ if (status?.ok) {
4681
+ const body = await status.json().catch(() => null);
4682
+ if (body?.accepted) {
4683
+ log.success("Already accepted \u2014 nothing to do.");
4684
+ return true;
4685
+ }
4686
+ log.plain("Before publishing, please read and agree to:");
4687
+ for (const doc of body?.documents ?? []) log.plain(` ${doc.title} ${c.cyan(doc.url)}`);
4688
+ log.plain("");
4689
+ }
4690
+ if (!interactive) {
4691
+ log.error("Accepting the Terms needs a person, so this cannot run unattended.");
4692
+ log.dim(" Agreeing is a contract, and an agent cannot do it on your behalf.");
4693
+ log.dim(` Open ${c.cyan(`${web}/terms`)} and agree there, then re-run your command.`);
4694
+ return false;
4695
+ }
4696
+ const ask = opts.ask ?? askOnStdin;
4697
+ const answer = (await ask("Type 'agree' to accept: ")).trim().toLowerCase();
4698
+ if (answer !== "agree") {
4699
+ log.error("Not accepted \u2014 nothing was recorded.");
4700
+ return false;
4701
+ }
4702
+ const res = await apiFetch(`${apiUrl}/api/legal/accept`, {
4703
+ method: "POST",
4704
+ headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
4705
+ body: JSON.stringify({ surface: "cli" })
4706
+ }).catch(() => null);
4707
+ if (!res?.ok) {
4708
+ log.error(`Couldn't record your acceptance (HTTP ${res?.status ?? "no response"}).`);
4709
+ return false;
4710
+ }
4711
+ log.success("Accepted. Re-run your command.");
4712
+ return true;
4713
+ }
4714
+
4643
4715
  // src/lib/deploy.ts
4644
4716
  function printMobilePreflight(files, log) {
4645
4717
  try {
@@ -5220,6 +5292,10 @@ async function fetchPushUrl(ctx, log, expectStagingCommit) {
5220
5292
  log.error(`Rate limited authorizing the source push (HTTP 429).${retryAfterHint(res)}`);
5221
5293
  return null;
5222
5294
  }
5295
+ if (await isTermsRefusal(res)) {
5296
+ reportTermsRefusal(log);
5297
+ return null;
5298
+ }
5223
5299
  if (!res.ok) {
5224
5300
  log.error(`Couldn't authorize the source push (HTTP ${res.status}).`);
5225
5301
  return null;
@@ -6391,6 +6467,26 @@ async function runPromote(opts) {
6391
6467
  await verifyGamePage({ apiUrl, slug: meta.slug, published: meta.status === "published", log });
6392
6468
  }
6393
6469
 
6470
+ // src/commands/accept.ts
6471
+ async function runAcceptCommand(opts) {
6472
+ const log = createLogger({ quiet: opts.quiet });
6473
+ log.plain(c.bold("genex accept"));
6474
+ log.plain("");
6475
+ const token = await readUserToken(opts.envPath);
6476
+ if (!token) {
6477
+ log.error(`Not signed in. Run ${c.cyan("npx genex auth")} first.`);
6478
+ process.exitCode = 1;
6479
+ return;
6480
+ }
6481
+ const meta = await readProject();
6482
+ const ok = await runAccept({
6483
+ token,
6484
+ log,
6485
+ ...meta?.apiUrl ? { apiUrl: meta.apiUrl } : {}
6486
+ });
6487
+ if (!ok) process.exitCode = 1;
6488
+ }
6489
+
6394
6490
  // src/lib/rollback.ts
6395
6491
  async function readPreviousVersion(apiUrl, projectId, token, log) {
6396
6492
  let res;
@@ -20406,6 +20502,10 @@ ${c.bold("Usage")}
20406
20502
  genex promote [options] Make the previewed build live for players. No
20407
20503
  rebuild \u2014 the exact build you previewed.
20408
20504
  genex publish [options] Build + push + make live, then list it in the gallery.
20505
+ genex accept Read the current Terms, Privacy and Content
20506
+ policies and agree, so publishing is allowed.
20507
+ Needs a real terminal: agreeing is a contract,
20508
+ and an agent cannot do it for you.
20409
20509
  genex rollback [--yes] Put players back on the previous version. One
20410
20510
  version back, instantly \u2014 your code is not
20411
20511
  changed, only what the play URL serves.
@@ -21500,6 +21600,9 @@ async function main() {
21500
21600
  case "promote":
21501
21601
  await runPromote(parsed.options);
21502
21602
  break;
21603
+ case "accept":
21604
+ await runAcceptCommand(parsed.options);
21605
+ break;
21503
21606
  case "rollback":
21504
21607
  await runRollback(parsed.options);
21505
21608
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genex-ai/cli-demo",
3
- "version": "1.9.0-dev.512",
3
+ "version": "1.9.1-dev.514",
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": {