@letterstory/cli 0.177.38 → 0.177.39

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/lib/cli.mjs CHANGED
@@ -88,7 +88,7 @@ import {
88
88
  import { fetchParkedSections, withoutParked } from "./parked.mjs";
89
89
 
90
90
  // Matches cli/package.json; publish-cli.yml rewrites both to the published version.
91
- export const VERSION = "0.177.38";
91
+ export const VERSION = "0.177.39";
92
92
 
93
93
  /** The exit code for a gate refusal (CARD_REQUIRED, PAYMENT_FAILED, OUT_OF_TOKENS): 1 is a plain error. */
94
94
  export const EXIT_PAYMENT_REQUIRED = 3;
@@ -6355,7 +6355,9 @@ const FREE_USAGE = `Usage: admin billing free exposure [--json] wh
6355
6355
  admin billing free grant <org-id|name> <tokens> --why "…" [--key k] give an org free tokens (a Lago org: a one-off wallet); the same key is one grant
6356
6356
  admin billing free grants [--org <org-id>] [--limit n] staff grants, newest first, live and revoked
6357
6357
  admin billing free revoke <org-id> <ref> --why "…" take a staff grant back (ref from the list: grant:<id> or wallet:staff_…)
6358
- admin billing free preflight [--json] who the paywall stops the moment it is enforced, and whether it is ready`;
6358
+ admin billing free preflight [--json] who the paywall stops the moment it is enforced, and whether it is ready
6359
+ admin billing free pool <org-id|name>... --why "…" link orgs on free tokens so they spend from one balance
6360
+ admin billing free unpool <org-id|name> --why "…" take an org out of its shared balance`;
6359
6361
 
6360
6362
  const EXPOSURE_WORDS = {
6361
6363
  needs_legacy: "pay today: need a legacy mark (admin billing legacy mark --all)",
@@ -6457,6 +6459,28 @@ async function cmdAdminBillingFree(ctx) {
6457
6459
  });
6458
6460
  return 0;
6459
6461
  }
6462
+ if (positionals[1] === "pool" || positionals[1] === "unpool") {
6463
+ const pool = positionals[1] === "pool";
6464
+ const args = positionals.slice(2);
6465
+ if (pool ? args.length < 2 : args.length !== 1) throw new CliError(FREE_USAGE);
6466
+ const why = flagStr(flags.why);
6467
+ if (!why) throw new CliError(`Say why (--why "…"): it is kept with the change.\n${FREE_USAGE}`);
6468
+ const orgIds = [];
6469
+ for (const a of args) orgIds.push((await resolveBillingOrg(ctx, a)).orgId);
6470
+ const r = pool
6471
+ ? await staffPost(ctx, "/api/superadmin/billing/token-pools", { orgIds, why })
6472
+ : await staffRequest(ctx, "DELETE", "/api/superadmin/billing/token-pools", { orgId: orgIds[0], why });
6473
+ printResult(io, flags, r, (x) =>
6474
+ pool
6475
+ ? `Sharing one token balance (${x.poolId}):\n${x.orgs.map((o) => ` ${o.name} ${o.orgId}`).join("\n")}`
6476
+ : !x.changed
6477
+ ? `${orgIds[0]} is in no pool; nothing changed.`
6478
+ : x.left.length
6479
+ ? `Taken out. Still sharing: ${x.left.map((o) => o.name).join(", ")}.`
6480
+ : "Taken out. The pool had one org left, so it ended."
6481
+ );
6482
+ return 0;
6483
+ }
6460
6484
  if (positionals[1] === "grant") {
6461
6485
  const [orgArg, tokensArg] = [positionals[2], positionals[3]];
6462
6486
  const tokens = Number(String(tokensArg ?? "").replace(/[,_]/g, ""));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letterstory/cli",
3
- "version": "0.177.38",
3
+ "version": "0.177.39",
4
4
  "description": "Spin up and manage Letter phantom blogs from your terminal.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",