From 530ce80544755fb43bcaf98aabe37e76730ffee5 Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:58:36 +0000 Subject: [PATCH 01/11] probat: add activated component probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/d7fb1a9b-0a03-41e5-aa77-657a308ef113.tsx --- .../d7fb1a9b-0a03-41e5-aa77-657a308ef113.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/d7fb1a9b-0a03-41e5-aa77-657a308ef113.tsx diff --git a/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/d7fb1a9b-0a03-41e5-aa77-657a308ef113.tsx b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/d7fb1a9b-0a03-41e5-aa77-657a308ef113.tsx new file mode 100644 index 00000000..afed8299 --- /dev/null +++ b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/d7fb1a9b-0a03-41e5-aa77-657a308ef113.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import '../../src/components/Features.css'; + +interface Feature { + icon: string; + title: string; + description: string; +} + +const features: Feature[] = [ + { icon: '⚡', title: 'Lightning Fast', description: 'Built for speed with optimized performance and minimal loading times.' }, + { icon: '🔒', title: 'Secure', description: 'Enterprise-grade security with end-to-end encryption and compliance.' }, + { icon: '📱', title: 'Responsive', description: 'Perfect experience across all devices and screen sizes.' }, + { icon: '🎨', title: 'Customizable', description: 'Fully customizable themes and components to match your brand.' }, + { icon: '🚀', title: 'Scalable', description: 'Grows with your business from startup to enterprise scale.' }, + { icon: '💬', title: 'Support', description: '24/7 customer support with dedicated success managers.' } +]; + +const Features: React.FC = () => { + return ( +
+
+
+

Why Choose Us?

+

+ Discover the features that make our platform the best choice for your needs. +

+
+ +
+ {features.map((feature, index) => ( +
+
+ {feature.icon} +
+

{feature.title}

+

{feature.description}

+
+ ))} +
+
+
+ ); +}; + +export default Features; \ No newline at end of file From 387fa0298e9abc3f7118c2977d2dd9c2c21010d7 Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:58:39 +0000 Subject: [PATCH 02/11] probat: add activated component probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/35864a5f-62ca-48bf-bfe9-f9200590ffd7.tsx --- .../35864a5f-62ca-48bf-bfe9-f9200590ffd7.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/35864a5f-62ca-48bf-bfe9-f9200590ffd7.tsx diff --git a/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/35864a5f-62ca-48bf-bfe9-f9200590ffd7.tsx b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/35864a5f-62ca-48bf-bfe9-f9200590ffd7.tsx new file mode 100644 index 00000000..e4afc5f9 --- /dev/null +++ b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/35864a5f-62ca-48bf-bfe9-f9200590ffd7.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import '../../src/components/Features.css'; + +interface Feature { + icon: string; + title: string; + description: string; +} + +const features: Feature[] = [ + { icon: '⚡', title: 'Lightning Fast', description: 'Built for speed with optimized performance and minimal loading times.' }, + { icon: '🔒', title: 'Secure', description: 'Enterprise-grade security with end-to-end encryption and compliance.' }, + { icon: '📱', title: 'Responsive', description: 'Perfect experience across all devices and screen sizes.' }, + { icon: '🎨', title: 'Customizable', description: 'Fully customizable themes and components to match your brand.' }, + { icon: '🚀', title: 'Scalable', description: 'Grows with your business from startup to enterprise scale.' }, + { icon: '💬', title: 'Support', description: '24/7 customer support with dedicated success managers.' } +]; + +const Features: React.FC = () => { + return ( +
+
+
+

Why Choose Us?

+

+ Discover the features that make our platform the best choice for your needs. +

+
+ +
+ {features.map((feature, index) => ( +
+
+ {feature.icon} +
+

{feature.title}

+

{feature.description}

+
+ ))} +
+
+
+ ); +}; + +export default Features; \ No newline at end of file From 466a44bfe3a090e70bcd3cce52204978e562b9bb Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:58:41 +0000 Subject: [PATCH 03/11] probat: add activated component probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/3c390170-1a94-40d8-9d66-fc01f9ffff82.tsx --- .../3c390170-1a94-40d8-9d66-fc01f9ffff82.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/3c390170-1a94-40d8-9d66-fc01f9ffff82.tsx diff --git a/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/3c390170-1a94-40d8-9d66-fc01f9ffff82.tsx b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/3c390170-1a94-40d8-9d66-fc01f9ffff82.tsx new file mode 100644 index 00000000..7eb93737 --- /dev/null +++ b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/3c390170-1a94-40d8-9d66-fc01f9ffff82.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import '../../src/components/Features.css'; + +interface Feature { + icon: string; + title: string; + description: string; +} + +const features: Feature[] = [ + { icon: '⚡', title: 'Lightning Fast', description: 'Built for speed with optimized performance and minimal loading times.' }, + { icon: '🔒', title: 'Secure', description: 'Enterprise-grade security with end-to-end encryption and compliance.' }, + { icon: '📱', title: 'Responsive', description: 'Perfect experience across all devices and screen sizes.' }, + { icon: '🎨', title: 'Customizable', description: 'Fully customizable themes and components to match your brand.' }, + { icon: '🚀', title: 'Scalable', description: 'Grows with your business from startup to enterprise scale.' }, + { icon: '💬', title: 'Support', description: '24/7 customer support with dedicated success managers.' } +]; + +const Features: React.FC = () => { + return ( +
+
+
+

Why Choose Us?

+

+ Discover the features that make our platform the best choice for your needs. +

+
+ +
+ {features.map((feature, index) => ( +
+
+ {feature.icon} +
+

{feature.title}

+

{feature.description}

+
+ ))} +
+
+
+ ); +}; + +export default Features; \ No newline at end of file From 62d2eb8233ad6bfd0a7aa0a1d38c455b83a1a3a6 Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:58:43 +0000 Subject: [PATCH 04/11] probat: add activated component probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/735f4aa6-0f9b-4f54-a116-2aec55f39e6a.tsx --- .../735f4aa6-0f9b-4f54-a116-2aec55f39e6a.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/735f4aa6-0f9b-4f54-a116-2aec55f39e6a.tsx diff --git a/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/735f4aa6-0f9b-4f54-a116-2aec55f39e6a.tsx b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/735f4aa6-0f9b-4f54-a116-2aec55f39e6a.tsx new file mode 100644 index 00000000..d03e32fc --- /dev/null +++ b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/735f4aa6-0f9b-4f54-a116-2aec55f39e6a.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import '../../src/components/Features.css'; + +interface Feature { + icon: string; + title: string; + description: string; +} + +const features: Feature[] = [ + { icon: '⚡', title: 'Lightning Fast', description: 'Built for speed with optimized performance and minimal loading times.' }, + { icon: '🔒', title: 'Secure', description: 'Enterprise-grade security with end-to-end encryption and compliance.' }, + { icon: '📱', title: 'Responsive', description: 'Perfect experience across all devices and screen sizes.' }, + { icon: '🎨', title: 'Customizable', description: 'Fully customizable themes and components to match your brand.' }, + { icon: '🚀', title: 'Scalable', description: 'Grows with your business from startup to enterprise scale.' }, + { icon: '💬', title: 'Support', description: '24/7 customer support with dedicated success managers.' } +]; + +const Features: React.FC = () => { + return ( +
+
+
+

Why Choose Us?

+

+ Discover the features that make our platform the best choice for your needs. +

+
+ +
+ {features.map((feature, index) => ( +
+
+ {feature.icon} +
+

{feature.title}

+

{feature.description}

+
+ ))} +
+
+
+ ); +}; + +export default Features; \ No newline at end of file From 847cbaef3556ff984d24364d9696e39940ef00b1 Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:58:46 +0000 Subject: [PATCH 05/11] probat: add activated component probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/bc8fd9d7-0daf-4830-8af7-b5e1e4d31847.tsx --- .../bc8fd9d7-0daf-4830-8af7-b5e1e4d31847.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/bc8fd9d7-0daf-4830-8af7-b5e1e4d31847.tsx diff --git a/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/bc8fd9d7-0daf-4830-8af7-b5e1e4d31847.tsx b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/bc8fd9d7-0daf-4830-8af7-b5e1e4d31847.tsx new file mode 100644 index 00000000..64840668 --- /dev/null +++ b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/bc8fd9d7-0daf-4830-8af7-b5e1e4d31847.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import '../../src/components/Features.css'; + +interface Feature { + icon: string; + title: string; + description: string; +} + +const features: Feature[] = [ + { icon: '⚡', title: 'Lightning Fast', description: 'Built for speed with optimized performance and minimal loading times.' }, + { icon: '🔒', title: 'Secure', description: 'Enterprise-grade security with end-to-end encryption and compliance.' }, + { icon: '📱', title: 'Responsive', description: 'Perfect experience across all devices and screen sizes.' }, + { icon: '🎨', title: 'Customizable', description: 'Fully customizable themes and components to match your brand.' }, + { icon: '🚀', title: 'Scalable', description: 'Grows with your business from startup to enterprise scale.' }, + { icon: '💬', title: 'Support', description: '24/7 customer support with dedicated success managers.' } +]; + +const Features: React.FC = () => { + return ( +
+
+
+

Why Choose Us?

+

+ Discover the features that make our platform the best choice for your needs. +

+
+ +
+ {features.map((feature, index) => ( +
+
+ {feature.icon} +
+

{feature.title}

+

{feature.description}

+
+ ))} +
+
+
+ ); +}; + +export default Features; \ No newline at end of file From 8d32e6cd3eb9b7edc8128aea4041a45e5a3b5c05 Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:58:48 +0000 Subject: [PATCH 06/11] probat: add activated component probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/fc41a57e-2bae-4c44-8074-899f97f58c76.tsx --- .../fc41a57e-2bae-4c44-8074-899f97f58c76.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/fc41a57e-2bae-4c44-8074-899f97f58c76.tsx diff --git a/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/fc41a57e-2bae-4c44-8074-899f97f58c76.tsx b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/fc41a57e-2bae-4c44-8074-899f97f58c76.tsx new file mode 100644 index 00000000..d47ccb63 --- /dev/null +++ b/probat/b67c9b37-e15f-4562-99a2-8fa70af080a1/fc41a57e-2bae-4c44-8074-899f97f58c76.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import '../../src/components/Features.css'; + +interface Feature { + icon: string; + title: string; + description: string; +} + +const features: Feature[] = [ + { icon: '⚡', title: 'Lightning Fast', description: 'Built for speed with optimized performance and minimal loading times.' }, + { icon: '🔒', title: 'Secure', description: 'Enterprise-grade security with end-to-end encryption and compliance.' }, + { icon: '📱', title: 'Responsive', description: 'Perfect experience across all devices and screen sizes.' }, + { icon: '🎨', title: 'Customizable', description: 'Fully customizable themes and components to match your brand.' }, + { icon: '🚀', title: 'Scalable', description: 'Grows with your business from startup to enterprise scale.' }, + { icon: '💬', title: 'Support', description: '24/7 customer support with dedicated success managers.' } +]; + +const Features: React.FC = () => { + return ( +
+
+
+

Why Choose Us?

+

+ Discover the features that make our platform the best choice for your needs. +

+
+ +
+ {features.map((feature, index) => ( +
+
+ {feature.icon} +
+

{feature.title}

+

{feature.description}

+
+ ))} +
+
+
+ ); +}; + +export default Features; \ No newline at end of file From dc4d673db09b1f766a6185a3a7808e64008dd5d3 Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:58:51 +0000 Subject: [PATCH 07/11] Add probat/runtime.tsx --- probat/runtime.tsx | 247 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 probat/runtime.tsx diff --git a/probat/runtime.tsx b/probat/runtime.tsx new file mode 100644 index 00000000..e597a446 --- /dev/null +++ b/probat/runtime.tsx @@ -0,0 +1,247 @@ +// probat/runtime.tsx +import * as React from "react"; + +declare global { +interface Window { + __PROBAT_API?: string; +} +} + +const ENV_BASE: string = +(typeof import.meta !== "undefined" && (import.meta as any).env?.VITE_PROBAT_API) || +(typeof process !== "undefined" && (process as any).env?.NEXT_PUBLIC_PROBAT_API) || +(typeof window !== "undefined" && window.__PROBAT_API) || +"https://gushi.onrender.com"; + +const TTL_MS = 6 * 60 * 60 * 1000; // 6 hours +const KEY = (proposalId: string) => `probat_choice_v3:${proposalId}`; +const VISIT_KEY = (proposalId: string, label: string) => `probat_visit_v1:${proposalId}:${label}`; +const visitMemo = new Set(); + +type RetrieveResponse = { +proposal_id: string; +experiment_id: string | null; +label: string | null; +}; + +type Choice = { +experiment_id: string; +label: string; +ts: number; +}; + +function safeGet(k: string): any | null { +try { + const raw = localStorage.getItem(k); + return raw ? JSON.parse(raw) : null; +} catch { + return null; +} +} +function safeSet(k: string, v: any) { +try { + localStorage.setItem(k, JSON.stringify(v)); +} catch {} +} +function now() { return Date.now(); } +function fresh(ts: number) { return now() - ts <= TTL_MS; } +function readChoice(proposalId: string): Choice | null { +const c = safeGet(KEY(proposalId)) as Choice | null; +return c && fresh(c.ts) ? c : null; +} +function writeChoice(proposalId: string, experiment_id: string, label: string) { +safeSet(KEY(proposalId), { experiment_id, label, ts: now() } as Choice); +} + +async function fetchDecision(baseUrl: string, proposalId: string): Promise<{ experiment_id: string; label: string }> { +const url = `${baseUrl.replace(/\/$/, "")}/retrieve_react_experiment/${encodeURIComponent(proposalId)}`; +const res = await fetch(url, { method: "POST", headers: { Accept: "application/json" } }); +if (!res.ok) throw new Error(`HTTP ${res.status}`); +const data = (await res.json()) as RetrieveResponse; + +const experiment_id = (data.experiment_id || `exp_${proposalId}`).toString(); +const label = data.label && data.label.trim() ? data.label : "control"; + +writeChoice(proposalId, experiment_id, label); +return { experiment_id, label }; +} + +function hasTrackedVisit(proposalId: string, label: string): boolean { +const key = VISIT_KEY(proposalId, label); +if (visitMemo.has(key)) return true; +try { + const raw = localStorage.getItem(key); + if (!raw) return false; + const ts = Number(raw); + if (!Number.isFinite(ts) || ts <= 0) return false; + if (now() - ts > TTL_MS) { + localStorage.removeItem(key); + return false; + } + visitMemo.add(key); + return true; +} catch { + return false; +} +} + +function markTrackedVisit(proposalId: string, label: string) { +const key = VISIT_KEY(proposalId, label); +visitMemo.add(key); +try { + localStorage.setItem(key, now().toString()); +} catch {} +} + +async function sendVisitMetric(baseUrl: string, proposalId: string, experiment_id?: string, variant_label?: string) { +const url = `${baseUrl.replace(/\/$/, "")}/send_metrics/${encodeURIComponent(proposalId)}`; +const body = { + experiment_id: experiment_id ?? null, + variant_label: variant_label ?? "control", + metric_name: "visit", + metric_value: 1, + metric_unit: "count", + source: "react", + dimensions: {}, + captured_at: new Date().toISOString(), +}; +try { + await fetch(url, { + method: "POST", + headers: { Accept: "application/json", "Content-Type": "application/json" }, + body: JSON.stringify(body), + }); +} catch {} +} + +function recordVisit(baseUrl: string, proposalId: string, experiment_id?: string, variant_label?: string) { +const label = variant_label ?? "control"; +if (hasTrackedVisit(proposalId, label)) return; +markTrackedVisit(proposalId, label); +void sendVisitMetric(baseUrl, proposalId, experiment_id, label); +} + +function extractClickMeta(event?: React.MouseEvent): Record | undefined { +if (!event) return undefined; +const rawTarget = event.target as HTMLElement | null; +if (!rawTarget) return undefined; +const actionable = rawTarget.closest("[data-probat-conversion='true'], button, a, [role='button']"); +if (!actionable) return undefined; +const meta: Record = { + target_tag: actionable.tagName, +}; +if (actionable.id) meta.target_id = actionable.id; +const attr = actionable.getAttribute("data-probat-conversion"); +if (attr) meta.conversion_attr = attr; +const text = actionable.textContent?.trim(); +if (text) meta.target_text = text.slice(0, 120); +return meta; +} + +async function sendClickMetric(baseUrl: string, proposalId: string, _experiment_id?: string, variant_label?: string, meta?: Record) { +const url = `${baseUrl.replace(/\/$/, "")}/send_metrics/${encodeURIComponent(proposalId)}`; +const body = { + experiment_id: null, + variant_label: variant_label ?? "control", + metric_name: "click", + metric_value: 1, + metric_unit: "count", + source: "react", + dimensions: meta ?? {}, + captured_at: new Date().toISOString(), +}; +try { + await fetch(url, { + method: "POST", + headers: { Accept: "application/json", "Content-Type": "application/json" }, + body: JSON.stringify(body), + }); +} catch {} +} + +type WithExperimentOpts = { +proposalId: string; +registry: Record>; +}; + +export function withExperiment

( +Control: React.ComponentType

, +opts: WithExperimentOpts +): React.ComponentType

void; probat?: { trackClick: () => void } }> { +const { proposalId, registry } = opts; + +function Wrapped(props: P) { + const [choice, setChoice] = React.useState<{ experiment_id: string; label: string } | null>(null); + + React.useEffect(() => { + let alive = true; + + const cached = readChoice(proposalId); + if (cached) { + setChoice({ experiment_id: cached.experiment_id, label: cached.label }); + } + + if (!cached) { + (async () => { + try { + const { experiment_id, label } = await fetchDecision(ENV_BASE, proposalId); + if (!alive) return; + setChoice({ experiment_id, label }); + } catch (e) { + if (!alive) return; + setChoice({ experiment_id: `exp_${proposalId}`, label: "control" }); + } + })(); + } + + return () => { alive = false; }; + }, [proposalId]); + + React.useEffect(() => { + const exp = choice?.experiment_id; + const lbl = choice?.label ?? "control"; + if (!lbl) return; + recordVisit(ENV_BASE, proposalId, exp ?? undefined, lbl); + }, [proposalId, choice?.experiment_id, choice?.label]); + + const trackClick = React.useCallback( + (event?: React.MouseEvent | null, options?: { force?: boolean }) => { + const exp = choice?.experiment_id; + const lbl = choice?.label ?? "control"; + const meta = extractClickMeta(event ?? undefined); + if (!options?.force && event && !meta) { + return false; + } + void sendClickMetric(ENV_BASE, proposalId, exp, lbl, meta); + return true; + }, + [proposalId, choice?.experiment_id, choice?.label] + ); + + const label = choice?.label ?? "control"; + const Variant = registry[label] || Control; + + const key = `${proposalId}:${label}`; + return ( +

{ + try { + props.onProbatClick?.(); + } catch {} + trackClick(event); + }} + data-probat-proposal={proposalId} + > + {React.createElement(Variant, { + key, + ...(props as any), + onProbatClick: () => trackClick(null, { force: true }), + probat: { trackClick: () => trackClick(null, { force: true }) }, + })} +
+ ); +} + +(Wrapped as any).displayName = `withExperiment(${(Control as any).displayName || Control.name || "Component"})`; +return Wrapped as any; +} From 8a603281c2218c34028c39f3beb92ee5b20349a9 Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:58:54 +0000 Subject: [PATCH 08/11] Add probat/index.tsx --- probat/index.tsx | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 probat/index.tsx diff --git a/probat/index.tsx b/probat/index.tsx new file mode 100644 index 00000000..c5493906 --- /dev/null +++ b/probat/index.tsx @@ -0,0 +1,4 @@ +// probat/index.tsx +export { withExperiment } from "./runtime"; +export { PROBAT_REGISTRIES } from "./registry"; +export { PROBAT_COMPONENTS } from "./config"; From d0c07dc6feabd051a763699be69b6a1196109a62 Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:58:57 +0000 Subject: [PATCH 09/11] Ensure probat/config.tsx entry --- probat/config.tsx | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 probat/config.tsx diff --git a/probat/config.tsx b/probat/config.tsx new file mode 100644 index 00000000..37f7a7f3 --- /dev/null +++ b/probat/config.tsx @@ -0,0 +1,4 @@ +// probat/config.tsx +export const PROBAT_COMPONENTS: Record = { + "src/components/Features.tsx": { proposalId: "b67c9b37-e15f-4562-99a2-8fa70af080a1" } +}; From 4645a873e3098d5a240a11e17003d55f08817e7d Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:59:00 +0000 Subject: [PATCH 10/11] Ensure probat/registry.tsx entry --- probat/registry.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 probat/registry.tsx diff --git a/probat/registry.tsx b/probat/registry.tsx new file mode 100644 index 00000000..f79a130d --- /dev/null +++ b/probat/registry.tsx @@ -0,0 +1,18 @@ +// probat/registry.tsx + import type React from "react"; + import Exp_0_c from "./b67c9b37-e15f-4562-99a2-8fa70af080a1/d7fb1a9b-0a03-41e5-aa77-657a308ef113"; +import Exp_1_d from "./b67c9b37-e15f-4562-99a2-8fa70af080a1/35864a5f-62ca-48bf-bfe9-f9200590ffd7"; +import Exp_2_e from "./b67c9b37-e15f-4562-99a2-8fa70af080a1/3c390170-1a94-40d8-9d66-fc01f9ffff82"; +import Exp_3_f from "./b67c9b37-e15f-4562-99a2-8fa70af080a1/735f4aa6-0f9b-4f54-a116-2aec55f39e6a"; +import Exp_4_g from "./b67c9b37-e15f-4562-99a2-8fa70af080a1/bc8fd9d7-0daf-4830-8af7-b5e1e4d31847"; +import Exp_5_i from "./b67c9b37-e15f-4562-99a2-8fa70af080a1/fc41a57e-2bae-4c44-8074-899f97f58c76"; + export const PROBAT_REGISTRIES: Record>> = { + "src/components/Features.tsx": { + "c": Exp_0_c, + "d": Exp_1_d, + "e": Exp_2_e, + "f": Exp_3_f, + "g": Exp_4_g, + "i": Exp_5_i, + }, + }; From 6ee9e29a6a8ac3b0fc1b383c12d23ac37d193332 Mon Sep 17 00:00:00 2001 From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 07:59:08 +0000 Subject: [PATCH 11/11] probat: auto-edit component to integrate Probat at src/components/Features.tsx --- src/components/Features.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/components/Features.tsx b/src/components/Features.tsx index fdf0619f..3486623e 100644 --- a/src/components/Features.tsx +++ b/src/components/Features.tsx @@ -1,6 +1,10 @@ import React from 'react' +import { withExperiment } from "../../probat/runtime"; +import { PROBAT_COMPONENTS, PROBAT_REGISTRIES } from "../../probat/index"; import './Features.css' +const __PROBAT_KEY__ = "src/components/Features.tsx"; + interface Feature { icon: string title: string @@ -67,4 +71,11 @@ const Features: React.FC = () => { ) } -export default Features +// Probat Generate Lines. +export default (() => { + const meta = PROBAT_COMPONENTS[__PROBAT_KEY__]; + const reg = PROBAT_REGISTRIES[__PROBAT_KEY__] as Record> | undefined; + return (meta?.proposalId && reg) + ? withExperiment(Features as any, { proposalId: meta.proposalId, registry: reg }) + : Features; +})();