clixad 0.0.1-beta.1 → 0.0.1-beta.2
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 +166 -92
- package/package.json +1 -1
package/dist/clixad.mjs
CHANGED
|
@@ -210,14 +210,18 @@ var init_client = __esm({
|
|
|
210
210
|
if (!res.ok) throw new Error(`checkout failed: ${res.status} ${await res.text()}`);
|
|
211
211
|
return res.json();
|
|
212
212
|
}
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
// Both take an optional signal for the REPL's sake: they are awaited while the
|
|
214
|
+
// input box is locked, and a gateway that is cold-starting (Render's free tier,
|
|
215
|
+
// the better part of a minute) would otherwise be indistinguishable from a
|
|
216
|
+
// hung terminal. Nothing else passes one — a one-shot CLI command has Ctrl+C.
|
|
217
|
+
async models(signal) {
|
|
218
|
+
const res = await fetch(`${this.config.gatewayUrl}/v1/models`, { signal });
|
|
215
219
|
if (!res.ok) throw new Error(`models failed: ${res.status}`);
|
|
216
220
|
const data = await res.json();
|
|
217
221
|
return data.data;
|
|
218
222
|
}
|
|
219
|
-
async wallet() {
|
|
220
|
-
const res = await fetch(`${this.config.gatewayUrl}/v1/wallet`, { headers: this.headers() });
|
|
223
|
+
async wallet(signal) {
|
|
224
|
+
const res = await fetch(`${this.config.gatewayUrl}/v1/wallet`, { headers: this.headers(), signal });
|
|
221
225
|
if (res.status === 401) throw await authFailure(res, "wallet");
|
|
222
226
|
if (!res.ok) throw new Error(`wallet failed: ${res.status}`);
|
|
223
227
|
return res.json();
|
|
@@ -1483,7 +1487,9 @@ import { spawn as spawn3 } from "node:child_process";
|
|
|
1483
1487
|
function openBrowser(url) {
|
|
1484
1488
|
const cmd = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
1485
1489
|
const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
1486
|
-
spawn3(cmd, args, { detached: true, stdio: "ignore", windowsHide: true })
|
|
1490
|
+
const child = spawn3(cmd, args, { detached: true, stdio: "ignore", windowsHide: true });
|
|
1491
|
+
child.on("error", () => void 0);
|
|
1492
|
+
child.unref();
|
|
1487
1493
|
}
|
|
1488
1494
|
var init_browser = __esm({
|
|
1489
1495
|
"src/browser.ts"() {
|
|
@@ -2118,11 +2124,13 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2118
2124
|
const [tick, setTick] = useState(0);
|
|
2119
2125
|
const [startedAt, setStartedAt] = useState(0);
|
|
2120
2126
|
const [quitHint, setQuitHint] = useState(false);
|
|
2127
|
+
const [busyLabel, setBusyLabel] = useState(WORKING);
|
|
2121
2128
|
const [sponsor, setSponsor] = useState(null);
|
|
2122
2129
|
const messagesRef = useRef(messages);
|
|
2123
2130
|
messagesRef.current = messages;
|
|
2124
2131
|
const permRef = useRef(createState("normal"));
|
|
2125
2132
|
const abortRef = useRef(null);
|
|
2133
|
+
const busyAbortRef = useRef(null);
|
|
2126
2134
|
const filesRef = useRef(null);
|
|
2127
2135
|
const ctrlCRef = useRef(0);
|
|
2128
2136
|
const sessionRef = useRef(session ?? { id: newSessionId(), started: (/* @__PURE__ */ new Date()).toISOString() });
|
|
@@ -2324,6 +2332,30 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2324
2332
|
},
|
|
2325
2333
|
[client, contextWindow, handleEvent, model, nextSponsor, permit, push, root, session?.title]
|
|
2326
2334
|
);
|
|
2335
|
+
const stopCurrent = useCallback(() => {
|
|
2336
|
+
abortRef.current?.abort();
|
|
2337
|
+
busyAbortRef.current?.abort();
|
|
2338
|
+
}, []);
|
|
2339
|
+
const runBusy = useCallback(
|
|
2340
|
+
async (label, fn) => {
|
|
2341
|
+
const ac = new AbortController();
|
|
2342
|
+
busyAbortRef.current = ac;
|
|
2343
|
+
setBusy(true);
|
|
2344
|
+
setBusyLabel(label);
|
|
2345
|
+
setStartedAt(Date.now());
|
|
2346
|
+
try {
|
|
2347
|
+
await fn(ac.signal);
|
|
2348
|
+
} catch (err) {
|
|
2349
|
+
if (ac.signal.aborted) push({ kind: "notice", tone: "warn", text: " (stopped)" });
|
|
2350
|
+
else push({ kind: "notice", tone: "error", text: ` ${err.message}` });
|
|
2351
|
+
} finally {
|
|
2352
|
+
busyAbortRef.current = null;
|
|
2353
|
+
setBusyLabel(WORKING);
|
|
2354
|
+
setBusy(false);
|
|
2355
|
+
}
|
|
2356
|
+
},
|
|
2357
|
+
[push]
|
|
2358
|
+
);
|
|
2327
2359
|
const runAdWall = useCallback(async () => {
|
|
2328
2360
|
const task = pendingTaskRef.current;
|
|
2329
2361
|
pendingTaskRef.current = null;
|
|
@@ -2337,18 +2369,28 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2337
2369
|
` : ` opened ${base} \u2014 paste your token there; waiting for the reward\u2026
|
|
2338
2370
|
`) + ` Credits land on completion; being screened out of an offer pays nothing and is normal.`
|
|
2339
2371
|
});
|
|
2340
|
-
setBusy(true);
|
|
2341
|
-
const deadline = Date.now() + 5 * 6e4;
|
|
2342
2372
|
let credited = false;
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
const
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2373
|
+
let stopped = false;
|
|
2374
|
+
await runBusy(WAITING_FOR_REWARD, async (signal) => {
|
|
2375
|
+
const deadline = Date.now() + 5 * 6e4;
|
|
2376
|
+
while (Date.now() < deadline && !credited && !signal.aborted) {
|
|
2377
|
+
await sleep(3e3, signal);
|
|
2378
|
+
if (signal.aborted) break;
|
|
2379
|
+
const w = await client.wallet(signal).catch(() => void 0);
|
|
2380
|
+
if (w && w.balance > before) {
|
|
2381
|
+
setBalance(w.balance);
|
|
2382
|
+
credited = true;
|
|
2383
|
+
}
|
|
2349
2384
|
}
|
|
2350
|
-
|
|
2351
|
-
|
|
2385
|
+
stopped = signal.aborted;
|
|
2386
|
+
});
|
|
2387
|
+
if (!credited) pendingTaskRef.current = task;
|
|
2388
|
+
if (stopped)
|
|
2389
|
+
return push({
|
|
2390
|
+
kind: "notice",
|
|
2391
|
+
tone: "warn",
|
|
2392
|
+
text: " stopped waiting. A reward still lands whenever the offer clears \u2014\n /wallet checks the balance, /earn opens the wall again." + (task ? "\n Your last request is still queued: press enter to retry it." : "")
|
|
2393
|
+
});
|
|
2352
2394
|
if (!credited)
|
|
2353
2395
|
return push({
|
|
2354
2396
|
kind: "notice",
|
|
@@ -2357,7 +2399,7 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2357
2399
|
});
|
|
2358
2400
|
push({ kind: "notice", tone: "good", text: " credits added \u2014 continuing" });
|
|
2359
2401
|
if (task) await runTurn2(task);
|
|
2360
|
-
}, [balance, client, config.dashboardUrl, push, runTurn2]);
|
|
2402
|
+
}, [balance, client, config.dashboardUrl, push, runBusy, runTurn2]);
|
|
2361
2403
|
const runCommand = useCallback(
|
|
2362
2404
|
async (line2) => {
|
|
2363
2405
|
const [cmd, ...rest] = line2.slice(1).split(" ");
|
|
@@ -2390,83 +2432,74 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2390
2432
|
push({ kind: "notice", text: ` mode \u2192 ${MODE_LABEL[permRef.current.mode]}` });
|
|
2391
2433
|
return;
|
|
2392
2434
|
}
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
}
|
|
2413
|
-
setBusy(false);
|
|
2435
|
+
// A model call like any other, so esc has to stop it like any other —
|
|
2436
|
+
// and stopping it costs nothing, since the summary only replaces the
|
|
2437
|
+
// conversation once the call has come back whole.
|
|
2438
|
+
case "compact":
|
|
2439
|
+
await runBusy(COMPACTING, async (signal) => {
|
|
2440
|
+
const res = await compact(
|
|
2441
|
+
client,
|
|
2442
|
+
model,
|
|
2443
|
+
[{ role: "system", content: contextRef.current.systemPrompt }, ...messagesRef.current],
|
|
2444
|
+
{ signal }
|
|
2445
|
+
);
|
|
2446
|
+
if (!res) return push({ kind: "notice", text: " nothing to compact yet" });
|
|
2447
|
+
setMessages(res.messages.slice(1));
|
|
2448
|
+
setBalance(res.balance);
|
|
2449
|
+
setSpent((s) => s + res.creditsCharged);
|
|
2450
|
+
push({
|
|
2451
|
+
kind: "notice",
|
|
2452
|
+
text: ` compacted: ~${Math.round(res.before / 1e3)}k \u2192 ~${Math.round(res.after / 1e3)}k tokens (${res.creditsCharged} credits)`
|
|
2453
|
+
});
|
|
2454
|
+
});
|
|
2414
2455
|
return;
|
|
2415
|
-
}
|
|
2416
2456
|
case "init":
|
|
2417
2457
|
await runTurn2(INIT_PROMPT);
|
|
2418
2458
|
return;
|
|
2419
2459
|
// Always the picker — an id you have to remember and type is exactly
|
|
2420
2460
|
// what a picker is for. A typed id only preselects a row.
|
|
2421
|
-
case "model":
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
push({ kind: "notice", tone: "warn", text: ` unknown model: ${arg}` });
|
|
2429
|
-
}
|
|
2430
|
-
const items = models.map((m) => ({
|
|
2431
|
-
value: m.id,
|
|
2432
|
-
label: m.id,
|
|
2433
|
-
hint: `${m.tier.padEnd(8)}${adsPerTaskLabel(m.est_ads_per_task)}`,
|
|
2434
|
-
current: m.id === model
|
|
2435
|
-
}));
|
|
2436
|
-
const preselect = items.findIndex((i) => i.value === arg);
|
|
2437
|
-
setPickerSel(preselect >= 0 ? preselect : Math.max(0, items.findIndex((i) => i.current)));
|
|
2438
|
-
setPicker({
|
|
2439
|
-
title: "Select model",
|
|
2440
|
-
subtitle: "Applies to this session and is saved as your default.",
|
|
2441
|
-
items,
|
|
2442
|
-
onPick: (choice) => {
|
|
2443
|
-
config.model = choice.value;
|
|
2444
|
-
saveConfig(config);
|
|
2445
|
-
setModel2(choice.value);
|
|
2446
|
-
push({ kind: "notice", text: ` model \u2192 ${choice.value}` });
|
|
2461
|
+
case "model":
|
|
2462
|
+
await runBusy(LOADING, async (signal) => {
|
|
2463
|
+
const models = catalogRef.current.length ? catalogRef.current : await client.models(signal);
|
|
2464
|
+
catalogRef.current = models;
|
|
2465
|
+
if (!models.length) return push({ kind: "notice", tone: "error", text: " could not load the model list" });
|
|
2466
|
+
if (arg && !models.some((m) => m.id === arg)) {
|
|
2467
|
+
push({ kind: "notice", tone: "warn", text: ` unknown model: ${arg}` });
|
|
2447
2468
|
}
|
|
2469
|
+
const items = models.map((m) => ({
|
|
2470
|
+
value: m.id,
|
|
2471
|
+
label: m.id,
|
|
2472
|
+
hint: `${m.tier.padEnd(8)}${adsPerTaskLabel(m.est_ads_per_task)}`,
|
|
2473
|
+
current: m.id === model
|
|
2474
|
+
}));
|
|
2475
|
+
const preselect = items.findIndex((i) => i.value === arg);
|
|
2476
|
+
setPickerSel(preselect >= 0 ? preselect : Math.max(0, items.findIndex((i) => i.current)));
|
|
2477
|
+
setPicker({
|
|
2478
|
+
title: "Select model",
|
|
2479
|
+
subtitle: "Applies to this session and is saved as your default.",
|
|
2480
|
+
items,
|
|
2481
|
+
onPick: (choice) => {
|
|
2482
|
+
config.model = choice.value;
|
|
2483
|
+
saveConfig(config);
|
|
2484
|
+
setModel2(choice.value);
|
|
2485
|
+
push({ kind: "notice", text: ` model \u2192 ${choice.value}` });
|
|
2486
|
+
}
|
|
2487
|
+
});
|
|
2448
2488
|
});
|
|
2449
2489
|
return;
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
try {
|
|
2454
|
-
const ms = await client.models();
|
|
2490
|
+
case "models":
|
|
2491
|
+
await runBusy(LOADING, async (signal) => {
|
|
2492
|
+
const ms = await client.models(signal);
|
|
2455
2493
|
catalogRef.current = ms;
|
|
2456
2494
|
push({
|
|
2457
2495
|
kind: "notice",
|
|
2458
2496
|
text: ms.map((m) => ` ${m.id.padEnd(24)} ${adsPerTaskLabel(m.est_ads_per_task)}`).join("\n")
|
|
2459
2497
|
});
|
|
2460
|
-
}
|
|
2461
|
-
push({ kind: "notice", tone: "error", text: ` ${err.message}` });
|
|
2462
|
-
}
|
|
2463
|
-
setBusy(false);
|
|
2498
|
+
});
|
|
2464
2499
|
return;
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
try {
|
|
2469
|
-
const w = await client.wallet();
|
|
2500
|
+
case "wallet":
|
|
2501
|
+
await runBusy(LOADING, async (signal) => {
|
|
2502
|
+
const w = await client.wallet(signal);
|
|
2470
2503
|
setBalance(w.balance);
|
|
2471
2504
|
const reversals = w.ledger.filter((e) => e.reason === "ad_reversal");
|
|
2472
2505
|
const reversed = reversals.reduce((sum, e) => sum + Math.abs(e.delta), 0);
|
|
@@ -2475,12 +2508,8 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2475
2508
|
text: ` balance ${w.balance.toLocaleString("en-US")} credits \xB7 ${w.ads_today} offers today \xB7 $${w.earned_usd_today.toFixed(2)}/$${w.max_reward_usd_per_day.toFixed(2)} earned` + (reversals.length ? `
|
|
2476
2509
|
recently: ${reversed.toLocaleString("en-US")} credits from ${reversals.length} offer${reversals.length === 1 ? "" : "s"} were reversed by the provider. Run \`clixad wallet\` for the full ledger.` : "")
|
|
2477
2510
|
});
|
|
2478
|
-
}
|
|
2479
|
-
push({ kind: "notice", tone: "error", text: ` ${err.message}` });
|
|
2480
|
-
}
|
|
2481
|
-
setBusy(false);
|
|
2511
|
+
});
|
|
2482
2512
|
return;
|
|
2483
|
-
}
|
|
2484
2513
|
// The same browser handoff the paywall takes, rather than a second way of
|
|
2485
2514
|
// doing it: /earn used to call the dev-only /v1/ads/reward simulator, so
|
|
2486
2515
|
// in production the slash command the paywall itself recommends was a 404.
|
|
@@ -2491,7 +2520,7 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2491
2520
|
push({ kind: "notice", tone: "warn", text: ` unknown command: /${cmd} \u2014 try /help` });
|
|
2492
2521
|
}
|
|
2493
2522
|
},
|
|
2494
|
-
[client, config, cycleMode, exit, model, push, runTurn2]
|
|
2523
|
+
[client, config, cycleMode, exit, model, push, runAdWall, runBusy, runTurn2]
|
|
2495
2524
|
);
|
|
2496
2525
|
const submit = useCallback(
|
|
2497
2526
|
async (raw) => {
|
|
@@ -2540,7 +2569,7 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2540
2569
|
);
|
|
2541
2570
|
useInput((ch, key) => {
|
|
2542
2571
|
if (key.ctrl && ch === "c") {
|
|
2543
|
-
if (busy) return
|
|
2572
|
+
if (busy) return stopCurrent();
|
|
2544
2573
|
if (!isEmpty(editor)) return setEditor(EMPTY);
|
|
2545
2574
|
if (Date.now() - ctrlCRef.current < 2e3) return exit();
|
|
2546
2575
|
ctrlCRef.current = Date.now();
|
|
@@ -2579,7 +2608,7 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2579
2608
|
return;
|
|
2580
2609
|
}
|
|
2581
2610
|
if (busy) {
|
|
2582
|
-
if (key.escape)
|
|
2611
|
+
if (key.escape) stopCurrent();
|
|
2583
2612
|
return;
|
|
2584
2613
|
}
|
|
2585
2614
|
if (key.tab && key.shift) return cycleMode();
|
|
@@ -2675,7 +2704,9 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2675
2704
|
/* @__PURE__ */ jsx2(Text2, { color: MANGO_BRIGHT, children: "\u276F " }),
|
|
2676
2705
|
busy ? /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
2677
2706
|
spinner,
|
|
2678
|
-
"
|
|
2707
|
+
" ",
|
|
2708
|
+
busyLabel,
|
|
2709
|
+
" ",
|
|
2679
2710
|
elapsed,
|
|
2680
2711
|
"s \xB7 esc to stop"
|
|
2681
2712
|
] }) : /* @__PURE__ */ jsx2(Text2, { children: renderInput(editor) })
|
|
@@ -2702,6 +2733,18 @@ function App({ client, config, wallet, session, initialTask }) {
|
|
|
2702
2733
|
] })
|
|
2703
2734
|
] });
|
|
2704
2735
|
}
|
|
2736
|
+
function sleep(ms, signal) {
|
|
2737
|
+
return new Promise((resolve2) => {
|
|
2738
|
+
if (signal.aborted) return resolve2();
|
|
2739
|
+
const done = () => {
|
|
2740
|
+
clearTimeout(timer);
|
|
2741
|
+
signal.removeEventListener("abort", done);
|
|
2742
|
+
resolve2();
|
|
2743
|
+
};
|
|
2744
|
+
const timer = setTimeout(done, ms);
|
|
2745
|
+
signal.addEventListener("abort", done, { once: true });
|
|
2746
|
+
});
|
|
2747
|
+
}
|
|
2705
2748
|
function renderInput(state) {
|
|
2706
2749
|
return state.lines.map((line2, row) => {
|
|
2707
2750
|
const prefix = row === 0 ? "" : "\n";
|
|
@@ -2762,7 +2805,7 @@ function tailLines(text, max) {
|
|
|
2762
2805
|
const lines = text.split("\n");
|
|
2763
2806
|
return lines.length <= max ? text : lines.slice(-max).join("\n");
|
|
2764
2807
|
}
|
|
2765
|
-
var SPINNER, LIVE_OUTPUT_LINES, COMMITTED_OUTPUT_LINES;
|
|
2808
|
+
var SPINNER, WORKING, WAITING_FOR_REWARD, LOADING, COMPACTING, LIVE_OUTPUT_LINES, COMMITTED_OUTPUT_LINES;
|
|
2766
2809
|
var init_app = __esm({
|
|
2767
2810
|
"src/tui/app.tsx"() {
|
|
2768
2811
|
"use strict";
|
|
@@ -2785,6 +2828,10 @@ var init_app = __esm({
|
|
|
2785
2828
|
init_suggest();
|
|
2786
2829
|
init_views();
|
|
2787
2830
|
SPINNER = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
2831
|
+
WORKING = "working\u2026";
|
|
2832
|
+
WAITING_FOR_REWARD = "waiting for the offer\u2026";
|
|
2833
|
+
LOADING = "loading\u2026";
|
|
2834
|
+
COMPACTING = "compacting\u2026";
|
|
2788
2835
|
LIVE_OUTPUT_LINES = 5;
|
|
2789
2836
|
COMMITTED_OUTPUT_LINES = 4;
|
|
2790
2837
|
}
|
|
@@ -2819,6 +2866,31 @@ init_session();
|
|
|
2819
2866
|
init_kimi();
|
|
2820
2867
|
init_banner();
|
|
2821
2868
|
init_browser();
|
|
2869
|
+
|
|
2870
|
+
// src/title.ts
|
|
2871
|
+
var APP_TITLE = "Clixad";
|
|
2872
|
+
function titleEnabled({ isTTY, env }) {
|
|
2873
|
+
const flag = env.CLIXAD_TITLE?.trim().toLowerCase();
|
|
2874
|
+
if (flag === "0" || flag === "false" || flag === "off" || flag === "no") return false;
|
|
2875
|
+
if (!isTTY) return false;
|
|
2876
|
+
if (env.TERM === "dumb") return false;
|
|
2877
|
+
if (env.CI !== void 0 && env.CI !== "") return false;
|
|
2878
|
+
return true;
|
|
2879
|
+
}
|
|
2880
|
+
function titleSequence(title) {
|
|
2881
|
+
return `\x1B]0;${title.replace(/[\x00-\x1f\x7f]/g, " ").trim()}\x07`;
|
|
2882
|
+
}
|
|
2883
|
+
function setTerminalTitle(title = APP_TITLE, out = process.stdout) {
|
|
2884
|
+
process.title = title.toLowerCase();
|
|
2885
|
+
if (!titleEnabled({ isTTY: out.isTTY, env: process.env })) return;
|
|
2886
|
+
out.write(titleSequence(title));
|
|
2887
|
+
}
|
|
2888
|
+
function clearTerminalTitle(out = process.stdout) {
|
|
2889
|
+
if (!titleEnabled({ isTTY: out.isTTY, env: process.env })) return;
|
|
2890
|
+
out.write(titleSequence(""));
|
|
2891
|
+
}
|
|
2892
|
+
|
|
2893
|
+
// src/main.ts
|
|
2822
2894
|
var c = {
|
|
2823
2895
|
cyan: (s) => `\x1B[36m${s}\x1B[0m`,
|
|
2824
2896
|
green: (s) => `\x1B[32m${s}\x1B[0m`,
|
|
@@ -2828,6 +2900,8 @@ var c = {
|
|
|
2828
2900
|
bold: (s) => `\x1B[1m${s}\x1B[0m`
|
|
2829
2901
|
};
|
|
2830
2902
|
async function main() {
|
|
2903
|
+
setTerminalTitle();
|
|
2904
|
+
process.on("exit", () => clearTerminalTitle());
|
|
2831
2905
|
const [cmd, ...rest] = process.argv.slice(2);
|
|
2832
2906
|
const config = loadConfig();
|
|
2833
2907
|
const client = new GatewayClient(config);
|
|
@@ -2925,7 +2999,7 @@ async function githubLogin(client, config, start, invite) {
|
|
|
2925
2999
|
const deadline = Date.now() + start.expires_in * 1e3;
|
|
2926
3000
|
let interval = Math.max(start.interval, 1);
|
|
2927
3001
|
while (Date.now() < deadline) {
|
|
2928
|
-
await
|
|
3002
|
+
await sleep2(interval * 1e3);
|
|
2929
3003
|
process.stdout.write(c.dim("."));
|
|
2930
3004
|
const poll = await client.devicePoll(start.session, invite);
|
|
2931
3005
|
if (poll.status === "pending") {
|
|
@@ -2976,7 +3050,7 @@ async function devLogin(client, config, email, invite) {
|
|
|
2976
3050
|
console.log(` balance: ${c.bold(String(res.balance))} credits (signup bonus)`);
|
|
2977
3051
|
console.log(c.dim(` token stored in ${configPath()}`));
|
|
2978
3052
|
}
|
|
2979
|
-
var
|
|
3053
|
+
var sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
2980
3054
|
function logout(config) {
|
|
2981
3055
|
delete config.token;
|
|
2982
3056
|
delete config.userId;
|
|
@@ -3052,7 +3126,7 @@ async function earn(client, config) {
|
|
|
3052
3126
|
process.stdout.write(c.dim(" waiting for an offer to clear"));
|
|
3053
3127
|
const deadline = Date.now() + 5 * 60 * 1e3;
|
|
3054
3128
|
while (Date.now() < deadline) {
|
|
3055
|
-
await
|
|
3129
|
+
await sleep2(3e3);
|
|
3056
3130
|
process.stdout.write(c.dim("."));
|
|
3057
3131
|
const balance = (await safeWallet(client))?.balance ?? before;
|
|
3058
3132
|
if (balance > before) {
|
|
@@ -3097,7 +3171,7 @@ async function buyCmd(client, config, pack) {
|
|
|
3097
3171
|
process.stdout.write(c.dim(" waiting for payment to clear"));
|
|
3098
3172
|
const deadline = Date.now() + 5 * 60 * 1e3;
|
|
3099
3173
|
while (Date.now() < deadline) {
|
|
3100
|
-
await
|
|
3174
|
+
await sleep2(3e3);
|
|
3101
3175
|
process.stdout.write(c.dim("."));
|
|
3102
3176
|
const balance = (await safeWallet(client))?.balance ?? before;
|
|
3103
3177
|
if (balance > before) {
|