Jacuzzi is a local Jac web app for provisioning test Claw workspaces on this server and pairing a laptop and phone into the same shared session.
Right now it is still a local demo. The admin section can provision a dedicated workspace under .runtime/claws/ with test inputs like soul.md, and the laptop can create a local shared session, render a QR code from the configured phone access URL, and let a phone open /pair/<token>. Both sides read and update the same backend session record.
- Jacuzzi can inspect, start, and stop the singleton local OpenClaw gateway on this Mac.
- The laptop dashboard can create a new shared session.
- The admin dashboard can provision and delete test Claw workspaces on this server.
- Provisioning now confirms the shared OpenClaw host is running before a workspace is created.
- Test inputs are written to a dedicated workspace under
.runtime/claws/<slug>-<id>/. - The pair URL and token can be copied from the browser.
- The QR code is generated from the configured phone access URL for the phone to scan.
- The phone page can join or decline the laptop session.
- The laptop and phone presence are tracked on the same session record.
- Shared session state is persisted in Jac graph storage under
.jac/.
- No PWA manifest, service worker, or install behavior.
- No per-workspace OpenClaw runtime is started. Every provisioned workspace still shares one local gateway host.
- No OpenClaw session management beyond local pairing state and shared host lifecycle.
- No auth, accounts, or hosted multi-user control plane.
- No live push updates. The desktop reflects changes on reload or refresh.
A native phone app is not justified yet. The current backend only supports local pairing state, not durable device identity or OpenClaw session management. See docs/native-app-decision.md for the audit, the backend gaps, and the threshold to revisit Expo later.
If jac is already on your PATH:
jac install
jac start main.jacIf it is not:
uv tool run --from jaclang jac install
uv tool run --from jaclang jac start main.jacOpen http://localhost:8000/ for the desktop dashboard.
For a real phone scan, either open the dashboard on the laptop's LAN URL or fill in Phone access URL with that LAN origin first. A QR generated from localhost or 127.0.0.1 will not work on a physical phone.
Use the repo script when you want the quickest path to a local test run:
./scripts/start-local.shOr through npm:
npm run local:startWhat it does:
- loads
.envif present - clears local Jac demo data unless you pass
--keep-state - defaults
DEEPSEEK_MODELtodeepseek-chatwhen a DeepSeek key exists - installs
node_modulesif needed - picks a free port starting at
8000 - starts the local demo host with the correct port already selected
You can also request a different starting port:
./scripts/start-local.sh 8100If you want to keep the current local state instead of starting fresh:
./scripts/start-local.sh --keep-stateThe current demo plan is to use one machine as the only host and have the phone reach that same host over a real network URL. For the fastest live demo, use the laptop as the host if the phone can share Wi-Fi with it.
npm run demo:startThat script starts Jacuzzi on port 8000 and prints the detected LAN URLs to open from another browser or phone. The single-host demo goal is written down in docs/demo-host-plan.md.
If you are running the demo from the laptop instead, use docs/laptop-demo-checklist.md. That is the current best path for a phone-on-same-Wi-Fi demo.
Provisioned Claw workspaces can only answer if the host has a real provider configured.
Fastest path:
export OPENAI_API_KEY=...
export OPENAI_MODEL=gpt-5.4-mini
npm run demo:startAlternative hosted path:
export DEEPSEEK_API_KEY=...
export DEEPSEEK_MODEL=deepseek-chat
npm run demo:startOptional local path later:
export OLLAMA_HOST=http://127.0.0.1:11434
export OLLAMA_MODEL=<installed-model>
npm run demo:startWithout one of those provider setups, the Claw admin panel will provision workspaces but the chat panel will show a provider-missing error instead of pretending to answer.
Playwright covers the real laptop-phone shared-session flow in tests/e2e/shared-session.spec.js.
It also covers the admin create/delete flow in tests/e2e/claw-admin.spec.js.
npm install
npm run test:e2e:install
npm run test:e2eThe test server boots Jacuzzi through uv tool run --from jaclang jac start, uses a dedicated test port, and clears .jac/data/*.db* before each run so the browser flows start from a clean local state.
If Railway cannot infer a build plan for this repo, it can deploy through the included Dockerfile.
After pushing the repo:
railway upOr redeploy from the Railway UI after the new commit lands. The container runs:
uv tool run --from jaclang jac start main.jac --port $PORT/renders the laptop dashboard./pair/<token>renders the phone join page.- The provisioning backend is exposed through
def:pubfunctions such ascreate_claw_instance,get_claw_instance,get_claw_instances, anddelete_claw_instance. - The pairing backend is exposed through
def:pubfunctions such ascreate_pairing_session,get_pairing_session,get_pairing_sessions,touch_host_session,mark_pairing_opened,approve_pairing_session, andreject_pairing_session.