clixad 0.0.1-beta.27 → 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.
- package/dist/clixad.mjs +111 -22
- package/package.json +1 -1
package/dist/clixad.mjs
CHANGED
|
@@ -310,8 +310,10 @@ function accessColumn(m, premium) {
|
|
|
310
310
|
function premiumLocked(premium) {
|
|
311
311
|
return premium !== void 0 && !premium.unlocked && premium.credits <= 0;
|
|
312
312
|
}
|
|
313
|
-
function premiumUnlockHint(unlockUsd) {
|
|
314
|
-
|
|
313
|
+
function premiumUnlockHint(unlockUsd, streak) {
|
|
314
|
+
const base = typeof unlockUsd === "number" && unlockUsd > 0 ? `premium: a survey or ${usd(unlockUsd)} unlocks it` : "premium: a survey unlocks it";
|
|
315
|
+
const s = usableStreak(streak);
|
|
316
|
+
return s && s.day < s.min_day ? `${base}, or a ${s.min_day}-day streak` : base;
|
|
315
317
|
}
|
|
316
318
|
function premiumHeadline(unlockUsd) {
|
|
317
319
|
return typeof unlockUsd === "number" && unlockUsd > 0 ? `Premium: complete a survey or unlock from ${usd(unlockUsd)}.` : "Premium: complete a survey to unlock it.";
|
|
@@ -319,6 +321,36 @@ function premiumHeadline(unlockUsd) {
|
|
|
319
321
|
function usd(v) {
|
|
320
322
|
return Number.isInteger(v) ? `$${v}` : `$${v.toFixed(2)}`;
|
|
321
323
|
}
|
|
324
|
+
function packsFromClause(cheapestUsd) {
|
|
325
|
+
return typeof cheapestUsd === "number" && cheapestUsd > 0 ? `, from ${usd(cheapestUsd)}` : "";
|
|
326
|
+
}
|
|
327
|
+
function usableStreak(streak) {
|
|
328
|
+
if (typeof streak !== "object" || streak === null) return void 0;
|
|
329
|
+
const s = streak;
|
|
330
|
+
const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
331
|
+
const day = num(s.day);
|
|
332
|
+
const minDay = num(s.min_day);
|
|
333
|
+
const daily = num(s.daily_credits);
|
|
334
|
+
const left = num(s.credits_left);
|
|
335
|
+
if (day === void 0 || minDay === void 0 || daily === void 0 || left === void 0 || daily <= 0) {
|
|
336
|
+
return void 0;
|
|
337
|
+
}
|
|
338
|
+
return { day, min_day: minDay, daily_credits: daily, credits_left: left };
|
|
339
|
+
}
|
|
340
|
+
function premiumStreakLine(streak) {
|
|
341
|
+
const s = usableStreak(streak);
|
|
342
|
+
if (!s) return null;
|
|
343
|
+
const n = (x) => x.toLocaleString("en-US");
|
|
344
|
+
if (s.day < s.min_day) {
|
|
345
|
+
const wait = s.min_day - s.day;
|
|
346
|
+
const when = wait === 1 ? "tomorrow" : wait === 2 ? "the day after tomorrow" : `in ${wait} days`;
|
|
347
|
+
return `From day ${s.min_day} of your login streak, ${n(s.daily_credits)} bonus credits a day work on premium models too. You are on day ${s.day}, so that starts ${when} if you open Clixad every day.`;
|
|
348
|
+
}
|
|
349
|
+
if (s.credits_left <= 0) {
|
|
350
|
+
return `Today's ${n(s.daily_credits)} bonus credits for premium models are used up. They come back at 00:00 UTC while your login streak holds.`;
|
|
351
|
+
}
|
|
352
|
+
return `Your login streak lets ${n(s.credits_left)} more bonus credits go to premium models today.`;
|
|
353
|
+
}
|
|
322
354
|
function adsPerTaskLabel(estAdsPerTask) {
|
|
323
355
|
const effort = estAdsPerTask >= 1 ? `~${estAdsPerTask} ads/task` : "<1 ad/task";
|
|
324
356
|
return `${effort} on completion (median)`;
|
|
@@ -336,7 +368,18 @@ function streakLabel(streak) {
|
|
|
336
368
|
if (!streak.claimed) return `daily streak: ${where} \xB7 today's already counted`;
|
|
337
369
|
const tomorrow = streak.schedule[Math.min(streak.day, streak.length - 1)];
|
|
338
370
|
const next = tomorrow === void 0 ? "" : ` \xB7 tomorrow ${n(tomorrow)}`;
|
|
339
|
-
return `daily streak: ${where} \xB7 +${n(streak.credits)} credits${next}`;
|
|
371
|
+
return `daily streak: ${where} \xB7 +${n(streak.credits)} credits${next}${streakPremiumClause(streak)}`;
|
|
372
|
+
}
|
|
373
|
+
function streakPremiumClause(streak) {
|
|
374
|
+
const p = streak.premium;
|
|
375
|
+
if (!p) return "";
|
|
376
|
+
return streak.day < p.minDay ? ` \xB7 bonus credits on premium from day ${p.minDay}` : ` \xB7 ${p.dailyCredits.toLocaleString("en-US")} bonus credits a day on premium`;
|
|
377
|
+
}
|
|
378
|
+
function streakPremium(raw) {
|
|
379
|
+
if (typeof raw !== "object" || raw === null) return {};
|
|
380
|
+
const p = raw;
|
|
381
|
+
if (typeof p.min_day !== "number" || typeof p.daily_credits !== "number" || p.daily_credits <= 0) return {};
|
|
382
|
+
return { premium: { minDay: p.min_day, dailyCredits: p.daily_credits } };
|
|
340
383
|
}
|
|
341
384
|
function referLines(info) {
|
|
342
385
|
const n = (x) => x.toLocaleString("en-US");
|
|
@@ -431,7 +474,8 @@ function premiumLockedError(message, model, body) {
|
|
|
431
474
|
num(body?.premium_credits),
|
|
432
475
|
typeof body?.unlock_usd === "number" && body.unlock_usd > 0 ? body.unlock_usd : null,
|
|
433
476
|
num(body?.grant_per_ad),
|
|
434
|
-
freeAlternatives(body?.free_models)
|
|
477
|
+
freeAlternatives(body?.free_models),
|
|
478
|
+
usableStreak(body?.streak)
|
|
435
479
|
);
|
|
436
480
|
}
|
|
437
481
|
function shortfallHeadline(err, model) {
|
|
@@ -440,7 +484,14 @@ function shortfallHeadline(err, model) {
|
|
|
440
484
|
return `Not enough credits for this turn${model ? ` on ${model}` : ""}: it needs about ${n(err.estimatedCost)}, and the balance is ${n(err.balance)}.`;
|
|
441
485
|
}
|
|
442
486
|
function paywallError(body) {
|
|
443
|
-
|
|
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
|
+
);
|
|
444
495
|
}
|
|
445
496
|
function freeAlternatives(list) {
|
|
446
497
|
return Array.isArray(list) ? list.filter(
|
|
@@ -613,21 +664,23 @@ var init_client = __esm({
|
|
|
613
664
|
waitlistUrl;
|
|
614
665
|
};
|
|
615
666
|
PaywallError = class extends Error {
|
|
616
|
-
constructor(balance, estimatedCost, grantPerAd, freeModels = []) {
|
|
667
|
+
constructor(balance, estimatedCost, grantPerAd, freeModels = [], cheapestPackUsd = null) {
|
|
617
668
|
super("Out of credits");
|
|
618
669
|
this.balance = balance;
|
|
619
670
|
this.estimatedCost = estimatedCost;
|
|
620
671
|
this.grantPerAd = grantPerAd;
|
|
621
672
|
this.freeModels = freeModels;
|
|
673
|
+
this.cheapestPackUsd = cheapestPackUsd;
|
|
622
674
|
this.name = "PaywallError";
|
|
623
675
|
}
|
|
624
676
|
balance;
|
|
625
677
|
estimatedCost;
|
|
626
678
|
grantPerAd;
|
|
627
679
|
freeModels;
|
|
680
|
+
cheapestPackUsd;
|
|
628
681
|
};
|
|
629
682
|
PremiumLockedError = class extends Error {
|
|
630
|
-
constructor(message, model, neededCredits, premiumCredits, unlockUsd, grantPerAd, freeModels) {
|
|
683
|
+
constructor(message, model, neededCredits, premiumCredits, unlockUsd, grantPerAd, freeModels, streak) {
|
|
631
684
|
super(message);
|
|
632
685
|
this.model = model;
|
|
633
686
|
this.neededCredits = neededCredits;
|
|
@@ -635,6 +688,7 @@ var init_client = __esm({
|
|
|
635
688
|
this.unlockUsd = unlockUsd;
|
|
636
689
|
this.grantPerAd = grantPerAd;
|
|
637
690
|
this.freeModels = freeModels;
|
|
691
|
+
this.streak = streak;
|
|
638
692
|
this.name = "PremiumLockedError";
|
|
639
693
|
}
|
|
640
694
|
model;
|
|
@@ -643,6 +697,7 @@ var init_client = __esm({
|
|
|
643
697
|
unlockUsd;
|
|
644
698
|
grantPerAd;
|
|
645
699
|
freeModels;
|
|
700
|
+
streak;
|
|
646
701
|
};
|
|
647
702
|
GatewayUnreachableError = class extends Error {
|
|
648
703
|
constructor(host, code) {
|
|
@@ -801,7 +856,8 @@ var init_client = __esm({
|
|
|
801
856
|
claimed: body.claimed === true,
|
|
802
857
|
balance: typeof body.balance === "number" ? body.balance : 0,
|
|
803
858
|
schedule: Array.isArray(body.schedule) ? body.schedule : [],
|
|
804
|
-
length: typeof body.length === "number" ? body.length : 0
|
|
859
|
+
length: typeof body.length === "number" ? body.length : 0,
|
|
860
|
+
...streakPremium(body.premium)
|
|
805
861
|
};
|
|
806
862
|
} catch {
|
|
807
863
|
return null;
|
|
@@ -1751,7 +1807,9 @@ function freeTierNotice(o) {
|
|
|
1751
1807
|
if (!free || !(free.daily_credits > 0)) return void 0;
|
|
1752
1808
|
const pick = free.credits_left > 0 ? freeModelToName(free, o.model) : void 0;
|
|
1753
1809
|
if (!pick) {
|
|
1754
|
-
|
|
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.` : ".");
|
|
1755
1813
|
}
|
|
1756
1814
|
if (pick.id === o.model) {
|
|
1757
1815
|
return `${pick.id} is free today, ${turns(pick.turns)} left. /model shows the other free models.`;
|
|
@@ -1778,6 +1836,7 @@ var turns;
|
|
|
1778
1836
|
var init_free_tier = __esm({
|
|
1779
1837
|
"src/free-tier.ts"() {
|
|
1780
1838
|
"use strict";
|
|
1839
|
+
init_client();
|
|
1781
1840
|
turns = (n) => `about ${n.toLocaleString("en-US")} turn${n === 1 ? "" : "s"}`;
|
|
1782
1841
|
}
|
|
1783
1842
|
});
|
|
@@ -6366,7 +6425,12 @@ function App({
|
|
|
6366
6425
|
}
|
|
6367
6426
|
const streakLine = streak && streak.claimed ? streakLabel(streak) : null;
|
|
6368
6427
|
if (streakLine) push({ kind: "notice", tone: "good", text: ` ${streakLine}` });
|
|
6369
|
-
const freeLine = freeTierNotice({
|
|
6428
|
+
const freeLine = freeTierNotice({
|
|
6429
|
+
model: config.model,
|
|
6430
|
+
balance: wallet?.balance ?? 0,
|
|
6431
|
+
free: wallet?.free_tier,
|
|
6432
|
+
cheapestPackUsd: client.premiumUnlockUsd
|
|
6433
|
+
});
|
|
6370
6434
|
if (freeLine) {
|
|
6371
6435
|
push({ kind: "notice", tone: (wallet?.balance ?? 0) <= 0 ? "warn" : "good", text: ` ${freeLine}` });
|
|
6372
6436
|
}
|
|
@@ -6641,7 +6705,7 @@ function App({
|
|
|
6641
6705
|
if (event.creditsCharged > 0 && premiumRef.current) {
|
|
6642
6706
|
const p = premiumRef.current;
|
|
6643
6707
|
setPremium({
|
|
6644
|
-
|
|
6708
|
+
...p,
|
|
6645
6709
|
credits: Math.max(0, p.unlocked ? event.balance : Math.min(event.balance, p.credits - event.creditsCharged))
|
|
6646
6710
|
});
|
|
6647
6711
|
}
|
|
@@ -6767,7 +6831,12 @@ ${NO_SEARCH_INSTRUCTION}`),
|
|
|
6767
6831
|
const on = model2;
|
|
6768
6832
|
void client.wallet().then((w) => {
|
|
6769
6833
|
setFreeTier(w.free_tier);
|
|
6770
|
-
const line2 = freeTierNotice({
|
|
6834
|
+
const line2 = freeTierNotice({
|
|
6835
|
+
model: on,
|
|
6836
|
+
balance: w.balance,
|
|
6837
|
+
free: w.free_tier,
|
|
6838
|
+
cheapestPackUsd: client.premiumUnlockUsd
|
|
6839
|
+
});
|
|
6771
6840
|
if (line2) push({ kind: "notice", tone: "warn", text: ` ${line2}` });
|
|
6772
6841
|
}).catch(() => void 0);
|
|
6773
6842
|
}
|
|
@@ -6796,15 +6865,17 @@ ${NO_SEARCH_INSTRUCTION}`),
|
|
|
6796
6865
|
if (err instanceof PremiumLockedError) {
|
|
6797
6866
|
pendingTaskRef.current = { task, images };
|
|
6798
6867
|
pendingPremiumRef.current = err;
|
|
6799
|
-
setPremium({ unlocked: false, credits: err.premiumCredits });
|
|
6868
|
+
setPremium({ unlocked: false, credits: err.premiumCredits, ...err.streak ? { streak: err.streak } : {} });
|
|
6800
6869
|
const short2 = err.premiumCredits > 0 ? ` This turn needs about ${err.neededCredits.toLocaleString("en-US")} of those credits, and you have ${err.premiumCredits.toLocaleString("en-US")}.
|
|
6801
6870
|
` : "";
|
|
6871
|
+
const streakLine = premiumStreakLine(err.streak);
|
|
6802
6872
|
push({
|
|
6803
6873
|
kind: "notice",
|
|
6804
6874
|
tone: "warn",
|
|
6805
6875
|
text: ` ${premiumHeadline(err.unlockUsd)}
|
|
6806
6876
|
${err.model} is a premium model. It runs on credits you earned on the offer walls or bought.
|
|
6807
|
-
` + short2 +
|
|
6877
|
+
` + short2 + (streakLine ? ` ${streakLine}
|
|
6878
|
+
` : "") + " 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."
|
|
6808
6879
|
});
|
|
6809
6880
|
} else if (err instanceof PaywallError) {
|
|
6810
6881
|
pendingTaskRef.current = { task, images };
|
|
@@ -6819,7 +6890,7 @@ ${NO_SEARCH_INSTRUCTION}`),
|
|
|
6819
6890
|
Press enter \u2014 ${free.id} is still free today (~${free.turnsLeft} turn${free.turnsLeft === 1 ? "" : "s"} left), or take an offer instead.
|
|
6820
6891
|
Your request is kept either way, so you will not have to type it again.
|
|
6821
6892
|
Offers you are screened out of pay nothing; that is normal, just start another.
|
|
6822
|
-
/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)}
|
|
6823
6894
|
Press enter to open the ad wall \u2014 offers pay ${grantLabel(err.grantPerAd)}.
|
|
6824
6895
|
I'll continue automatically. Offers you are screened out of pay nothing;
|
|
6825
6896
|
that is normal, just start another.
|
|
@@ -6831,8 +6902,11 @@ ${NO_SEARCH_INSTRUCTION}`),
|
|
|
6831
6902
|
` : "") + // One clause, last, and it stays last. The wall is how this product
|
|
6832
6903
|
// is meant to be paid for and the offer is free; naming /buy here
|
|
6833
6904
|
// is discoverability rather than a pitch, and it is the moment
|
|
6834
|
-
// somebody actually wants to know the command exists.
|
|
6835
|
-
|
|
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.`
|
|
6836
6910
|
});
|
|
6837
6911
|
} else if (err instanceof AuthError) {
|
|
6838
6912
|
push({ kind: "notice", tone: "error", text: NOT_SIGNED_IN });
|
|
@@ -6930,7 +7004,12 @@ ${NO_SEARCH_INSTRUCTION}`),
|
|
|
6930
7004
|
if (w) {
|
|
6931
7005
|
setBalance(w.balance);
|
|
6932
7006
|
setFreeTier(w.free_tier);
|
|
6933
|
-
const freeLine = freeTierNotice({
|
|
7007
|
+
const freeLine = freeTierNotice({
|
|
7008
|
+
model: modelRef.current,
|
|
7009
|
+
balance: w.balance,
|
|
7010
|
+
free: w.free_tier,
|
|
7011
|
+
cheapestPackUsd: client.premiumUnlockUsd
|
|
7012
|
+
});
|
|
6934
7013
|
if (freeLine) push({ kind: "notice", tone: w.balance <= 0 ? "warn" : "good", text: ` ${freeLine}` });
|
|
6935
7014
|
}
|
|
6936
7015
|
return;
|
|
@@ -7267,7 +7346,7 @@ ${NO_SEARCH_INSTRUCTION}`),
|
|
|
7267
7346
|
const items = models.map((m) => ({
|
|
7268
7347
|
value: m.id,
|
|
7269
7348
|
label: m.id,
|
|
7270
|
-
hint: accessColumn(m, premium2) + (m.access === "premium" && premiumLocked(premium2) ? premiumUnlockHint(unlockUsd) : modelHint(m, free)),
|
|
7349
|
+
hint: accessColumn(m, premium2) + (m.access === "premium" && premiumLocked(premium2) ? premiumUnlockHint(unlockUsd, premium2?.streak) : modelHint(m, free)),
|
|
7271
7350
|
current: m.id === model
|
|
7272
7351
|
}));
|
|
7273
7352
|
const preselect = items.findIndex((i) => i.value === arg);
|
|
@@ -7283,12 +7362,14 @@ ${NO_SEARCH_INSTRUCTION}`),
|
|
|
7283
7362
|
push({ kind: "notice", text: ` model \u2192 ${choice.value}` });
|
|
7284
7363
|
const picked = models.find((m) => m.id === choice.value);
|
|
7285
7364
|
if (picked?.access === "premium" && premiumLocked(premium2)) {
|
|
7365
|
+
const streakLine = premiumStreakLine(premium2?.streak);
|
|
7286
7366
|
push({
|
|
7287
7367
|
kind: "notice",
|
|
7288
7368
|
tone: "warn",
|
|
7289
7369
|
text: ` ${premiumHeadline(unlockUsd)}
|
|
7290
7370
|
${choice.value} runs on credits you earned on the offer walls or bought.
|
|
7291
|
-
|
|
7371
|
+
` + (streakLine ? ` ${streakLine}
|
|
7372
|
+
` : "") + " /earn opens the offer walls" + (unlockUsd ? `, /buy unlocks premium from ${usd(unlockUsd)}.` : ".") + " Your bonus credits work on budget models."
|
|
7292
7373
|
});
|
|
7293
7374
|
}
|
|
7294
7375
|
}
|
|
@@ -8672,6 +8753,8 @@ function printPremiumRefusal(err) {
|
|
|
8672
8753
|
)
|
|
8673
8754
|
);
|
|
8674
8755
|
}
|
|
8756
|
+
const streakLine = premiumStreakLine(err.streak);
|
|
8757
|
+
if (streakLine) console.log(c.yellow(streakLine));
|
|
8675
8758
|
console.log(c.yellow(`Run \`clixad earn\` for a survey on the offer walls. Offers pay ${grantLabel(err.grantPerAd)}.`));
|
|
8676
8759
|
if (err.unlockUsd) {
|
|
8677
8760
|
console.log(c.yellow(`Or unlock premium from ${usd(err.unlockUsd)}: start \`clixad\` and type /buy.`));
|
|
@@ -8703,6 +8786,8 @@ async function setModel(client, config, model) {
|
|
|
8703
8786
|
`${model} runs on credits you earned on the offer walls or bought. Run \`clixad earn\` for a survey` + (client.premiumUnlockUsd ? `, or start \`clixad\` and type /buy.` : ".")
|
|
8704
8787
|
)
|
|
8705
8788
|
);
|
|
8789
|
+
const streakLine = premiumStreakLine(w?.premium?.streak);
|
|
8790
|
+
if (streakLine) console.log(c.yellow(streakLine));
|
|
8706
8791
|
}
|
|
8707
8792
|
}
|
|
8708
8793
|
}
|
|
@@ -8851,7 +8936,9 @@ ${shortfallHeadline(err, config.model)}`));
|
|
|
8851
8936
|
`Run \`clixad earn\` to open the offerwall \u2014 offers pay ${grantLabel(err.grantPerAd)}.`
|
|
8852
8937
|
)
|
|
8853
8938
|
);
|
|
8854
|
-
console.log(
|
|
8939
|
+
console.log(
|
|
8940
|
+
c.yellow(`Credits can also be bought${packsFromClause(err.cheapestPackUsd)}: start \`clixad\` and type /buy.`)
|
|
8941
|
+
);
|
|
8855
8942
|
console.log(c.dim(" Offers you are screened out of pay nothing \u2014 that is normal, just start another."));
|
|
8856
8943
|
} else if (err instanceof AuthError) {
|
|
8857
8944
|
console.log(c.red(err.message));
|
|
@@ -8985,7 +9072,9 @@ async function runTurn(client, config, messages) {
|
|
|
8985
9072
|
console.log(
|
|
8986
9073
|
c.yellow(`Run \`clixad earn\` to open the offerwall \u2014 offers pay ${grantLabel(err.grantPerAd)}.`)
|
|
8987
9074
|
);
|
|
8988
|
-
console.log(
|
|
9075
|
+
console.log(
|
|
9076
|
+
c.yellow(`Credits can also be bought${packsFromClause(err.cheapestPackUsd)}: start \`clixad\` and type /buy.`)
|
|
9077
|
+
);
|
|
8989
9078
|
console.log(c.dim(" Offers you are screened out of pay nothing \u2014 that is normal, just start another."));
|
|
8990
9079
|
} else if (err instanceof AuthError) {
|
|
8991
9080
|
console.log(c.red(err.message));
|