@vibes.diy/api-svc 14.3.172 → 14.3.174

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.
@@ -0,0 +1,103 @@
1
+ import type { ResReportCampaignReadoutCheck, ResReportCampaignReadoutComparison, ResReportCampaignReadoutDay, ResReportCampaignReadoutPlacement, ResReportCampaignReadoutVerdict } from "@vibes.diy/api-types";
2
+ export declare const BENCHMARK_COST_PER_PROMPT = 54;
3
+ export declare const MIN_PROMPTERS = 10;
4
+ export declare const INTERVAL_LEVEL = 0.9;
5
+ export declare function poissonCI(k: number, level: number): [number, number];
6
+ export interface CostCI {
7
+ readonly point: number;
8
+ readonly lower: number;
9
+ readonly upper: number;
10
+ }
11
+ export declare function costPerPromptCI(spend: number, prompts: number, level: number): CostCI;
12
+ export declare function promptVerdict(spend: number, prompts: number | undefined, benchmark: number, level?: number): ResReportCampaignReadoutVerdict;
13
+ export interface CompareSide {
14
+ readonly name: string;
15
+ readonly spend: number;
16
+ readonly prompts: number;
17
+ }
18
+ export declare function compareToControl(cell: CompareSide, control: CompareSide, level: number): ResReportCampaignReadoutComparison;
19
+ export declare function parseSegmentStart(info: unknown): number | undefined;
20
+ export declare function effectiveSegmentStart(sigEditTs: number): number;
21
+ export declare function zonedDay(unixSec: number, tz: string): string;
22
+ export declare function zonedHourToUnix(day: string, hour: number, tz: string): number;
23
+ export interface MetaActionLike {
24
+ readonly action_type: string;
25
+ readonly value: string;
26
+ }
27
+ export declare function leadCount(actions: readonly MetaActionLike[] | undefined): number;
28
+ export declare function leadPoints(actionValues: readonly MetaActionLike[] | undefined): number;
29
+ export interface MetaHourlyRow {
30
+ readonly date_start: string;
31
+ readonly hourly_stats_aggregated_by_advertiser_time_zone?: string;
32
+ readonly spend?: string;
33
+ readonly impressions?: string;
34
+ readonly inline_link_clicks?: string;
35
+ readonly actions?: readonly MetaActionLike[];
36
+ readonly action_values?: readonly MetaActionLike[];
37
+ }
38
+ export interface MetaTotals {
39
+ readonly spend: number;
40
+ readonly impressions: number;
41
+ readonly linkClicks: number;
42
+ readonly leads: number;
43
+ readonly leadPoints: number;
44
+ }
45
+ export interface MetaHour extends MetaTotals {
46
+ readonly startTs: number;
47
+ readonly day: string;
48
+ }
49
+ export declare function parseHourlyInsight(row: MetaHourlyRow, tz: string): MetaHour | undefined;
50
+ export declare function sumHours(hours: readonly MetaHour[], fromTs: number, toTs: number): MetaTotals;
51
+ export declare function extractUtmCampaign(link: string | undefined, urlTags: string | undefined): string | undefined;
52
+ export interface AttributedPerson {
53
+ readonly utmCampaign: string;
54
+ readonly clickedAt: number;
55
+ readonly touchedAt: number;
56
+ readonly typedAt: number;
57
+ }
58
+ export interface AttributionCounts {
59
+ readonly visitors: number;
60
+ readonly touched: number;
61
+ readonly typedPrompters: number;
62
+ }
63
+ export interface RawAttributedPerson {
64
+ readonly utmCampaign: string;
65
+ readonly clicks: readonly number[];
66
+ readonly touches: readonly number[];
67
+ readonly typed: readonly number[];
68
+ }
69
+ export declare function personsInWindow(raw: readonly RawAttributedPerson[], fromTs: number, toTs: number): AttributedPerson[];
70
+ export declare function aggregateAttribution(persons: readonly AttributedPerson[], utmToAdset: ReadonlyMap<string, string>, fromTs: number, toTs: number): Map<string, AttributionCounts>;
71
+ export declare function dailyTrend(input: {
72
+ readonly hours: readonly MetaHour[];
73
+ readonly persons: readonly AttributedPerson[] | undefined;
74
+ readonly adsetUtms: ReadonlySet<string>;
75
+ readonly fromTs: number;
76
+ readonly toTs: number;
77
+ readonly tz: string;
78
+ }): ResReportCampaignReadoutDay[];
79
+ export interface MetaPlacementRow {
80
+ readonly publisher_platform?: string;
81
+ readonly platform_position?: string;
82
+ readonly spend?: string;
83
+ readonly action_values?: readonly MetaActionLike[];
84
+ }
85
+ export declare function placementRows(rows: readonly MetaPlacementRow[]): ResReportCampaignReadoutPlacement[];
86
+ export declare const DELIVERY_MIN = 0.9;
87
+ export declare const NON_TOUCH_MIN = 0.8;
88
+ export declare const FREQUENCY_MAX = 2;
89
+ export interface ChecklistInput {
90
+ readonly budget: number | undefined;
91
+ readonly spend: number;
92
+ readonly learningStatus: string | undefined;
93
+ readonly typedPrompters: number | undefined;
94
+ readonly costPerPrompt: number | undefined;
95
+ readonly leads: number;
96
+ readonly leadPoints: number;
97
+ readonly frequency: number | undefined;
98
+ readonly benchmark: number;
99
+ }
100
+ export declare function evaluateChecklist(input: ChecklistInput): {
101
+ items: ResReportCampaignReadoutCheck[];
102
+ ready: boolean;
103
+ };
@@ -0,0 +1,438 @@
1
+ export const BENCHMARK_COST_PER_PROMPT = 54;
2
+ export const MIN_PROMPTERS = 10;
3
+ export const INTERVAL_LEVEL = 0.9;
4
+ function logGamma(x) {
5
+ const c = [
6
+ 0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313, -176.61502916214059, 12.507343278686905,
7
+ -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7,
8
+ ];
9
+ if (x < 0.5)
10
+ return Math.log(Math.PI / Math.sin(Math.PI * x)) - logGamma(1 - x);
11
+ const xm = x - 1;
12
+ let a = c[0];
13
+ const t = xm + 7.5;
14
+ for (let i = 1; i < 9; i++)
15
+ a += c[i] / (xm + i);
16
+ return 0.5 * Math.log(2 * Math.PI) + (xm + 0.5) * Math.log(t) - t + Math.log(a);
17
+ }
18
+ function gammaP(s, x) {
19
+ if (x <= 0)
20
+ return 0;
21
+ if (x < s + 1) {
22
+ let sum = 1 / s;
23
+ let term = sum;
24
+ for (let n = 1; n < 1000; n++) {
25
+ term *= x / (s + n);
26
+ sum += term;
27
+ if (Math.abs(term) < Math.abs(sum) * 1e-15)
28
+ break;
29
+ }
30
+ return sum * Math.exp(-x + s * Math.log(x) - logGamma(s));
31
+ }
32
+ let b = x + 1 - s;
33
+ let c = 1e300;
34
+ let d = 1 / b;
35
+ let h = d;
36
+ for (let i = 1; i < 1000; i++) {
37
+ const an = -i * (i - s);
38
+ b += 2;
39
+ d = an * d + b;
40
+ if (Math.abs(d) < 1e-300)
41
+ d = 1e-300;
42
+ c = b + an / c;
43
+ if (Math.abs(c) < 1e-300)
44
+ c = 1e-300;
45
+ d = 1 / d;
46
+ const del = d * c;
47
+ h *= del;
48
+ if (Math.abs(del - 1) < 1e-15)
49
+ break;
50
+ }
51
+ return 1 - Math.exp(-x + s * Math.log(x) - logGamma(s)) * h;
52
+ }
53
+ function betaI(x, a, b) {
54
+ if (x <= 0)
55
+ return 0;
56
+ if (x >= 1)
57
+ return 1;
58
+ if (x > (a + 1) / (a + b + 2))
59
+ return 1 - betaI(1 - x, b, a);
60
+ const front = Math.exp(logGamma(a + b) - logGamma(a) - logGamma(b) + a * Math.log(x) + b * Math.log(1 - x));
61
+ let c = 1;
62
+ let d = 1 - ((a + b) * x) / (a + 1);
63
+ if (Math.abs(d) < 1e-300)
64
+ d = 1e-300;
65
+ d = 1 / d;
66
+ let h = d;
67
+ for (let m = 1; m < 1000; m++) {
68
+ const m2 = 2 * m;
69
+ let aa = (m * (b - m) * x) / ((a + m2 - 1) * (a + m2));
70
+ d = 1 + aa * d;
71
+ if (Math.abs(d) < 1e-300)
72
+ d = 1e-300;
73
+ c = 1 + aa / c;
74
+ if (Math.abs(c) < 1e-300)
75
+ c = 1e-300;
76
+ d = 1 / d;
77
+ h *= d * c;
78
+ aa = (-(a + m) * (a + b + m) * x) / ((a + m2) * (a + m2 + 1));
79
+ d = 1 + aa * d;
80
+ if (Math.abs(d) < 1e-300)
81
+ d = 1e-300;
82
+ c = 1 + aa / c;
83
+ if (Math.abs(c) < 1e-300)
84
+ c = 1e-300;
85
+ d = 1 / d;
86
+ const del = d * c;
87
+ h *= del;
88
+ if (Math.abs(del - 1) < 1e-15)
89
+ break;
90
+ }
91
+ return (front * h) / a;
92
+ }
93
+ function bisect(f, lo, hi, target) {
94
+ let l = lo;
95
+ let h = hi;
96
+ for (let i = 0; i < 200; i++) {
97
+ const mid = (l + h) / 2;
98
+ if (f(mid) < target)
99
+ l = mid;
100
+ else
101
+ h = mid;
102
+ }
103
+ return (l + h) / 2;
104
+ }
105
+ export function poissonCI(k, level) {
106
+ const alpha = 1 - level;
107
+ const lower = k === 0 ? 0 : bisect((mu) => gammaP(k, mu), 0, 10 * k + 100, alpha / 2);
108
+ const upper = bisect((mu) => gammaP(k + 1, mu), 0, 10 * k + 100, 1 - alpha / 2);
109
+ return [lower, upper];
110
+ }
111
+ function clopperPearson(x, n, level) {
112
+ const alpha = 1 - level;
113
+ const lower = x === 0 ? 0 : bisect((p) => betaI(p, x, n - x + 1), 0, 1, alpha / 2);
114
+ const upper = x === n ? 1 : bisect((p) => betaI(p, x + 1, n - x), 0, 1, 1 - alpha / 2);
115
+ return [lower, upper];
116
+ }
117
+ export function costPerPromptCI(spend, prompts, level) {
118
+ const [lo, hi] = poissonCI(prompts, level);
119
+ return {
120
+ point: prompts > 0 ? spend / prompts : Infinity,
121
+ lower: spend / hi,
122
+ upper: lo > 0 ? spend / lo : Infinity,
123
+ };
124
+ }
125
+ function money(n) {
126
+ return Number.isFinite(n) ? `$${n.toFixed(0)}` : "∞";
127
+ }
128
+ export function promptVerdict(spend, prompts, benchmark, level = INTERVAL_LEVEL) {
129
+ if (prompts === undefined)
130
+ return { kind: "no-data", label: "no PostHog data" };
131
+ const ci = costPerPromptCI(spend, prompts, level);
132
+ const bounds = {
133
+ ...(Number.isFinite(ci.point) ? { point: ci.point } : {}),
134
+ lower: ci.lower,
135
+ ...(Number.isFinite(ci.upper) ? { upper: ci.upper } : {}),
136
+ };
137
+ if (prompts < MIN_PROMPTERS) {
138
+ return { kind: "too-early", label: `too early — ${prompts} of ${MIN_PROMPTERS} prompters`, ...bounds };
139
+ }
140
+ const range = `${money(ci.lower)}–${money(ci.upper)}`;
141
+ if (ci.upper < benchmark)
142
+ return { kind: "cheaper", label: `cheaper than benchmark (${range})`, ...bounds };
143
+ if (ci.lower > benchmark)
144
+ return { kind: "dearer", label: `dearer than benchmark (${range})`, ...bounds };
145
+ return { kind: "cant-tell", label: `can't tell yet (${range} straddles ${money(benchmark)})`, ...bounds };
146
+ }
147
+ export function compareToControl(cell, control, level) {
148
+ const a = cell.prompts;
149
+ const b = control.prompts;
150
+ const n = a + b;
151
+ const base = { adsetName: cell.name, controlName: control.name };
152
+ if (n === 0 || cell.spend <= 0 || control.spend <= 0) {
153
+ return { ...base, lower: 0, verdict: "cant-tell", text: `${cell.name} vs ${control.name}: no prompts yet` };
154
+ }
155
+ const [plo, phi] = clopperPearson(a, n, level);
156
+ const toR = (p) => (p >= 1 ? Infinity : (p / (1 - p)) * (control.spend / cell.spend));
157
+ const rLo = toR(plo);
158
+ const rHi = toR(phi);
159
+ const lower = rHi === Infinity ? 0 : 1 / rHi;
160
+ const upper = rLo === 0 ? Infinity : 1 / rLo;
161
+ const point = a === 0 || b === 0 ? undefined : b / control.spend / (a / cell.spend);
162
+ const verdict = upper < 1 ? "cheaper" : lower > 1 ? "dearer" : "cant-tell";
163
+ const fmtR = (r) => (Number.isFinite(r) ? `${r.toFixed(2)}×` : "∞");
164
+ const pct = Math.round(level * 100);
165
+ const head = point === undefined
166
+ ? `${cell.name} vs ${control.name}: one side has no prompts yet`
167
+ : `${cell.name} pays ${fmtR(point)} what ${control.name} pays per real prompt`;
168
+ const tail = verdict === "cheaper"
169
+ ? "cheaper, and the counts support it"
170
+ : verdict === "dearer"
171
+ ? "dearer, and the counts support it"
172
+ : "the counts can't tell them apart yet";
173
+ return {
174
+ ...base,
175
+ ...(point === undefined ? {} : { point }),
176
+ lower,
177
+ ...(Number.isFinite(upper) ? { upper } : {}),
178
+ verdict,
179
+ text: `${head} (${pct}%: ${fmtR(lower)}–${fmtR(upper)}) — ${tail}.`,
180
+ };
181
+ }
182
+ export function parseSegmentStart(info) {
183
+ if (info === null || typeof info !== "object")
184
+ return undefined;
185
+ const raw = info.last_sig_edit_ts;
186
+ const n = typeof raw === "number" ? raw : typeof raw === "string" && raw.trim() !== "" ? Number(raw) : NaN;
187
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : undefined;
188
+ }
189
+ export function effectiveSegmentStart(sigEditTs) {
190
+ return Math.ceil(sigEditTs / 3600) * 3600;
191
+ }
192
+ export function zonedDay(unixSec, tz) {
193
+ return new Intl.DateTimeFormat("en-CA", { timeZone: tz, year: "numeric", month: "2-digit", day: "2-digit" }).format(new Date(unixSec * 1000));
194
+ }
195
+ function tzOffsetMs(utcMs, tz) {
196
+ const parts = new Intl.DateTimeFormat("en-US", {
197
+ timeZone: tz,
198
+ hourCycle: "h23",
199
+ year: "numeric",
200
+ month: "2-digit",
201
+ day: "2-digit",
202
+ hour: "2-digit",
203
+ minute: "2-digit",
204
+ second: "2-digit",
205
+ }).formatToParts(new Date(utcMs));
206
+ const get = (t) => Number(parts.find((p) => p.type === t)?.value ?? 0);
207
+ const asUtc = Date.UTC(get("year"), get("month") - 1, get("day"), get("hour") % 24, get("minute"), get("second"));
208
+ return asUtc - utcMs;
209
+ }
210
+ export function zonedHourToUnix(day, hour, tz) {
211
+ const [y, m, d] = day.split("-").map(Number);
212
+ const guess = Date.UTC(y, m - 1, d, hour);
213
+ const off = tzOffsetMs(guess, tz);
214
+ let t = guess - off;
215
+ const off2 = tzOffsetMs(t, tz);
216
+ if (off2 !== off)
217
+ t = guess - off2;
218
+ return Math.round(t / 1000);
219
+ }
220
+ function actionNum(list, type) {
221
+ const v = Number(list?.find((a) => a.action_type === type)?.value ?? 0);
222
+ return Number.isFinite(v) ? v : 0;
223
+ }
224
+ export function leadCount(actions) {
225
+ return actionNum(actions, "lead");
226
+ }
227
+ export function leadPoints(actionValues) {
228
+ return actionNum(actionValues, "lead");
229
+ }
230
+ function n(v) {
231
+ const x = Number(v ?? 0);
232
+ return Number.isFinite(x) ? x : 0;
233
+ }
234
+ export function parseHourlyInsight(row, tz) {
235
+ const m = /^(\d{1,2}):/.exec(row.hourly_stats_aggregated_by_advertiser_time_zone ?? "");
236
+ if (m === null)
237
+ return undefined;
238
+ return {
239
+ startTs: zonedHourToUnix(row.date_start, Number(m[1]), tz),
240
+ day: row.date_start,
241
+ spend: n(row.spend),
242
+ impressions: n(row.impressions),
243
+ linkClicks: n(row.inline_link_clicks),
244
+ leads: leadCount(row.actions),
245
+ leadPoints: leadPoints(row.action_values),
246
+ };
247
+ }
248
+ export function sumHours(hours, fromTs, toTs) {
249
+ const acc = { spend: 0, impressions: 0, linkClicks: 0, leads: 0, leadPoints: 0 };
250
+ for (const h of hours) {
251
+ if (h.startTs < fromTs || h.startTs >= toTs)
252
+ continue;
253
+ acc.spend += h.spend;
254
+ acc.impressions += h.impressions;
255
+ acc.linkClicks += h.linkClicks;
256
+ acc.leads += h.leads;
257
+ acc.leadPoints += h.leadPoints;
258
+ }
259
+ return acc;
260
+ }
261
+ export function extractUtmCampaign(link, urlTags) {
262
+ if (link !== undefined) {
263
+ try {
264
+ const v = new URL(link).searchParams.get("utm_campaign");
265
+ if (v !== null && v !== "")
266
+ return v;
267
+ }
268
+ catch {
269
+ }
270
+ }
271
+ if (urlTags !== undefined) {
272
+ const v = new URLSearchParams(urlTags).get("utm_campaign");
273
+ if (v !== null && v !== "")
274
+ return v;
275
+ }
276
+ return undefined;
277
+ }
278
+ function firstIn(list, from, to) {
279
+ for (const t of list)
280
+ if (t >= from && t < to)
281
+ return t;
282
+ return 0;
283
+ }
284
+ export function personsInWindow(raw, fromTs, toTs) {
285
+ const out = [];
286
+ for (const p of raw) {
287
+ const clickedAt = firstIn(p.clicks, fromTs, toTs);
288
+ if (clickedAt === 0)
289
+ continue;
290
+ out.push({
291
+ utmCampaign: p.utmCampaign,
292
+ clickedAt,
293
+ touchedAt: firstIn(p.touches, clickedAt, Number.POSITIVE_INFINITY),
294
+ typedAt: firstIn(p.typed, clickedAt, Number.POSITIVE_INFINITY),
295
+ });
296
+ }
297
+ return out;
298
+ }
299
+ export function aggregateAttribution(persons, utmToAdset, fromTs, toTs) {
300
+ const out = new Map();
301
+ for (const p of persons) {
302
+ if (p.clickedAt < fromTs || p.clickedAt >= toTs)
303
+ continue;
304
+ const adset = utmToAdset.get(p.utmCampaign);
305
+ if (adset === undefined)
306
+ continue;
307
+ const acc = out.get(adset) ?? { visitors: 0, touched: 0, typedPrompters: 0 };
308
+ acc.visitors += 1;
309
+ if (p.touchedAt > 0)
310
+ acc.touched += 1;
311
+ if (p.typedAt > 0)
312
+ acc.typedPrompters += 1;
313
+ out.set(adset, acc);
314
+ }
315
+ return out;
316
+ }
317
+ export function dailyTrend(input) {
318
+ const { tz } = input;
319
+ if (input.fromTs >= input.toTs)
320
+ return [];
321
+ const firstDay = zonedDay(input.fromTs, tz);
322
+ const lastDay = zonedDay(input.toTs - 1, tz);
323
+ const days = new Map();
324
+ for (let d = firstDay, guard = 0; guard < 400; guard++) {
325
+ days.set(d, { spend: 0, impressions: 0, leadPoints: 0, visitors: 0, typed: 0 });
326
+ if (d === lastDay)
327
+ break;
328
+ d = zonedDay(zonedHourToUnix(d, 12, tz) + 86_400, tz);
329
+ }
330
+ for (const h of input.hours) {
331
+ if (h.startTs < input.fromTs || h.startTs >= input.toTs)
332
+ continue;
333
+ const acc = days.get(zonedDay(h.startTs, tz));
334
+ if (acc === undefined)
335
+ continue;
336
+ acc.spend += h.spend;
337
+ acc.impressions += h.impressions;
338
+ acc.leadPoints += h.leadPoints;
339
+ }
340
+ for (const p of input.persons ?? []) {
341
+ if (!input.adsetUtms.has(p.utmCampaign))
342
+ continue;
343
+ if (p.clickedAt < input.fromTs || p.clickedAt >= input.toTs)
344
+ continue;
345
+ const acc = days.get(zonedDay(p.clickedAt, tz));
346
+ if (acc === undefined)
347
+ continue;
348
+ acc.visitors += 1;
349
+ if (p.typedAt > 0)
350
+ acc.typed += 1;
351
+ }
352
+ const firstPartial = zonedHourToUnix(firstDay, 0, tz) !== input.fromTs;
353
+ const lastEndsAtMidnight = zonedHourToUnix(zonedDay(input.toTs, tz), 0, tz) === input.toTs;
354
+ return [...days.entries()]
355
+ .map(([day, a]) => ({
356
+ day,
357
+ partial: (day === firstDay && firstPartial) || (day === lastDay && !lastEndsAtMidnight),
358
+ spend: a.spend,
359
+ impressions: a.impressions,
360
+ leadPoints: a.leadPoints,
361
+ ...(input.persons === undefined ? {} : { visitors: a.visitors, typedPrompters: a.typed }),
362
+ }))
363
+ .sort((a, b) => (a.day < b.day ? 1 : a.day > b.day ? -1 : 0));
364
+ }
365
+ export function placementRows(rows) {
366
+ const total = rows.reduce((s, r) => s + n(r.spend), 0);
367
+ return rows
368
+ .map((r) => {
369
+ const position = r.platform_position ?? "unknown";
370
+ return {
371
+ platform: r.publisher_platform ?? "unknown",
372
+ position,
373
+ spend: n(r.spend),
374
+ share: total > 0 ? n(r.spend) / total : 0,
375
+ leadPoints: leadPoints(r.action_values),
376
+ reels: /reels/i.test(position),
377
+ };
378
+ })
379
+ .sort((a, b) => b.spend - a.spend);
380
+ }
381
+ export const DELIVERY_MIN = 0.9;
382
+ export const NON_TOUCH_MIN = 0.8;
383
+ export const FREQUENCY_MAX = 2;
384
+ export function evaluateChecklist(input) {
385
+ const pct = (x) => `${Math.round(x * 100)}%`;
386
+ const items = [];
387
+ if (input.budget === undefined || input.budget <= 0) {
388
+ items.push({ id: "delivery", label: "Delivery ≥ 90% of daily budget", pass: null, value: "no daily budget" });
389
+ }
390
+ else {
391
+ const r = input.spend / input.budget;
392
+ items.push({ id: "delivery", label: "Delivery ≥ 90% of daily budget", pass: r >= DELIVERY_MIN, value: pct(r) });
393
+ }
394
+ items.push({
395
+ id: "learning",
396
+ label: "Learning exited (SUCCESS)",
397
+ pass: input.learningStatus === undefined ? null : input.learningStatus === "SUCCESS",
398
+ value: input.learningStatus ?? "not reported",
399
+ });
400
+ if (input.typedPrompters === undefined) {
401
+ items.push({
402
+ id: "prompts",
403
+ label: `≥ ${MIN_PROMPTERS} typed prompters at ≤ $${input.benchmark}`,
404
+ pass: null,
405
+ value: "no PostHog data",
406
+ });
407
+ }
408
+ else {
409
+ const cpp = input.costPerPrompt;
410
+ const ok = input.typedPrompters >= MIN_PROMPTERS && cpp !== undefined && cpp <= input.benchmark;
411
+ items.push({
412
+ id: "prompts",
413
+ label: `≥ ${MIN_PROMPTERS} typed prompters at ≤ $${input.benchmark}`,
414
+ pass: ok,
415
+ value: `${input.typedPrompters} at ${cpp === undefined ? "—" : `$${cpp.toFixed(2)}`}`,
416
+ });
417
+ }
418
+ if (input.leadPoints <= 0) {
419
+ items.push({ id: "rungs", label: "≥ 80% of Lead points above the touch rung", pass: null, value: "no Lead points" });
420
+ }
421
+ else {
422
+ const share = Math.max(0, input.leadPoints - input.leads) / input.leadPoints;
423
+ items.push({
424
+ id: "rungs",
425
+ label: "≥ 80% of Lead points above the touch rung",
426
+ pass: share >= NON_TOUCH_MIN,
427
+ value: pct(share),
428
+ });
429
+ }
430
+ items.push({
431
+ id: "frequency",
432
+ label: "Frequency < 2",
433
+ pass: input.frequency === undefined ? null : input.frequency < FREQUENCY_MAX,
434
+ value: input.frequency === undefined ? "not reported" : input.frequency.toFixed(2),
435
+ });
436
+ return { items, ready: items.every((i) => i.pass === true) };
437
+ }
438
+ //# sourceMappingURL=campaign-health-readout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaign-health-readout.js","sourceRoot":"","sources":["../../jsr/public/campaign-health-readout.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { CFEnv } from "@vibes.diy/api-types";
2
2
  import { cfDrizzle, VibesApiTables } from "@vibes.diy/api-sql";
3
+ import { timingSafeEqualString } from "../intern/timing-safe-equal.js";
3
4
  export interface GithubWebhookSql {
4
5
  db: ReturnType<typeof cfDrizzle>["db"];
5
6
  tables: VibesApiTables;
@@ -16,7 +17,7 @@ export declare const VIBES_CONTENT_HEADER = "x-vibes-content";
16
17
  export declare const VIBES_CONTENT_UNTRUSTED = "untrusted-external";
17
18
  export declare const VIBES_TIMESTAMP_HEADER = "x-vibes-timestamp";
18
19
  export declare const GITHUB_REPO_MAX_VIBES = 10;
19
- export declare function timingSafeEqualString(a: string, b: string): boolean;
20
+ export { timingSafeEqualString };
20
21
  export declare function githubSignatureFor(secret: string, rawBody: string): Promise<string>;
21
22
  export declare function vibeProvenanceSignature(input: {
22
23
  secret: string;
@@ -3,6 +3,7 @@ import { cfDrizzle, createVibesApiTables, toDBFlavour } from "@vibes.diy/api-sql
3
3
  import { and, asc, eq, inArray } from "drizzle-orm/sql/expressions";
4
4
  import { BACKEND_INTERNAL_AUTH_HEADER, backendDoName, sanitizeBackendApiForwardHeaders, VIBES_SESSION_USER_HEADER, } from "../intern/backend-do-addr.js";
5
5
  import { binderHandlesFor } from "../intern/github-binder-handle.js";
6
+ import { timingSafeEqualString } from "../intern/timing-safe-equal.js";
6
7
  export const GITHUB_EVENT_HEADER = "x-github-event";
7
8
  export const GITHUB_DELIVERY_HEADER = "x-github-delivery";
8
9
  export const GITHUB_SIGNATURE_HEADER = "x-hub-signature-256";
@@ -28,15 +29,7 @@ async function hmacSha256(key, message) {
28
29
  const cryptoKey = await crypto.subtle.importKey("raw", raw, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
29
30
  return crypto.subtle.sign("HMAC", cryptoKey, TxtEnDecoderSingleton().encode(message));
30
31
  }
31
- export function timingSafeEqualString(a, b) {
32
- if (a.length !== b.length)
33
- return false;
34
- let diff = 0;
35
- for (let i = 0; i < a.length; i = i + 1) {
36
- diff = diff | (a.charCodeAt(i) ^ b.charCodeAt(i));
37
- }
38
- return diff === 0;
39
- }
32
+ export { timingSafeEqualString };
40
33
  export async function githubSignatureFor(secret, rawBody) {
41
34
  return `sha256=${toHex(await hmacSha256(TxtEnDecoderSingleton().encode(secret), rawBody))}`;
42
35
  }