clixad 0.0.1-beta.41 → 0.0.1-beta.42

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.
@@ -214,6 +214,11 @@ function usd(v) {
214
214
  function packsFromClause(cheapestUsd) {
215
215
  return typeof cheapestUsd === "number" && cheapestUsd > 0 ? `, from ${usd(cheapestUsd)}` : "";
216
216
  }
217
+ function rewardedAdLine(offer) {
218
+ if (!offer) return "";
219
+ return ` Or watch a short ad on the earn page (/earn): ${offer.credits.toLocaleString("en-US")} credits for watching one to the end, ${offer.leftToday} left today.
220
+ `;
221
+ }
217
222
  function parseSpendable(raw) {
218
223
  if (!raw || typeof raw !== "object") return void 0;
219
224
  const r = raw;
@@ -291,6 +296,7 @@ var LEDGER_REASONS = {
291
296
  own_survey_reward: "Clixad survey",
292
297
  ad_screenout_bonus: "screenout bonus (didn't qualify)",
293
298
  ad_sponsor_impression: "sponsored line shown",
299
+ ad_rewarded_view: "ad watched",
294
300
  ad_reversal: "offer reward reversed by the provider",
295
301
  purchase: "credits purchased",
296
302
  usage: "model usage",
@@ -368,7 +374,7 @@ var SignupClosedError = class extends Error {
368
374
  waitlistUrl;
369
375
  };
370
376
  var PaywallError = class extends Error {
371
- constructor(balance, estimatedCost, grantPerAd, freeModels = [], cheapestPackUsd = null, ownSurvey = null) {
377
+ constructor(balance, estimatedCost, grantPerAd, freeModels = [], cheapestPackUsd = null, ownSurvey = null, rewardedAd = null) {
372
378
  super("Out of credits");
373
379
  this.balance = balance;
374
380
  this.estimatedCost = estimatedCost;
@@ -376,6 +382,7 @@ var PaywallError = class extends Error {
376
382
  this.freeModels = freeModels;
377
383
  this.cheapestPackUsd = cheapestPackUsd;
378
384
  this.ownSurvey = ownSurvey;
385
+ this.rewardedAd = rewardedAd;
379
386
  this.name = "PaywallError";
380
387
  }
381
388
  balance;
@@ -384,9 +391,10 @@ var PaywallError = class extends Error {
384
391
  freeModels;
385
392
  cheapestPackUsd;
386
393
  ownSurvey;
394
+ rewardedAd;
387
395
  };
388
396
  var PremiumLockedError = class extends Error {
389
- constructor(message, model, neededCredits, premiumCredits, unlockUsd, grantPerAd, freeModels, spendable) {
397
+ constructor(message, model, neededCredits, premiumCredits, unlockUsd, grantPerAd, freeModels, spendable, rewardedAd = null) {
390
398
  super(message);
391
399
  this.model = model;
392
400
  this.neededCredits = neededCredits;
@@ -395,6 +403,7 @@ var PremiumLockedError = class extends Error {
395
403
  this.grantPerAd = grantPerAd;
396
404
  this.freeModels = freeModels;
397
405
  this.spendable = spendable;
406
+ this.rewardedAd = rewardedAd;
398
407
  this.name = "PremiumLockedError";
399
408
  }
400
409
  model;
@@ -404,6 +413,7 @@ var PremiumLockedError = class extends Error {
404
413
  grantPerAd;
405
414
  freeModels;
406
415
  spendable;
416
+ rewardedAd;
407
417
  };
408
418
  var LimitRefusalError = class extends Error {
409
419
  constructor(message, type, spendable) {
@@ -447,7 +457,8 @@ function premiumLockedError(message, model, body, spendable) {
447
457
  typeof body?.unlock_usd === "number" && body.unlock_usd > 0 ? body.unlock_usd : null,
448
458
  num(body?.grant_per_ad),
449
459
  freeAlternatives(body?.free_models),
450
- spendable
460
+ spendable,
461
+ ownSurveyOffer(body?.rewarded_ad)
451
462
  );
452
463
  }
453
464
  function shortfallHeadline(err, model) {
@@ -463,7 +474,9 @@ function paywallError(body) {
463
474
  body.grant_per_ad,
464
475
  freeAlternatives(body.free_models),
465
476
  typeof pack === "number" && Number.isFinite(pack) && pack > 0 ? pack : null,
466
- ownSurveyOffer(body.own_survey)
477
+ ownSurveyOffer(body.own_survey),
478
+ // The same shape, `{ credits, left_today }`, and the same defensive read.
479
+ ownSurveyOffer(body.rewarded_ad)
467
480
  );
468
481
  }
469
482
  function ownSurveyOffer(raw) {
@@ -6410,6 +6423,7 @@ export {
6410
6423
  NO_PREMIUM_CREDITS,
6411
6424
  usd,
6412
6425
  packsFromClause,
6426
+ rewardedAdLine,
6413
6427
  parseSpendable,
6414
6428
  adsPerTaskLabel,
6415
6429
  grantLabel,
package/dist/clixad.mjs CHANGED
@@ -53,7 +53,7 @@ import {
53
53
  takeConfigNotices,
54
54
  toolSchemaFor,
55
55
  usd
56
- } from "./chunk-AOKPITZW.mjs";
56
+ } from "./chunk-ABDMJDYJ.mjs";
57
57
 
58
58
  // src/tui/load.ts
59
59
  import * as nodeModule from "node:module";
@@ -132,7 +132,7 @@ async function withProductionReact(load) {
132
132
  }
133
133
  function loadTui() {
134
134
  boundInkCaches();
135
- return withProductionReact(() => import("./tui-FSKTJFDL.mjs"));
135
+ return withProductionReact(() => import("./tui-377KNURT.mjs"));
136
136
  }
137
137
 
138
138
  // src/title.ts
@@ -69,6 +69,7 @@ import {
69
69
  redeemMessage,
70
70
  referLines,
71
71
  resolveEffort,
72
+ rewardedAdLine,
72
73
  rowTaskHint,
73
74
  runAgent,
74
75
  safeResolve,
@@ -94,7 +95,7 @@ import {
94
95
  visibleLength,
95
96
  webSearchCostLine,
96
97
  welcomeBanner
97
- } from "./chunk-AOKPITZW.mjs";
98
+ } from "./chunk-ABDMJDYJ.mjs";
98
99
 
99
100
  // src/tui/index.tsx
100
101
  import "react";
@@ -1003,7 +1004,13 @@ function App({
1003
1004
  }, []);
1004
1005
  const lastTextAtRef = useRef(0);
1005
1006
  const pendingSendRef = useRef(void 0);
1006
- useEffect(() => () => clearTimeout(pendingSendRef.current), []);
1007
+ useEffect(
1008
+ () => () => {
1009
+ clearTimeout(pendingSendRef.current);
1010
+ pendingSendRef.current = void 0;
1011
+ },
1012
+ []
1013
+ );
1007
1014
  const [busy, setBusy] = useState(false);
1008
1015
  const [live, setLive] = useState(null);
1009
1016
  const [balance, setBalance] = useState(wallet?.balance);
@@ -1828,7 +1835,7 @@ ${preferencesText}` : ""),
1828
1835
  tone: "warn",
1829
1836
  text: ` ${premiumHeadline(err.unlockUsd)}
1830
1837
  ${err.model} is a premium model. It runs on credits from offer-wall surveys or purchases.
1831
- ` + short + " Your bonus credits (the signup bonus, our own surveys) still work on budget models.\n Press enter to unlock it or to switch to a budget model. Your request is kept."
1838
+ ` + short + " Your bonus credits (the signup bonus, our own surveys) still work on budget models.\n" + rewardedAdLine(err.rewardedAd) + " Press enter to unlock it or to switch to a budget model. Your request is kept."
1832
1839
  });
1833
1840
  } else if (err instanceof PaywallError) {
1834
1841
  pendingTaskRef.current = { task, images };
@@ -1838,15 +1845,16 @@ ${preferencesText}` : ""),
1838
1845
  const free = err.freeModels[0];
1839
1846
  const own = err.ownSurvey ? ` Our own surveys pay ${err.ownSurvey.credits.toLocaleString("en-US")} credits each and nobody is screened out (${err.ownSurvey.leftToday} left today). They are first on the wall.
1840
1847
  ` : "";
1848
+ const ad = rewardedAdLine(err.rewardedAd);
1841
1849
  push({
1842
1850
  kind: "notice",
1843
1851
  tone: "warn",
1844
1852
  text: free ? ` ${shortfallHeadline(err, model2)}
1845
- ` + own + ` Press enter \u2014 ${free.id} is still free today (~${free.turnsLeft} turn${free.turnsLeft === 1 ? "" : "s"} left), or take an offer instead.
1853
+ ` + own + ad + ` Press enter \u2014 ${free.id} is still free today (~${free.turnsLeft} turn${free.turnsLeft === 1 ? "" : "s"} left), or take an offer instead.
1846
1854
  Your request is kept either way, so you will not have to type it again.
1847
1855
  Offers you are screened out of pay nothing; that is normal, just start another.
1848
1856
  /buy is there too${packsFromClause(err.cheapestPackUsd)}, if you would rather pay than do an offer.` : ` ${shortfallHeadline(err, model2)}
1849
- ` + own + ` Press enter to open the ad wall \u2014 offers pay ${grantLabel(err.grantPerAd)}.
1857
+ ` + own + ad + ` Press enter to open the ad wall \u2014 offers pay ${grantLabel(err.grantPerAd)}.
1850
1858
  I'll continue automatically. Offers you are screened out of pay nothing;
1851
1859
  that is normal, just start another.
1852
1860
  ` + // A wallet that is short rather than empty has a third way on,
@@ -2984,10 +2992,14 @@ ${dropped.map((l) => ` \xB7 ${l}`).join("\n")}`
2984
2992
  if (!busy && pendingTaskRef.current && isEmpty(editorRef.current)) {
2985
2993
  return void (pendingPremiumRef.current ? runPremiumChoice() : runPaywallChoice());
2986
2994
  }
2987
- pendingSendRef.current = setTimeout(() => {
2988
- pendingSendRef.current = void 0;
2989
- void submit(toText(editorRef.current));
2995
+ const timer = setTimeout(() => {
2996
+ setImmediate(() => {
2997
+ if (pendingSendRef.current !== timer) return;
2998
+ pendingSendRef.current = void 0;
2999
+ void submit(toText(editorRef.current));
3000
+ });
2990
3001
  }, PASTE_ENTER_MS);
3002
+ pendingSendRef.current = timer;
2991
3003
  return;
2992
3004
  }
2993
3005
  if (key.ctrl && ch === "j") return setEditor(newline);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clixad",
3
- "version": "0.0.1-beta.41",
3
+ "version": "0.0.1-beta.42",
4
4
  "description": "Free AI coding agent in your terminal, funded by rewarded ads.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",