clixad 0.0.1-beta.28 → 0.0.1-beta.29

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/clixad.mjs +48 -11
  2. package/package.json +1 -1
package/dist/clixad.mjs CHANGED
@@ -321,6 +321,9 @@ function premiumHeadline(unlockUsd) {
321
321
  function usd(v) {
322
322
  return Number.isInteger(v) ? `$${v}` : `$${v.toFixed(2)}`;
323
323
  }
324
+ function packsFromClause(cheapestUsd) {
325
+ return typeof cheapestUsd === "number" && cheapestUsd > 0 ? `, from ${usd(cheapestUsd)}` : "";
326
+ }
324
327
  function usableStreak(streak) {
325
328
  if (typeof streak !== "object" || streak === null) return void 0;
326
329
  const s = streak;
@@ -481,7 +484,14 @@ function shortfallHeadline(err, model) {
481
484
  return `Not enough credits for this turn${model ? ` on ${model}` : ""}: it needs about ${n(err.estimatedCost)}, and the balance is ${n(err.balance)}.`;
482
485
  }
483
486
  function paywallError(body) {
484
- return new PaywallError(body.balance, body.estimated_cost, body.grant_per_ad, freeAlternatives(body.free_models));
487
+ const pack = body.cheapest_pack_usd;
488
+ return new PaywallError(
489
+ body.balance,
490
+ body.estimated_cost,
491
+ body.grant_per_ad,
492
+ freeAlternatives(body.free_models),
493
+ typeof pack === "number" && Number.isFinite(pack) && pack > 0 ? pack : null
494
+ );
485
495
  }
486
496
  function freeAlternatives(list) {
487
497
  return Array.isArray(list) ? list.filter(
@@ -654,18 +664,20 @@ var init_client = __esm({
654
664
  waitlistUrl;
655
665
  };
656
666
  PaywallError = class extends Error {
657
- constructor(balance, estimatedCost, grantPerAd, freeModels = []) {
667
+ constructor(balance, estimatedCost, grantPerAd, freeModels = [], cheapestPackUsd = null) {
658
668
  super("Out of credits");
659
669
  this.balance = balance;
660
670
  this.estimatedCost = estimatedCost;
661
671
  this.grantPerAd = grantPerAd;
662
672
  this.freeModels = freeModels;
673
+ this.cheapestPackUsd = cheapestPackUsd;
663
674
  this.name = "PaywallError";
664
675
  }
665
676
  balance;
666
677
  estimatedCost;
667
678
  grantPerAd;
668
679
  freeModels;
680
+ cheapestPackUsd;
669
681
  };
670
682
  PremiumLockedError = class extends Error {
671
683
  constructor(message, model, neededCredits, premiumCredits, unlockUsd, grantPerAd, freeModels, streak) {
@@ -1795,7 +1807,9 @@ function freeTierNotice(o) {
1795
1807
  if (!free || !(free.daily_credits > 0)) return void 0;
1796
1808
  const pick = free.credits_left > 0 ? freeModelToName(free, o.model) : void 0;
1797
1809
  if (!pick) {
1798
- return o.balance <= 0 ? "Your balance is empty and today's free turns are used up. They come back at midnight UTC, and /earn tops up before then." : void 0;
1810
+ if (o.balance > 0) return void 0;
1811
+ const pack = o.cheapestPackUsd;
1812
+ return "Your balance is empty and today's free turns are used up. They come back at midnight UTC, and /earn tops up before then" + (typeof pack === "number" && pack > 0 ? `, or a pack from ${usd(pack)} with /buy.` : ".");
1799
1813
  }
1800
1814
  if (pick.id === o.model) {
1801
1815
  return `${pick.id} is free today, ${turns(pick.turns)} left. /model shows the other free models.`;
@@ -1822,6 +1836,7 @@ var turns;
1822
1836
  var init_free_tier = __esm({
1823
1837
  "src/free-tier.ts"() {
1824
1838
  "use strict";
1839
+ init_client();
1825
1840
  turns = (n) => `about ${n.toLocaleString("en-US")} turn${n === 1 ? "" : "s"}`;
1826
1841
  }
1827
1842
  });
@@ -6410,7 +6425,12 @@ function App({
6410
6425
  }
6411
6426
  const streakLine = streak && streak.claimed ? streakLabel(streak) : null;
6412
6427
  if (streakLine) push({ kind: "notice", tone: "good", text: ` ${streakLine}` });
6413
- const freeLine = freeTierNotice({ model: config.model, balance: wallet?.balance ?? 0, free: wallet?.free_tier });
6428
+ const freeLine = freeTierNotice({
6429
+ model: config.model,
6430
+ balance: wallet?.balance ?? 0,
6431
+ free: wallet?.free_tier,
6432
+ cheapestPackUsd: client.premiumUnlockUsd
6433
+ });
6414
6434
  if (freeLine) {
6415
6435
  push({ kind: "notice", tone: (wallet?.balance ?? 0) <= 0 ? "warn" : "good", text: ` ${freeLine}` });
6416
6436
  }
@@ -6811,7 +6831,12 @@ ${NO_SEARCH_INSTRUCTION}`),
6811
6831
  const on = model2;
6812
6832
  void client.wallet().then((w) => {
6813
6833
  setFreeTier(w.free_tier);
6814
- const line2 = freeTierNotice({ model: on, balance: w.balance, free: w.free_tier });
6834
+ const line2 = freeTierNotice({
6835
+ model: on,
6836
+ balance: w.balance,
6837
+ free: w.free_tier,
6838
+ cheapestPackUsd: client.premiumUnlockUsd
6839
+ });
6815
6840
  if (line2) push({ kind: "notice", tone: "warn", text: ` ${line2}` });
6816
6841
  }).catch(() => void 0);
6817
6842
  }
@@ -6865,7 +6890,7 @@ ${NO_SEARCH_INSTRUCTION}`),
6865
6890
  Press enter \u2014 ${free.id} is still free today (~${free.turnsLeft} turn${free.turnsLeft === 1 ? "" : "s"} left), or take an offer instead.
6866
6891
  Your request is kept either way, so you will not have to type it again.
6867
6892
  Offers you are screened out of pay nothing; that is normal, just start another.
6868
- /buy is there too, if you would rather pay than do an offer.` : ` ${shortfallHeadline(err, model2)}
6893
+ /buy is there too${packsFromClause(err.cheapestPackUsd)}, if you would rather pay than do an offer.` : ` ${shortfallHeadline(err, model2)}
6869
6894
  Press enter to open the ad wall \u2014 offers pay ${grantLabel(err.grantPerAd)}.
6870
6895
  I'll continue automatically. Offers you are screened out of pay nothing;
6871
6896
  that is normal, just start another.
@@ -6877,8 +6902,11 @@ ${NO_SEARCH_INSTRUCTION}`),
6877
6902
  ` : "") + // One clause, last, and it stays last. The wall is how this product
6878
6903
  // is meant to be paid for and the offer is free; naming /buy here
6879
6904
  // is discoverability rather than a pitch, and it is the moment
6880
- // somebody actually wants to know the command exists.
6881
- ` /buy is there too, if you would rather pay than do an offer.`
6905
+ // somebody actually wants to know the command exists. The
6906
+ // cheapest pack's price rides along, the gateway's figure: the
6907
+ // median refusal is a couple of thousand credits short, and the
6908
+ // smallest pack is what fits that.
6909
+ ` /buy is there too${packsFromClause(err.cheapestPackUsd)}, if you would rather pay than do an offer.`
6882
6910
  });
6883
6911
  } else if (err instanceof AuthError) {
6884
6912
  push({ kind: "notice", tone: "error", text: NOT_SIGNED_IN });
@@ -6976,7 +7004,12 @@ ${NO_SEARCH_INSTRUCTION}`),
6976
7004
  if (w) {
6977
7005
  setBalance(w.balance);
6978
7006
  setFreeTier(w.free_tier);
6979
- const freeLine = freeTierNotice({ model: modelRef.current, balance: w.balance, free: w.free_tier });
7007
+ const freeLine = freeTierNotice({
7008
+ model: modelRef.current,
7009
+ balance: w.balance,
7010
+ free: w.free_tier,
7011
+ cheapestPackUsd: client.premiumUnlockUsd
7012
+ });
6980
7013
  if (freeLine) push({ kind: "notice", tone: w.balance <= 0 ? "warn" : "good", text: ` ${freeLine}` });
6981
7014
  }
6982
7015
  return;
@@ -8903,7 +8936,9 @@ ${shortfallHeadline(err, config.model)}`));
8903
8936
  `Run \`clixad earn\` to open the offerwall \u2014 offers pay ${grantLabel(err.grantPerAd)}.`
8904
8937
  )
8905
8938
  );
8906
- console.log(c.yellow("Credits can also be bought: start `clixad` and type /buy."));
8939
+ console.log(
8940
+ c.yellow(`Credits can also be bought${packsFromClause(err.cheapestPackUsd)}: start \`clixad\` and type /buy.`)
8941
+ );
8907
8942
  console.log(c.dim(" Offers you are screened out of pay nothing \u2014 that is normal, just start another."));
8908
8943
  } else if (err instanceof AuthError) {
8909
8944
  console.log(c.red(err.message));
@@ -9037,7 +9072,9 @@ async function runTurn(client, config, messages) {
9037
9072
  console.log(
9038
9073
  c.yellow(`Run \`clixad earn\` to open the offerwall \u2014 offers pay ${grantLabel(err.grantPerAd)}.`)
9039
9074
  );
9040
- console.log(c.yellow("Credits can also be bought: start `clixad` and type /buy."));
9075
+ console.log(
9076
+ c.yellow(`Credits can also be bought${packsFromClause(err.cheapestPackUsd)}: start \`clixad\` and type /buy.`)
9077
+ );
9041
9078
  console.log(c.dim(" Offers you are screened out of pay nothing \u2014 that is normal, just start another."));
9042
9079
  } else if (err instanceof AuthError) {
9043
9080
  console.log(c.red(err.message));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clixad",
3
- "version": "0.0.1-beta.28",
3
+ "version": "0.0.1-beta.29",
4
4
  "description": "Free AI coding agent in your terminal, funded by rewarded ads.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",