import { For, Show, createSignal } from "solid-js"; import Button from "~/components/ui/Button"; import Input from "~/components/ui/Input"; import { STATUS, ACCENT } from "./IslandMock"; import { useDemoLoop } from "./useDemoLoop"; import { betaRequestPayload } from "./betaRequest"; /** * iPhone + Apple Watch companion, in TestFlight beta. The request form * mirrors Settings ▸ Phone's BetaAccessCard in the app: it sends only the * email, over the same `/api/the-nook/report` pipeline (see betaRequest.ts). */ type RequestState = "idle" | "sending" | "sent" | "limited" | "failed"; function requestBetaAccess(email: string): Promise { return fetch("/api/the-nook/report", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(betaRequestPayload(email)) }); } /* ── Demo: a request lands on the phone, a question on the wrist ─── */ function CompanionDemo() { const [phase, setPhase] = createSignal< "quiet" | "ask" | "allowed" | "question" | "answered" >("quiet"); useDemoLoop(11000, [ [0, () => setPhase("quiet")], [900, () => setPhase("ask")], [3600, () => setPhase("allowed")], [5400, () => setPhase("question")], [8200, () => setPhase("answered")] ]); const askVisible = () => phase() !== "quiet"; const allowed = () => phase() !== "quiet" && phase() !== "ask"; const working = () => (allowed() ? 3 : 2); const waiting = () => (phase() === "ask" ? 1 : 0); return (
{/* iPhone */}

9:41

{/* Lock Screen widget: what the numbers count */}
{working()} working {waiting()} waiting
{/* notification */}
The Nook · now

{allowed() ? "Allowed ✓" : "Claude Code · the-nook"}

{allowed() ? "Back to work." : "Run Bash: swift test"}

Allow Deny
{/* Apple Watch */}
{working()} agents working
} >

Codex asks

Ship it to staging?

{(option, i) => ( {phase() === "answered" && i() === 0 ? "Sent ✓" : option} )}
); } export default function PhoneBeta(props: { brandColor: string }) { const [email, setEmail] = createSignal(""); const [state, setState] = createSignal("idle"); const submit = async () => { const contact = email().trim(); if (!contact || state() === "sending") return; setState("sending"); try { const res = await requestBetaAccess(contact); if (res.status === 429) return setState("limited"); if (!res.ok) return setState("failed"); setEmail(""); setState("sent"); } catch { setState("failed"); } }; return (
TestFlight beta

Your fleet, in your pocket

The iPhone and Apple Watch companion is in beta. Approvals, questions, and replies reach you away from the desk, and your answer goes straight back to the agent.

    {(bullet) => (
  • {bullet}
  • )}

Request beta access

Leave your email to get a TestFlight invite. We only receive your email address.

{ e.preventDefault(); void submit(); }} > setEmail(e.currentTarget.value)} />

Thanks. Watch your inbox for a TestFlight invite.

Too many requests from this network. Try again later.

Couldn't send the request. Check your connection and try again.

); }