>;
+};
+
+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]);
+
+ const trackClick = React.useCallback(() => {
+ const exp = choice?.experiment_id;
+ const lbl = choice?.label ?? "control";
+ void sendClickMetric(ENV_BASE, proposalId, exp, lbl);
+ }, [proposalId, choice?.experiment_id, choice?.label]);
+
+ const label = choice?.label ?? "control";
+ const Variant = registry[label] || Control;
+
+ const key = `${proposalId}:${label}`;
+ return (
+
+ {React.createElement(Variant, {
+ key,
+ ...(props as any),
+ onProbatClick: trackClick,
+ probat: { trackClick },
+ })}
+
+ );
+}
+
+(Wrapped as any).displayName = `withExperiment(${(Control as any).displayName || Control.name || "Component"})`;
+return Wrapped as any;
+}
From 0cceac02ac1e8d68f212d6c7e82f9af380f7d9d3 Mon Sep 17 00:00:00 2001
From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com>
Date: Thu, 6 Nov 2025 09:32:58 +0000
Subject: [PATCH 12/15] 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 85109dd05f6e96c01b8e3539b411692432db70fc Mon Sep 17 00:00:00 2001
From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com>
Date: Thu, 6 Nov 2025 09:33:04 +0000
Subject: [PATCH 13/15] 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..1c69a1ee
--- /dev/null
+++ b/probat/config.tsx
@@ -0,0 +1,4 @@
+// probat/config.tsx
+export const PROBAT_COMPONENTS: Record = {
+ "src/components/Hero.tsx": { proposalId: "1db9df23-c7ca-4395-b929-65aa26949c93" }
+};
From 4da5ca82acee6d308ad77e69c9874ce9e8b9a72b Mon Sep 17 00:00:00 2001
From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com>
Date: Thu, 6 Nov 2025 09:33:10 +0000
Subject: [PATCH 14/15] Ensure probat/registry.tsx entry
---
probat/registry.tsx | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 probat/registry.tsx
diff --git a/probat/registry.tsx b/probat/registry.tsx
new file mode 100644
index 00000000..100c1dec
--- /dev/null
+++ b/probat/registry.tsx
@@ -0,0 +1,26 @@
+// probat/registry.tsx
+ import type React from "react";
+ import Exp_0_a from "./1db9df23-c7ca-4395-b929-65aa26949c93/0c07ddee-e9d0-405b-9119-145c0d19a527";
+import Exp_1_b from "./1db9df23-c7ca-4395-b929-65aa26949c93/c0fc681c-f985-481f-adc0-52bb28382da7";
+import Exp_2_c from "./1db9df23-c7ca-4395-b929-65aa26949c93/17a93140-b922-4fee-92cc-1a91362712c6";
+import Exp_3_d from "./1db9df23-c7ca-4395-b929-65aa26949c93/1e4a9571-c221-44da-a30f-5ff6b38abecd";
+import Exp_4_e from "./1db9df23-c7ca-4395-b929-65aa26949c93/2a340853-6b6b-47a0-abbc-9a527d1c6741";
+import Exp_5_f from "./1db9df23-c7ca-4395-b929-65aa26949c93/8f21c2a2-5e86-4f16-89a3-72a22d59a8eb";
+import Exp_6_g from "./1db9df23-c7ca-4395-b929-65aa26949c93/984e4b19-c412-4aec-bb5b-3c214a8c23e9";
+import Exp_7_h from "./1db9df23-c7ca-4395-b929-65aa26949c93/f3e7d614-bb8d-4b34-b2a9-a7c0d4f00394";
+import Exp_8_i from "./1db9df23-c7ca-4395-b929-65aa26949c93/e39bfa6b-caa7-4aa7-a1cc-debe8753743e";
+import Exp_9_j from "./1db9df23-c7ca-4395-b929-65aa26949c93/51840ed1-40c6-4cbd-ba33-f7ec7b53f560";
+ export const PROBAT_REGISTRIES: Record>> = {
+ "src/components/Hero.tsx": {
+ "a": Exp_0_a,
+ "b": Exp_1_b,
+ "c": Exp_2_c,
+ "d": Exp_3_d,
+ "e": Exp_4_e,
+ "f": Exp_5_f,
+ "g": Exp_6_g,
+ "h": Exp_7_h,
+ "i": Exp_8_i,
+ "j": Exp_9_j,
+ },
+ };
From ddc98d402a1938015511f5150e21bff8706fb7d6 Mon Sep 17 00:00:00 2001
From: "probatai[bot]" <236084945+probatai[bot]@users.noreply.github.com>
Date: Thu, 6 Nov 2025 09:33:24 +0000
Subject: [PATCH 15/15] probat: auto-edit component to integrate Probat at
src/components/Hero.tsx
---
src/components/Hero.tsx | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx
index 66d7f27c..8306d303 100644
--- a/src/components/Hero.tsx
+++ b/src/components/Hero.tsx
@@ -1,5 +1,9 @@
-import React from 'react'
-import './Hero.css'
+import React from "react";
+import { withExperiment } from "../../probat/runtime";
+import { PROBAT_COMPONENTS, PROBAT_REGISTRIES } from "../../probat/index";
+import './Hero.css';
+
+const __PROBAT_KEY__ = "src/components/Hero.tsx";
const Hero: React.FC = () => {
return (
@@ -61,4 +65,11 @@ const Hero: React.FC = () => {
)
}
-export default Hero
+// 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(Hero as any, { proposalId: meta.proposalId, registry: reg })
+ : Hero;
+})();