Call Sheet Announcer
Lovable AI summarizes daily logistics so crews stay informed; the Adamo fleet dashboard shows every robot doing it at once.
The move.
Filmmakers watch every robot in the Filmmaking & Animation ensemble at once: a live grid, join/leave feed, and wildcard topic tap over the Adamo bridge so production management at scale stays legible from one glance.
Why this kernelA fleet dashboard matches production management because Filmmaking & Animation at scale is many bodies moving together — the operator needs to see which robots are online, what topics are flowing, and where attention should go, all in one glance.
Run the bridge first.
Start the bridge on your laptop before pasting the prompt below. The Lovable app never holds the Adamo key.
The build prompt.
Paste into a fresh Lovable project. Make sure the bridge above is running first. read the bridge protocol →
Build "Call Sheet Announcer" as a ONE-SHOT Lovable build **from a phone**. The participant
has only 5 credits and only a mobile browser — this single message must ship a
working demo with zero follow-ups and zero laptop steps. Physical AI on Adamo.
CONCEPT
Lovable AI summarizes daily logistics so crews stay informed; the Adamo fleet dashboard shows every robot doing it at once.
Discipline: film-animation (production management).
Kernel: Publish (shareable artifact).
Why this kernel: A fleet dashboard matches production management because Filmmaking & Animation at scale is many bodies moving together — the operator needs to see which robots are online, what topics are flowing, and where attention should go, all in one glance.
MOBILE-ONLY, SANDBOX-BACKED — READ THIS FIRST
Adamo's SDK is Python-only. Cloudflare Workers cannot import it. The
participant is on a phone; there is no laptop bridge. The ONLY place inside
this Lovable session where the SDK runs is the Linux build sandbox. So:
- Every Adamo call happens in a Python script the agent runs ONCE at
build time in the sandbox.
- The script writes a JSON proof artifact into `public/` that the
deployed mobile web app fetches at runtime.
- The deployed app itself never imports adamo, never holds
ADAMO_API_KEY, never opens a QUIC/Zenoh socket, never calls a
server function that tries to.
- The runtime robot performance happens later at the physical showcase,
off-device. The mobile app AUTHORS, the sandbox VERIFIES, the operator
PLAYS BACK.
SECRETS
Request `ADAMO_API_KEY` via the add-secret tool (format hint `ak_...`).
Never reference it in .ts/.tsx code, never in `import.meta.env`, never in
a `createServerFn` handler. It lives only in the sandbox process env.
BUDGET (5 CREDITS, ONE-SHOT)
- ONE TanStack Start app, one primary route (`src/routes/index.tsx`).
- ONE mobile-first surface (touch targets >=44px, thumb-reachable primary
action, no hover-only affordances, no drag-only interactions).
- Lovable AI Gateway allowed for text (default `google/gemini-3-flash-preview`),
called from a server fn.
- NO database, NO auth, NO Lovable Cloud, NO extra pages, NO tests.
- Libraries: template defaults + `ai` + `@ai-sdk/openai-compatible` + `zod`.
VERIFIED ADAMO SDK SURFACE (adamo >= 0.4.42)
import adamo
session = adamo.connect(api_key=os.environ["ADAMO_API_KEY"])
session.put(key, payload_bytes)
sub = session.subscribe(key, callback=fn) # kwarg-only, NOT positional
session.get(key, timeout_ms=5000) # returns list[Sample]
session.live_tokens("**/alive") # discovery (returns live tokens)
session.alive(token_key) # DECLARES a token; not discovery
session.close()
Footguns: subscribe callback is kwarg-only; `alive()` declares, `live_tokens`
discovers; `connect` requires `api_key=` (keyword).
STEP 1 — SMOKE TEST (mandatory, every build)
Write this to `scripts/adamo_smoke.py` verbatim:
```python
"""Verify ADAMO_API_KEY from the Lovable sandbox and write proof to
public/adamo-smoke.json. Run once during the build."""
from __future__ import annotations
import json, os, sys, time, threading
from datetime import datetime, timezone
from pathlib import Path
OUT = Path(__file__).resolve().parent.parent / "public" / "adamo-smoke.json"
OUT.parent.mkdir(parents=True, exist_ok=True)
def write(p): OUT.write_text(json.dumps(p, indent=2) + "\n"); print(json.dumps(p))
def main() -> int:
key = os.environ.get("ADAMO_API_KEY")
if not key:
write({"ok": False, "error": "ADAMO_API_KEY missing"}); return 2
try:
import adamo
except Exception as e:
write({"ok": False, "error": f"adamo import failed: {e!r}"}); return 2
out = {"ok": False, "at": datetime.now(timezone.utc).isoformat(),
"sdk_version": getattr(adamo, "__version__", "unknown"),
"roundtrip_ms": None, "alive": [], "error": None}
s = None
try:
t0 = time.time()
s = adamo.connect(api_key=key)
out["connect_ms"] = int((time.time() - t0) * 1000)
k = f"lovable/smoke/{int(time.time()*1000)}"
got = threading.Event(); seen = {}
def on(sample):
try: seen["v"] = json.loads(bytes(sample.payload).decode())
except Exception: seen["v"] = None
got.set()
sub = s.subscribe(k, callback=on)
time.sleep(0.2)
sent = time.time()
s.put(k, json.dumps({"ping": sent}).encode())
if got.wait(3.0):
out["roundtrip_ms"] = int((time.time() - sent) * 1000)
out["ok"] = True; out["echo"] = seen.get("v")
else:
out["error"] = "roundtrip timeout"
try: sub.undeclare()
except Exception: pass
try: out["alive"] = sorted({str(t) for t in (s.live_tokens("**/alive") or [])})
except Exception as e: out["alive_error"] = repr(e)
except Exception as e:
out["error"] = f"{type(e).__name__}: {e}"
finally:
try:
if s is not None: s.close()
except Exception: pass
write(out)
return 0 if out["ok"] else 1
if __name__ == "__main__":
sys.exit(main())
```
Then in the sandbox run:
python -m pip install --no-cache-dir adamo
python scripts/adamo_smoke.py
Commit the resulting `public/adamo-smoke.json`.
STEP 2 — KERNEL JOB (Publish)
SANDBOX JOB — scripts/adamo_publish.py
After the smoke test succeeds, write a second script that:
1. Connects to Adamo like the smoke test.
2. Reads the authored artifact from `public/program.json`.
3. Validates every key by calling `session.put(f"publish/film-animation-call-sheet-announcer-19/N", ...)`
for each step N and confirming a `session.get(...)` echo returns
within 500 ms.
4. Writes `public/adamo-publish.json` with { ok, key_prefix, steps, at }.
The mobile app renders that JSON as a "ready to hand to an operator" card
with a copy-URL button. No live robot required at build time.
STEP 3 — MOBILE APP
- `src/routes/index.tsx` renders the Publish surface for "Call Sheet Announcer".
- Include an `<AdamoProof />` card that `fetch("/adamo-smoke.json")` on
mount and shows: "Sandbox verified at HH:MM · Xms roundtrip · N tokens
live". Empty state: "No proof yet — re-run scripts/adamo_smoke.py".
- Mobile-first layout: single column, 16-24px padding, primary CTA fixed
or bottom-anchored within thumb reach. NO desktop-only grids as the
main surface.
- Empty state copy when no robot is connected: "Your key is verified in
the sandbox. The operator will replay this on the robot at the
showcase." — never "start the bridge" or "install Python".
- Tailwind + shadcn. Editorial industrial look: gold accent, dark
background, one strong headline, one primary action.
- Footer: "Built during the Physical AI & Creative Robotics Hackathon
organised by StreetKode Fam during Indian Krump Festival 14".
BRAIN — Lovable AI Gateway (already provisioned, no key prompt)
```ts
// src/lib/ai-gateway.server.ts
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
export function gateway() {
return createOpenAICompatible({
name: "lovable",
baseURL: "https://ai.gateway.lovable.dev/v1",
headers: {
"Lovable-API-Key": process.env.LOVABLE_API_KEY!,
"X-Lovable-AIG-SDK": "vercel-ai-sdk",
},
});
}
```
Call `generateText` inside `createServerFn` handlers only.
DO / DON'T
| Do | Don't |
| ----------------------------------------------- | ---------------------------------------------- |
| Run adamo only in scripts/ (sandbox) | `import adamo` from a server fn or route |
| Read `/adamo-smoke.json` from the browser | Read ADAMO_API_KEY from `import.meta.env` |
| `session.subscribe(k, callback=fn)` | `session.subscribe(k, fn)` (positional fails) |
| `session.live_tokens("**/alive")` for discovery | `session.alive()` for discovery |
| Design for a phone in portrait first | Ship a desktop dashboard as the primary UI |
SUCCESS
On first load on a phone, the participant sees the Publish surface for
"Call Sheet Announcer", the AdamoProof card shows a green "sandbox verified" line with
a real roundtrip number, and the primary action is reachable with the
thumb. That is the demo.
Market sizing.
Indicative figures for hackathon pitches — refine with your own research before raising.