clixad 0.0.1-beta.16 → 0.0.1-beta.17

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 +62 -3
  2. package/package.json +1 -1
package/dist/clixad.mjs CHANGED
@@ -510,11 +510,17 @@ var init_client = __esm({
510
510
  if (!res.ok) throw new Error(`packs failed: ${res.status}`);
511
511
  return res.json();
512
512
  }
513
- async checkout(pack) {
513
+ /**
514
+ * `consent` carries the two declarations § 356 (5) BGB requires before we may
515
+ * deliver digital content inside the withdrawal period. It is not optional:
516
+ * the gateway refuses a checkout without it, because starting a purchase we
517
+ * could not deliver instantly is worse than not starting one.
518
+ */
519
+ async checkout(pack, consent) {
514
520
  const res = await fetch(`${this.config.gatewayUrl}/v1/billing/checkout`, {
515
521
  method: "POST",
516
522
  headers: this.headers(),
517
- body: JSON.stringify({ pack })
523
+ body: JSON.stringify({ pack, consent })
518
524
  });
519
525
  if (res.status === 401) throw await authFailure(res, "checkout");
520
526
  if (res.status === 501) throw new Error("Buying credits isn't enabled (Stripe not configured on the gateway).");
@@ -1001,12 +1007,18 @@ function sleep(ms, signal) {
1001
1007
  signal.addEventListener("abort", done, { once: true });
1002
1008
  });
1003
1009
  }
1010
+ var TERMS_URL, PRIVACY_URL, TERMS_NOTICE;
1004
1011
  var init_login = __esm({
1005
1012
  "src/login.ts"() {
1006
1013
  "use strict";
1007
1014
  init_client();
1008
1015
  init_browser();
1009
1016
  init_config();
1017
+ TERMS_URL = "https://clixad.io/terms.html";
1018
+ PRIVACY_URL = "https://clixad.io/privacy.html";
1019
+ TERMS_NOTICE = `By creating an account you confirm that you are at least 18 and that you agree to
1020
+ the Terms \u2014 ${TERMS_URL}
1021
+ and the Privacy Policy \u2014 ${PRIVACY_URL}`;
1010
1022
  }
1011
1023
  });
1012
1024
 
@@ -5639,6 +5651,7 @@ ${NO_SEARCH_INSTRUCTION}`),
5639
5651
  const runLogin = useCallback(
5640
5652
  async (arg) => {
5641
5653
  const args = parseLoginArgs(arg.split(/\s+/).filter(Boolean));
5654
+ push({ kind: "notice", text: TERMS_NOTICE });
5642
5655
  await runBusy(SIGNING_IN, async (signal) => {
5643
5656
  const outcome = await performLogin(
5644
5657
  client,
@@ -6719,6 +6732,7 @@ init_kimi();
6719
6732
  init_banner();
6720
6733
  init_browser();
6721
6734
  init_color();
6735
+ import { createInterface } from "node:readline/promises";
6722
6736
 
6723
6737
  // src/title.ts
6724
6738
  var APP_TITLE = "Clixad";
@@ -6815,6 +6829,7 @@ async function main() {
6815
6829
  }
6816
6830
  async function login(client, config, args) {
6817
6831
  const parsed = parseLoginArgs(args);
6832
+ for (const line2 of TERMS_NOTICE.split("\n")) console.log(c.dim(` ${line2}`));
6818
6833
  const outcome = await performLogin(client, config, parsed, {
6819
6834
  verify(start) {
6820
6835
  console.log(`
@@ -7020,9 +7035,20 @@ async function buyCmd(client, config, pack) {
7020
7035
  console.log(c.dim("\n buy one with: clixad buy <id>"));
7021
7036
  return;
7022
7037
  }
7038
+ const chosen = packs.find((x) => x.id === pack);
7039
+ if (!chosen) {
7040
+ console.log(c.red(` unknown pack: ${pack}`));
7041
+ return console.log(c.dim(` try one of: ${packs.map((x) => x.id).join(", ")}`));
7042
+ }
7043
+ const consented = await confirmWithdrawalWaiver(chosen);
7044
+ if (!consented) return;
7023
7045
  let checkout;
7024
7046
  try {
7025
- checkout = await client.checkout(pack);
7047
+ checkout = await client.checkout(pack, {
7048
+ requestImmediatePerformance: true,
7049
+ acknowledgeLossOfWithdrawal: true,
7050
+ at: (/* @__PURE__ */ new Date()).toISOString()
7051
+ });
7026
7052
  } catch (err) {
7027
7053
  return console.log(c.red(err.message));
7028
7054
  }
@@ -7045,6 +7071,39 @@ async function buyCmd(client, config, pack) {
7045
7071
  }
7046
7072
  console.log(c.yellow("\n No credits yet \u2014 the webhook may be delayed. Check `clixad wallet`."));
7047
7073
  }
7074
+ async function confirmWithdrawalWaiver(pack) {
7075
+ if (!process.stdin.isTTY) {
7076
+ console.log(c.yellow("\n Buying credits needs an interactive terminal."));
7077
+ console.log(
7078
+ c.dim(" We have to record your confirmation before charging you, and a pipe has nobody to ask.")
7079
+ );
7080
+ return false;
7081
+ }
7082
+ const price = "$" + pack.price_usd.toFixed(2);
7083
+ console.log(`
7084
+ ${c.bold(pack.label)} \u2014 ${credits(pack.credits)} credits for ${c.bold(price)}`);
7085
+ console.log(c.dim(` One purchase. No subscription, nothing to cancel. Terms: ${TERMS_URL}`));
7086
+ console.log("\n Before you pay, please confirm:");
7087
+ console.log(" \xB7 You request that we deliver the credits immediately, before the");
7088
+ console.log(" 14-day withdrawal period has expired.");
7089
+ console.log(" \xB7 You acknowledge that your right of withdrawal lapses once they");
7090
+ console.log(" have been delivered.");
7091
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
7092
+ let answer = "";
7093
+ try {
7094
+ answer = (await rl.question(`
7095
+ Type ${c.bold("yes")} to continue: `)).trim().toLowerCase();
7096
+ } catch {
7097
+ answer = "";
7098
+ } finally {
7099
+ rl.close();
7100
+ }
7101
+ if (answer !== "yes" && answer !== "y") {
7102
+ console.log(c.dim("\n Cancelled. You have not been charged."));
7103
+ return false;
7104
+ }
7105
+ return true;
7106
+ }
7048
7107
  async function ask(client, config, prompt) {
7049
7108
  if (!prompt) return console.error(c.red('usage: clixad ask "your prompt"'));
7050
7109
  const messages = [{ role: "user", content: prompt }];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clixad",
3
- "version": "0.0.1-beta.16",
3
+ "version": "0.0.1-beta.17",
4
4
  "description": "Free AI coding agent in your terminal, funded by rewarded ads.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",