clixad 0.0.1-beta.41 → 0.0.1-beta.43
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) {
|
|
@@ -2306,6 +2319,94 @@ function diffStat(lines) {
|
|
|
2306
2319
|
}
|
|
2307
2320
|
return { added, removed };
|
|
2308
2321
|
}
|
|
2322
|
+
var MAX_VIEW_ROWS = 2e3;
|
|
2323
|
+
function diffView(path, before, after, opts = {}) {
|
|
2324
|
+
const context = opts.context ?? 3;
|
|
2325
|
+
if (opts.created) {
|
|
2326
|
+
const lines2 = splitLines(after);
|
|
2327
|
+
const rows2 = lines2.slice(0, MAX_VIEW_ROWS).map((text, i) => ({ kind: "add", line: i + 1, text }));
|
|
2328
|
+
if (lines2.length > MAX_VIEW_ROWS) rows2.push({ kind: "gap", count: lines2.length - MAX_VIEW_ROWS });
|
|
2329
|
+
return { kind: "diff", path, created: true, added: after === "" ? 0 : lines2.length, removed: 0, rows: rows2 };
|
|
2330
|
+
}
|
|
2331
|
+
const lines = diffLines(splitLines(before), splitLines(after));
|
|
2332
|
+
const { added, removed } = diffStat(lines);
|
|
2333
|
+
const keep = new Array(lines.length).fill(false);
|
|
2334
|
+
lines.forEach((l, i) => {
|
|
2335
|
+
if (l.kind === "ctx") return;
|
|
2336
|
+
for (let k = Math.max(0, i - context); k <= Math.min(lines.length - 1, i + context); k++) keep[k] = true;
|
|
2337
|
+
});
|
|
2338
|
+
const rows = [];
|
|
2339
|
+
let skipped = 0;
|
|
2340
|
+
for (let i = 0; i < lines.length; i++) {
|
|
2341
|
+
if (!keep[i]) {
|
|
2342
|
+
skipped++;
|
|
2343
|
+
continue;
|
|
2344
|
+
}
|
|
2345
|
+
if (skipped > 0 && rows.length > 0) rows.push({ kind: "gap", count: skipped });
|
|
2346
|
+
skipped = 0;
|
|
2347
|
+
if (rows.length >= MAX_VIEW_ROWS) {
|
|
2348
|
+
rows.push({ kind: "gap", count: lines.length - i });
|
|
2349
|
+
break;
|
|
2350
|
+
}
|
|
2351
|
+
rows.push({ ...lines[i] });
|
|
2352
|
+
}
|
|
2353
|
+
return { kind: "diff", path, created: false, added, removed, rows };
|
|
2354
|
+
}
|
|
2355
|
+
function diffTint(env = process.env) {
|
|
2356
|
+
if (env.NO_COLOR) return "none";
|
|
2357
|
+
if (env.COLORTERM === "truecolor" || env.COLORTERM === "24bit") return "truecolor";
|
|
2358
|
+
if (/256/.test(env.TERM ?? "")) return "256";
|
|
2359
|
+
if (env.TERM === "dumb") return "none";
|
|
2360
|
+
return "basic";
|
|
2361
|
+
}
|
|
2362
|
+
var TINTS = {
|
|
2363
|
+
truecolor: {
|
|
2364
|
+
add: "\x1B[48;2;28;62;38m",
|
|
2365
|
+
del: "\x1B[48;2;78;32;36m",
|
|
2366
|
+
addSign: "\x1B[38;2;126;231;135m",
|
|
2367
|
+
delSign: "\x1B[38;2;255;123;114m",
|
|
2368
|
+
off: R
|
|
2369
|
+
},
|
|
2370
|
+
"256": { add: "\x1B[48;5;22m", del: "\x1B[48;5;52m", addSign: "\x1B[92m", delSign: "\x1B[91m", off: R },
|
|
2371
|
+
basic: { add: GREEN, del: RED, addSign: "", delSign: "", off: R },
|
|
2372
|
+
none: { add: "", del: "", addSign: "", delSign: "", off: "" }
|
|
2373
|
+
};
|
|
2374
|
+
function renderDiffRows(view, width, opts) {
|
|
2375
|
+
const tint = TINTS[opts.tint ?? "basic"];
|
|
2376
|
+
const max = opts.maxRows ?? Number.POSITIVE_INFINITY;
|
|
2377
|
+
const numbers = view.rows.filter((r) => r.kind !== "gap");
|
|
2378
|
+
const gutter = Math.max(3, ...numbers.map((r) => String(r.line).length));
|
|
2379
|
+
const fit = (text) => {
|
|
2380
|
+
const cut2 = opts.measure(text) > width ? opts.cut(text, width) : text;
|
|
2381
|
+
return cut2 + " ".repeat(Math.max(0, width - opts.measure(cut2)));
|
|
2382
|
+
};
|
|
2383
|
+
const rows = [];
|
|
2384
|
+
let more = 0;
|
|
2385
|
+
for (const row of view.rows) {
|
|
2386
|
+
if (rows.length >= max) {
|
|
2387
|
+
if (row.kind !== "gap") more++;
|
|
2388
|
+
continue;
|
|
2389
|
+
}
|
|
2390
|
+
if (row.kind === "gap") {
|
|
2391
|
+
const dim = tint === TINTS.none ? "" : DIM;
|
|
2392
|
+
rows.push(`${dim}${opts.cut(`${" ".repeat(gutter)} \u22EF ${row.count} unchanged line${row.count === 1 ? "" : "s"}`, width)}${tint.off}`);
|
|
2393
|
+
continue;
|
|
2394
|
+
}
|
|
2395
|
+
const text = row.text.replace(/\t/g, " ");
|
|
2396
|
+
const no = String(row.line).padStart(gutter);
|
|
2397
|
+
if (row.kind === "ctx") {
|
|
2398
|
+
rows.push(`${tint === TINTS.none ? "" : DIM}${opts.cut(`${no} ${text}`, width)}${tint.off}`);
|
|
2399
|
+
continue;
|
|
2400
|
+
}
|
|
2401
|
+
const sign = row.kind === "add" ? "+" : "-";
|
|
2402
|
+
const bg2 = row.kind === "add" ? tint.add : tint.del;
|
|
2403
|
+
const signColor = row.kind === "add" ? tint.addSign : tint.delSign;
|
|
2404
|
+
const body = fit(`${no} ${sign} ${text}`);
|
|
2405
|
+
const at = gutter + 1;
|
|
2406
|
+
rows.push(`${bg2}${body.slice(0, at)}${signColor}${sign}${signColor ? "\x1B[39m" : ""}${body.slice(at + 1)}${tint.off}`);
|
|
2407
|
+
}
|
|
2408
|
+
return { rows, more };
|
|
2409
|
+
}
|
|
2309
2410
|
function renderDiff(oldText, newText, opts = {}) {
|
|
2310
2411
|
const context = opts.context ?? 3;
|
|
2311
2412
|
const maxLines = opts.maxLines ?? 40;
|
|
@@ -3605,13 +3706,16 @@ ${body2}` + (pdf.text.length > MAX_FILE_BYTES ? "\n\u2026 [truncated]" : "");
|
|
|
3605
3706
|
const abs = safeResolve(ctx.root, requireString(args.path, "write_file", "path"));
|
|
3606
3707
|
const content = requireString(args.content, "write_file", "content");
|
|
3607
3708
|
const name = rel(ctx.root, abs);
|
|
3608
|
-
const
|
|
3709
|
+
const existed = existsSync2(abs);
|
|
3710
|
+
const before = existed ? fsCall(`cannot write ${name}`, () => readFileSync3(abs, "utf8")) : "";
|
|
3609
3711
|
const preview = renderDiff(before, content) || "(no change)";
|
|
3712
|
+
const view = diffView(name, before, content, { created: !existed });
|
|
3610
3713
|
await gate(ctx, {
|
|
3611
3714
|
tool: "write_file",
|
|
3612
3715
|
signature: `write:${name}`,
|
|
3613
3716
|
summary: `${before ? "overwrite" : "create"} ${name}`,
|
|
3614
3717
|
preview,
|
|
3718
|
+
view,
|
|
3615
3719
|
path: name,
|
|
3616
3720
|
root: ctx.root
|
|
3617
3721
|
});
|
|
@@ -3619,6 +3723,7 @@ ${body2}` + (pdf.text.length > MAX_FILE_BYTES ? "\n\u2026 [truncated]" : "");
|
|
|
3619
3723
|
mkdirSync2(dirname2(abs), { recursive: true });
|
|
3620
3724
|
writeFileSync2(abs, content, "utf8");
|
|
3621
3725
|
});
|
|
3726
|
+
ctx.present?.(view);
|
|
3622
3727
|
return `wrote ${content.length} bytes to ${name}`;
|
|
3623
3728
|
},
|
|
3624
3729
|
/**
|
|
@@ -3648,15 +3753,18 @@ ${body2}` + (pdf.text.length > MAX_FILE_BYTES ? "\n\u2026 [truncated]" : "");
|
|
|
3648
3753
|
}
|
|
3649
3754
|
const after = before.split(oldString).join(newString);
|
|
3650
3755
|
const preview = renderDiff(before, after) || "(no change)";
|
|
3756
|
+
const view = diffView(name, before, after);
|
|
3651
3757
|
await gate(ctx, {
|
|
3652
3758
|
tool: "edit_file",
|
|
3653
3759
|
signature: `write:${name}`,
|
|
3654
3760
|
summary: `edit ${name}`,
|
|
3655
3761
|
preview,
|
|
3762
|
+
view,
|
|
3656
3763
|
path: name,
|
|
3657
3764
|
root: ctx.root
|
|
3658
3765
|
});
|
|
3659
3766
|
fsCall(`cannot edit ${name}`, () => writeFileSync2(abs, after, "utf8"));
|
|
3767
|
+
ctx.present?.(view);
|
|
3660
3768
|
return `edited ${name} (${count > 1 ? `${count} occurrences` : "1 occurrence"})`;
|
|
3661
3769
|
},
|
|
3662
3770
|
/**
|
|
@@ -5303,6 +5411,9 @@ async function runAgent(client, task, opts) {
|
|
|
5303
5411
|
mcp: opts.mcp,
|
|
5304
5412
|
shells: opts.shells,
|
|
5305
5413
|
attach: (image) => pendingImages.push(image),
|
|
5414
|
+
// A placeholder that says writes are shown at this depth; each call gets
|
|
5415
|
+
// its own (`executeToolCall`), which puts the view on its result event.
|
|
5416
|
+
...depth === 0 ? { present: () => void 0 } : {},
|
|
5306
5417
|
// The recursion guard, and the whole of it: a sub-agent runs at depth 1 and
|
|
5307
5418
|
// is handed no way to start another.
|
|
5308
5419
|
...depth === 0 ? { spawn: runSubAgent } : {}
|
|
@@ -5498,9 +5609,13 @@ async function executeToolCall(ctx, call, emit) {
|
|
|
5498
5609
|
}
|
|
5499
5610
|
emit({ type: "tool_call", id, name, args });
|
|
5500
5611
|
const search = ctx.webSearch;
|
|
5612
|
+
let view;
|
|
5501
5613
|
const scoped = {
|
|
5502
5614
|
...ctx,
|
|
5503
5615
|
onOutput: (chunk) => emit({ type: "tool_output", id, chunk }),
|
|
5616
|
+
// Only where something draws it: a sub-agent's writes are not shown, and
|
|
5617
|
+
// `ctx.present` is how this run says whether anybody is watching.
|
|
5618
|
+
...ctx.present ? { present: (v) => view = v } : {},
|
|
5504
5619
|
// Reported against this call the moment it is charged, so the row says
|
|
5505
5620
|
// what it cost and the balance on screen moves with it.
|
|
5506
5621
|
...search ? {
|
|
@@ -5520,7 +5635,7 @@ async function executeToolCall(ctx, call, emit) {
|
|
|
5520
5635
|
};
|
|
5521
5636
|
try {
|
|
5522
5637
|
const result = await dispatch(scoped, name, args);
|
|
5523
|
-
emit({ type: "tool_result", id, name, result, ok: true });
|
|
5638
|
+
emit({ type: "tool_result", id, name, result, ok: true, ...view ? { view } : {} });
|
|
5524
5639
|
return result;
|
|
5525
5640
|
} catch (err) {
|
|
5526
5641
|
if (err instanceof ToolError) {
|
|
@@ -6410,6 +6525,7 @@ export {
|
|
|
6410
6525
|
NO_PREMIUM_CREDITS,
|
|
6411
6526
|
usd,
|
|
6412
6527
|
packsFromClause,
|
|
6528
|
+
rewardedAdLine,
|
|
6413
6529
|
parseSpendable,
|
|
6414
6530
|
adsPerTaskLabel,
|
|
6415
6531
|
grantLabel,
|
|
@@ -6443,6 +6559,8 @@ export {
|
|
|
6443
6559
|
webSearchCostLine,
|
|
6444
6560
|
freeHelpLine,
|
|
6445
6561
|
freeAlternativeLine,
|
|
6562
|
+
diffTint,
|
|
6563
|
+
renderDiffRows,
|
|
6446
6564
|
shells,
|
|
6447
6565
|
TodoList,
|
|
6448
6566
|
loadMcpConfig,
|
package/dist/clixad.mjs
CHANGED
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
takeConfigNotices,
|
|
54
54
|
toolSchemaFor,
|
|
55
55
|
usd
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-T7SUUKJC.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-
|
|
135
|
+
return withProductionReact(() => import("./tui-773NJ4FQ.mjs"));
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
// src/title.ts
|