diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml
deleted file mode 100644
index 6cd9237..0000000
--- a/.github/workflows/fly-deploy.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-name: Deploy Fly API
-
-on:
- push:
- branches: [main]
- paths:
- - 'fly.toml'
- - 'Dockerfile.fly'
- - '.dockerignore'
- - 'interview-app/**'
- - '.github/workflows/fly-deploy.yml'
- workflow_dispatch:
-
-permissions:
- contents: read
-
-concurrency:
- group: fly-main
- cancel-in-progress: true
-
-jobs:
- deploy:
- name: Deploy interview-app to Fly
- runs-on: ubuntu-latest
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
- FLY_APP_NAME: ${{ vars.FLY_APP_NAME }}
- FLY_PRIMARY_REGION: ${{ vars.FLY_PRIMARY_REGION }}
- FLY_VOLUME_NAME: ${{ vars.FLY_VOLUME_NAME }}
- FLY_VOLUME_SIZE_GB: ${{ vars.FLY_VOLUME_SIZE_GB }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Setup flyctl
- uses: superfly/flyctl-actions/setup-flyctl@master
-
- - name: Deploy
- run: |
- if [ -z "${FLY_API_TOKEN}" ]; then
- echo "Missing FLY_API_TOKEN repository secret."
- echo "Add it in GitHub: Settings -> Secrets and variables -> Actions -> New repository secret."
- exit 1
- fi
-
- APP_FROM_CONFIG="$(awk -F'\"' '/^app[[:space:]]*=/ { print $2; exit }' fly.toml)"
- APP_NAME="${APP_FROM_CONFIG:-${FLY_APP_NAME}}"
- PRIMARY_REGION="${FLY_PRIMARY_REGION:-ord}"
- VOLUME_NAME="${FLY_VOLUME_NAME:-yappybara_data}"
- VOLUME_SIZE_GB="${FLY_VOLUME_SIZE_GB:-1}"
-
- if [ -z "${APP_NAME}" ]; then
- echo "Unable to determine Fly app name."
- echo "Set repository variable FLY_APP_NAME or app = \"...\" in fly.toml."
- exit 1
- fi
-
- if [ -n "${APP_FROM_CONFIG}" ] && [ -n "${FLY_APP_NAME}" ] && [ "${APP_FROM_CONFIG}" != "${FLY_APP_NAME}" ]; then
- echo "Ignoring stale FLY_APP_NAME='${FLY_APP_NAME}' and using fly.toml app '${APP_FROM_CONFIG}'."
- fi
-
- APP_INFO_OUTPUT="$(flyctl status --app "${APP_NAME}" 2>&1 || true)"
- if ! echo "${APP_INFO_OUTPUT}" | grep -q "App"; then
- if echo "${APP_INFO_OUTPUT}" | grep -qi "app not found"; then
- echo "Fly app ${APP_NAME} does not exist yet. Creating it now..."
- flyctl apps create "${APP_NAME}"
- else
- echo "${APP_INFO_OUTPUT}"
- echo "Unable to access Fly app '${APP_NAME}'. Check that FLY_API_TOKEN has deploy access to this app."
- exit 1
- fi
- fi
-
- if ! flyctl volumes list --app "${APP_NAME}" | grep -q "${VOLUME_NAME}"; then
- echo "Fly volume ${VOLUME_NAME} does not exist yet. Creating it now..."
- flyctl volumes create "${VOLUME_NAME}" \
- --yes \
- --app "${APP_NAME}" \
- --region "${PRIMARY_REGION}" \
- --size "${VOLUME_SIZE_GB}"
- fi
-
- echo "Deploying to Fly app: ${APP_NAME}"
- flyctl deploy \
- --remote-only \
- --app "${APP_NAME}" \
- --config fly.toml
diff --git a/.gitignore b/.gitignore
index f4c41c3..b6c44b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -72,8 +72,6 @@ interview-app/last-fix.md
interview-app/build-summary.md
interview-app/builds/
interview-app/public/builds/
-interview-app/fly.toml
-interview-app/.fly/
# Feedback transcripts and archives (local working files)
feedback/*
diff --git a/CLAUDE.md b/CLAUDE.md
index 98c4419..3798e0f 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1,167 +1,50 @@
# CLAUDE.md
-
-
+## Project summary
-## What is this project?
+Yappybara is a local-first AI app ideation and prototyping workspace.
-Yappybara is a toolkit for helping kids (ages 9-14) design and build their first app using Claude Code. It includes a voice-powered interview app, sketch tools, and an automated build system. The app idea hasn't been captured yet — run `/idea-capture` with the interview transcript to fill this in.
+Primary path:
+- run `interview-app/` locally,
+- iterate on prompts/spec/prototype quickly,
+- keep infra cost near zero.
----
+This repo is intentionally aligned to:
+- no required Fly.io backend,
+- free GitHub Pages site in `site/`,
+- local persistence and local execution by default.
-## Voice Interview App
+## Core runtime
-The `interview-app/` directory contains a browser-based interview tool. It uses:
-- **Web Speech API** for speech-to-text and text-to-speech (runs in Chrome)
-- **Claude Agent SDK** for conversation (uses your Claude Max subscription, no API key needed)
-- **Built-in drawing tool** for sketching app ideas directly in the browser
+- `interview-app/server.js` — Express server + orchestration
+- `interview-app/public/index.html` — browser UI
+- `interview-app/builder.js` — prototype builder
+- `interview-app/mechanic.js` — patch/fix loop
+- `interview-app/safety.js` — response/preview sanitization
-To run: `make interview-setup` (once), then `make interview`
-
-No API key needed — uses your existing Claude Code auth. Sketches are saved to `docs/sketches/` automatically.
-
-## Media Safety Rules
-
-- NEVER attempt to read audio or video files (`.wav`, `.mp3`, `.m4a`, `.mp4`, `.mov`, etc.)
-- Audio is handled by the browser's Web Speech API; Claude only ever sees text
-- The `/sketch` skill can read images (photos of drawings) — images are allowed
-- Sketches from the interview app are saved to `docs/sketches/`
-
----
-
-## Important Context for Claude
-
-**The creator is a kid (ages 9-14) and very intelligent.** When explaining things:
-- Use clear, direct language - no corporate jargon or hand-waving
-- It's okay to use real technical terms, but explain them the first time ("a *component* is a reusable piece of UI, like a building block")
-- Be encouraging and enthusiastic about their ideas
-- When there are choices to make, present 2-3 options with honest trade-offs
-- Default to the simplest approach that works
-- Ask "does that make sense?" and actually mean it
-
-**A parent or mentor is always present** during Claude interactions. They can help with:
-- Account setup (App Store, hosting, etc.)
-- Approving any spending or cloud resources
-- Git operations and deployment
-- Answering questions about the real world
-
-**The goal:** Show that a kid with a good idea and AI tools can build something real that helps people. Ship fast, learn by doing, iterate based on feedback.
-
----
-
-## Tech Stack
-
-
-
-| Layer | Choice | Notes |
-|-------|--------|-------|
-| **App Framework** | Expo (React Native) | One codebase for iOS, Android, and web |
-| **Language** | TypeScript + React | Industry standard, tons of learning resources |
-| **Backend** | Supabase | Free tier: database, auth, file storage, real-time |
-| **Hosting (web)** | Vercel | Free tier for the web version |
-| **Mobile builds** | EAS Build | Free tier for iOS/Android builds |
-| **CI/CD** | GitHub Actions | Auto-test on every push |
-
-**Why these choices:**
-- **Expo** handles iOS + Android + Web from one codebase. No need to learn Swift AND Kotlin AND React separately.
-- **Supabase** has a generous free tier (500MB database, 1GB file storage, 50K monthly active users). That's plenty to launch and get real users.
-- **Vercel** hosts the web version for free.
-- **Total cost to launch: $0.** Costs only start if the app gets thousands of users (a good problem to have).
-
----
-
-## Project Structure
-
-```
-interview-app/ # Voice interview tool (browser-based)
- server.js # Express server + Anthropic API
- public/index.html # Chat UI with speech + drawing
- uploads/ # Uploaded sketch photos
-app/ # Expo app (screens, components, navigation)
- (tabs)/ # Tab-based navigation screens
- components/ # Reusable UI components
- lib/ # Utilities, API client, helpers
- assets/ # Images, fonts, icons
-docs/
- sketches/ # Processed sketch specs (from interview + /sketch)
- BUILD-PLAN.md # Phased build plan
-feedback/ # Saved interview transcripts
-supabase/ # Database migrations and config
-CLAUDE.md # This file
-INTERVIEW.md # Interview script
-README.md # Project docs
-```
-
----
-
-## Development Commands
-
-```bash
-# Run the voice interview (first time: make interview-setup)
-make interview
-
-# Start the app in development mode (opens in browser + Expo Go on phone)
-make dev
-
-# Run tests
-make test
-
-# Build for web
-make build-web
-
-# Create a preview build for phone testing
-make build-preview
-
-# Check for problems
-make lint
-```
-
----
-
-## Database Tables
-
-
-
----
-
-## Environment Variables
+## Local commands
```bash
-# Supabase (get these from supabase.com dashboard)
-EXPO_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
-EXPO_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
+make interview-setup
+make interview # Claude-enabled mode
+make interview-demo # local-only mode
+make interview-test
```
----
-
-## Screens
-
-
-
----
-
-## Roadmap
+## Safety + constraints
-### Done
-- [x] Project template ready
-- [ ] Interview completed
-- [ ] Sketches processed
-- [ ] Plan created
+- Never read raw audio/video blobs in tooling flows.
+- Treat user/project files as local-first and avoid adding remote dependencies unless explicitly requested.
+- Prefer deterministic edits and test-backed changes.
-### Phase 1: Get it running
-- [ ] Create Expo project
-- [ ] Set up navigation
-- [ ] Build home screen
+## Public site
-### Phase 2: Core features
-- [ ]
+- `site/` is deployed by `.github/workflows/pages.yml`
+- custom domain target: `yappybara.dev`
+- DNS automation script: `scripts/configure-namecheap-github-pages.mjs`
-### Phase 3: Make it look great
-- [ ] Apply design from sketches
-- [ ] Add animations
-- [ ] Test on real phone
+## Release posture
-### Phase 4: Share it with the world
-- [ ] Deploy web version
-- [ ] Build for iOS/Android
-- [ ] Share with friends for feedback
+- MIT licensed
+- CI test workflow in `.github/workflows/ci.yml`
+- keep docs and workflows aligned with local-first + free-hosting strategy
diff --git a/Dockerfile.fly b/Dockerfile.fly
deleted file mode 100644
index de4e910..0000000
--- a/Dockerfile.fly
+++ /dev/null
@@ -1,21 +0,0 @@
-FROM node:22-slim
-
-WORKDIR /app
-
-ENV NODE_ENV=production
-
-COPY interview-app/package*.json ./
-RUN npm ci --omit=dev && npm cache clean --force
-
-COPY interview-app/ ./
-
-RUN mkdir -p /data
-
-ENV PORT=8080
-ENV YAPPY_STORAGE_DIR=/data
-ENV FORCE_HTTP=true
-ENV AUTO_GENERATE_CERTS=false
-
-EXPOSE 8080
-
-CMD ["node", "server.js"]
diff --git a/Makefile b/Makefile
index 18a5e5d..e95aef6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
# App Makefile
# These commands will work once the Expo project is created
-.PHONY: dev test build build-web build-preview lint clean setup help interview interview-demo interview-setup interview-test feedback restart resume yappybara-install yappybara-install-plugin yappybara-launch deploy-queue
+.PHONY: dev test build build-web build-preview lint clean setup help interview interview-demo interview-setup interview-test feedback restart resume yappybara-install yappybara-install-plugin yappybara-launch
help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
@@ -75,7 +75,7 @@ interview: ## Start the voice interview app (uses Claude Max subscription)
interview-demo: ## Start kid-safe demo mode (no Claude login required)
@cd interview-app && YAPPY_MODE=demo node server.js
-yappybara-install: ## One-command local install for families (set YAPPY_INSTALL_PLUGIN=1 to add Claude plugin)
+yappybara-install: ## One-command local install (set YAPPY_INSTALL_PLUGIN=1 to add Claude plugin)
@if [ "$${YAPPY_INSTALL_PLUGIN:-0}" = "1" ]; then \
./scripts/install-yappybara.sh --with-plugin; \
else \
@@ -85,12 +85,5 @@ yappybara-install: ## One-command local install for families (set YAPPY_INSTALL_
yappybara-install-plugin: ## Install Yappybara Claude plugin from this repo marketplace
@./scripts/install-claude-plugin.sh
-yappybara-launch: ## Fast launcher for kid-safe demo mode
+yappybara-launch: ## Fast launcher for local demo mode
@$(MAKE) interview-demo
-
-deploy-queue: ## Show recent parent deploy requests captured locally
- @if [ -f interview-app/data/deploy-requests.jsonl ]; then \
- tail -n 20 interview-app/data/deploy-requests.jsonl; \
- else \
- echo "No deploy requests yet."; \
- fi
diff --git a/README.md b/README.md
index e114d22..36fa269 100644
--- a/README.md
+++ b/README.md
@@ -2,240 +2,98 @@

-A toolkit for helping kids build their first app with AI. Yappybara guides a young creator through an interview about their app idea, then builds a working prototype — all through a friendly voice conversation with a capybara named Bart.
+Yappybara is a local-first AI app ideation and prototyping workspace.
-## What It Does
+It gives you a fast loop:
+1. chat through an app idea,
+2. shape the spec,
+3. generate a working prototype,
+4. iterate.
-1. **Interview** — Bart (a goofy capybara) chats with your kid about their app idea using voice or text. No tech jargon, just a fun conversation about what they want to build.
-2. **Sketch** — A built-in drawing tool lets them sketch their ideas right in the browser, or upload photos of paper sketches.
-3. **Build** — When Bart understands the idea, Dash (another capybara) automatically builds a working HTML prototype they can see and play with.
-4. **Fix** — A "fix this!" panic button lets the kid report problems, and Wrench (the mechanic capybara) patches things up.
+## Positioning
-The whole experience is designed to feel like chatting with a friend, not using a developer tool.
+- Engineer-focused
+- Local-first
+- Free to use locally
+- No required hosted backend
-## Parent Supervision And Legal Notice
+This repository intentionally does **not** depend on Fly.io or a paid hosted API layer for the core workflow.
-- Yappybara is an AI-assisted educational tool and should be used only with active parent/guardian supervision.
-- AI output can be wrong, incomplete, or occasionally inappropriate even with filters in place.
-- Do not enter sensitive personal data (full names, addresses, phone numbers, passwords, financial, medical, or legal details).
-- Yappybara is not a medical, legal, financial, or emergency service.
-- Foundational model providers also require policy/terms compliance for age and safety:
- - Anthropic Consumer Terms: https://www.anthropic.com/legal/consumer-terms
- - Anthropic Usage Policy: https://www.anthropic.com/legal/aup
- - OpenAI Terms of Use: https://openai.com/policies/terms-of-use/
+## Why this is cheap
-## Prerequisites
-
-- [Node.js](https://nodejs.org/) 18+
-- Optional for full AI mode: a [Claude Max subscription](https://claude.ai/) (or Claude Code/API access)
-- Chrome (for voice features via Web Speech API)
+- `interview-app/` runs locally on your machine
+- Data stays in local files (`interview-app/data/`, `interview-app/apps.json`)
+- GitHub Pages hosts `site/` for free
+- Domain can be pointed with standard DNS records (no app hosting bill)
## Quick Start
```bash
-# Clone the repo
git clone https://github.com/obsecurus/yappybara.git
cd yappybara
-
-# Install dependencies
make interview-setup
-
-# Start the interview app
-make interview
-
-# OR: zero-login demo mode (best for first-time kid sessions)
make interview-demo
```
-Open the URL shown in your terminal (usually `http://localhost:3456`). Your kid can talk or type to Bart, draw sketches, and watch their app idea come to life.
-
-`make interview-demo` runs local practice mode and does not require Claude auth. It is ideal for quick setup and classrooms.
-
-### One-command Family Install
-
-```bash
-# Install everything for local sessions
-make yappybara-install
-
-# Optional: also install the Claude Code plugin from this repo
-YAPPY_INSTALL_PLUGIN=1 make yappybara-install
-
-# Launch kid-safe mode
-make yappybara-launch
-```
-
-### Assistant modes
-
-- `YAPPY_MODE=auto` (default): tries Claude first, then falls back to local practice mode if unavailable.
-- `YAPPY_MODE=claude`: requires Claude; returns an error if Claude is unavailable.
-- `YAPPY_MODE=demo`: local kid-safe mode only (no Claude required).
-
-### Billing modes (cost control)
-
-- `YAPPY_BILLING_MODE=subscription` (default): subscription-first mode. If `ANTHROPIC_API_KEY` is set, Yappybara ignores it to avoid accidental API charges.
-- `YAPPY_BILLING_MODE=api`: usage-based API billing (requires `ANTHROPIC_API_KEY`).
-- `YAPPY_BILLING_MODE=user_api`: parent BYOK mode. Server ignores its own API key and requires each family to provide their own key in-browser.
-- `YAPPY_BILLING_MODE=auto`: uses API billing when a key is present, otherwise Claude login/subscription.
-
-### Claude Code Plugin
-
-This repo ships a plugin marketplace and plugin package:
+Then open `http://localhost:3456`.
-```bash
-make yappybara-install-plugin
-```
-
-Manual commands:
+For full Claude-backed mode:
```bash
-claude plugins marketplaces add https://raw.githubusercontent.com/Obsecurus/yappybara/main/.claude-plugin/marketplace.json
-claude plugins install yappybara-family-kit
+make interview
```
-### Accessing from another device
-
-The server prints a LAN URL and QR code on startup. The app now auto-generates local HTTPS certs in dev mode when needed, so voice input can work from another device on the same network.
-
-
-HTTPS details (optional)
+## Runtime modes
-Voice input (microphone) requires HTTPS when accessing from another device. On startup, `interview-app/server.js` will try to generate `interview-app/certs/cert.pem` and `interview-app/certs/key.pem` automatically in non-production mode.
+- `YAPPY_MODE=auto` (default): Claude first, fallback to local demo
+- `YAPPY_MODE=claude`: require Claude
+- `YAPPY_MODE=demo`: local-only demo mode
-If you want to force HTTP for local testing, run with:
+## Main commands
```bash
-AUTO_GENERATE_CERTS=false make interview
+make interview-setup # install interview-app dependencies
+make interview # start full mode (Claude)
+make interview-demo # start local-only mode
+make interview-test # run interview-app tests
```
-Or disable HTTPS explicitly:
+## GitHub Pages (`yappybara.dev`)
-```bash
-FORCE_HTTP=true make interview
-```
-
-
-## Website (GitHub Pages)
-
-This repo includes a cheap static website in `site/` for `https://yappybara.dev`.
-
-- `site/` is a browser-only \"Yappybara Lite\" interview demo.
-- `interview-app/` is the full backend-powered experience (Claude integration + prototype builder).
-
-Deploy docs: `docs/github-pages.md`
-Distribution docs: `docs/distribution.md`
-Fly API rollout docs: `docs/fly-api-rollout.md`
-Fly CI deploy workflow: `.github/workflows/fly-deploy.yml`
-Fly config: `fly.toml`
-Family launch docs: `docs/family-launch.md`
-Deploy queue docs: `docs/deploy-queue.md`
-Legal/supervision docs: `docs/legal-supervision.md`
+The public site is in `site/` and deploys via `.github/workflows/pages.yml`.
-Branding assets/docs: `assets/brand/` and `docs/branding.md`
+Setup guide:
+- `docs/github-pages.md`
-## How the Interview Works
+## Namecheap DNS automation
-Bart follows a natural conversation flow:
-- **What's the idea?** What problem does it solve?
-- **Who's it for?** Friends, family, everyone?
-- **Walk me through it** — What do you see when you open the app?
-- **What's the vibe?** Colors, style, inspiration?
-- **What makes it special?** Why would someone use this over alternatives?
-
-After a few minutes of chatting, Bart automatically triggers a build phase where Dash creates a working prototype. The kid gets to see their idea come to life in real time.
-
-## Parent/Mentor Tools
-
-While your kid is chatting with Bart, you can:
+Use the existing script to configure apex + `www` for GitHub Pages:
```bash
-# Send feedback without interrupting (e.g., "responses are too long")
-make feedback MSG="too verbose"
-
-# Restart the server transparently
-make restart
-
-# Resume from a previous session
-make resume
-
-# View recent deploy requests from parents
-make deploy-queue
+node scripts/configure-namecheap-github-pages.mjs
+node scripts/configure-namecheap-github-pages.mjs --apply
```
-There's also a structured interview script in `INTERVIEW.md` if you want to do an offline interview first and then feed the transcript to Claude.
+Required secrets are documented in `.env.secrets.example`.
-## Local Persistence + Deploy Queue
+## Repository layout
-- Project data is persisted in:
- - `interview-app/apps.json`
- - `interview-app/data/apps/*.json` (per-app local vault backup)
-- Parent "Deploy Your App" requests are logged locally in:
- - `interview-app/data/deploy-requests.jsonl`
-- Deploy requests are intentionally queued for manual fulfillment (domain + Fly.io + payment confirmation).
-
-## Project Structure
-
-```
-interview-app/ # The voice interview + builder app
- server.js # Express server + Claude Agent SDK
- safety.js # Shared kid-safety sanitizers/filters
- builder.js # "Dash" — builds HTML prototypes
- mechanic.js # "Wrench" — auto-fixes bugs
- public/index.html # Chat UI with speech + drawing
- data/ # Local persistence vault + deploy queue
- run.sh # Auto-restart wrapper
-plugins/ # Claude Code plugin packages
- yappybara-family-kit/ # Commands + skills for family sessions
-.claude-plugin/ # Plugin marketplace manifest
-CLAUDE.md # Project context for Claude Code
-INTERVIEW.md # Offline interview script
-Makefile # Dev commands
-.claude/ # Local private Claude workflows (excluded from git)
-.devcontainer/ # VS Code dev container (optional)
-.github/workflows/ci.yml # CI pipeline for interview app checks/tests
-.github/workflows/pages.yml # GitHub Pages deployment workflow
-site/ # Static website for yappybara.dev
-assets/brand/ # Logo files for GitHub/website branding
+```text
+interview-app/ # local app server + UI
+site/ # static marketing/docs site for GitHub Pages
+scripts/ # setup + DNS helper scripts
+.github/workflows/ # CI + Pages deploy workflow
+assets/brand/ # logo assets
```
-## The Capybara Crew
-
-| Character | Role | Personality |
-|-----------|------|-------------|
-| **Bart** | Interviewer | Goofy, enthusiastic hype-buddy. Asks about the idea, never about tech. |
-| **Dash** | Builder | Hyperactive speedster with headphones. Builds prototypes fast. |
-| **Wrench** | Mechanic | Calm fixer with goggles. Patches bugs when the kid hits "fix this!" |
-
-## Building the Actual App
-
-Once the interview captures the idea, you can build a real app in the Expo workspace:
+## Tests
```bash
-make setup # Create the Expo project (one-time)
-make dev # Start development
+cd interview-app
+node --check server.js builder.js mechanic.js safety.js
+AUTO_GENERATE_CERTS=false node --test test.js
```
-Private/internal Claude skill packs are intentionally kept out of this public repo.
-
-## Default Tech Stack
-
-| Layer | Tool | Cost |
-|-------|------|------|
-| App framework | Expo (React Native) | Free |
-| Database + Auth | Supabase | Free tier |
-| Web hosting | Vercel | Free tier |
-| Phone builds | EAS Build | Free tier |
-
-**Total cost to launch: $0.** Works on iPhone, Android, and web from a single codebase.
-
-## Safety
-
-Yappybara is built for kids (ages 9-14):
-- All AI responses are filtered for age-appropriate content
-- External images are blocked in generated prototypes (emoji and CSS art only)
-- Content Security Policy headers prevent loading external resources
-- Demo mode runs locally with no model-provider calls
-- Claude mode sends prompts/responses to Anthropic per their terms and policies
-
## License
MIT
diff --git a/assets/brand/yappybara-lockup.svg b/assets/brand/yappybara-lockup.svg
index 0ddade7..b6b3c39 100644
--- a/assets/brand/yappybara-lockup.svg
+++ b/assets/brand/yappybara-lockup.svg
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:6c7e4d32ad8e087bd8985b2e7d5f5d2411c807a82dd4fe5101895c35c72d686e
-size 2095
+oid sha256:9a475b588bf3bca317f662d1630f4479e9e09418dd48f4012d5090597d727f71
+size 2092
diff --git a/docs/deploy-queue.md b/docs/deploy-queue.md
deleted file mode 100644
index 6256e27..0000000
--- a/docs/deploy-queue.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Deploy Queue (Parent Requests)
-
-Yappybara captures deployment interest locally so families can request publishing from inside the app.
-
-## What happens in app
-
-1. Kid builds a prototype.
-2. Parent clicks **Deploy Your App**.
-3. Parent enters email, optional name, desired subdomain, and notes.
-4. Request is saved locally and attached to that app record.
-
-## Stored files
-
-- Queue log: `interview-app/data/deploy-requests.jsonl`
-- App metadata: `interview-app/apps.json`
-- Per-app backup: `interview-app/data/apps/.json`
-
-## API endpoints
-
-- `POST /api/deploy-request`
-- `GET /api/deploy-requests?limit=25`
-
-## Environment knobs
-
-- `YAPPY_DEPLOY_DOMAIN` (default: `yappybara.dev`)
-- `YAPPY_DEPLOY_PRICE_USD` (default: `5`)
-- `YAPPY_STORAGE_DIR` (set `/data` on Fly to persist queue/build artifacts)
-
-## Ops workflow (manual for now)
-
-1. Review queue with `make deploy-queue`.
-2. Confirm payment and parent contact.
-3. Set up subdomain and cert.
-4. Deploy app artifact to Fly.io.
-5. Mark request complete in your internal tracking.
diff --git a/docs/distribution.md b/docs/distribution.md
deleted file mode 100644
index d22fb2f..0000000
--- a/docs/distribution.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# Distribution Plan (Low Friction + Monetizable)
-
-Goal: kids can play instantly, non-technical parents do not need local setup, and you can monetize publishing.
-
-## Recommended architecture
-
-1. GitHub Pages (`site/`) for discovery and lightweight browser demo.
-2. Hosted Fly app (`interview-app/`) for full experience (`play.yappybara.dev` style URL).
-3. Optional local launcher for power users (`make interview`, plugin flows).
-
-## Why this is the best fit
-
-- GitHub Pages is static-only and cannot run your Node API.
-- Fly can run the full app + API and persist queue/build files via volumes.
-- You can keep one low-cost shared runtime, then charge for “deploy my kid’s app” fulfillment.
-
-## Product tiers to ship
-
-### Tier 1: Instant demo (free)
-
-- URL: `https://yappybara.dev`
-- Static demo only, no account friction.
-
-### Tier 2: Hosted builder (paid Claude usage behind your backend)
-
-- URL: `https://play.yappybara.dev` (Fly)
-- Full interview/build flow via hosted API.
-- Best for non-technical families.
-
-### Tier 3: Deploy request (parent upsell)
-
-- In-app button: `Deploy Your App`.
-- Captures parent contact + requested domain.
-- Queue processed by you (manual first, automated later).
-
-## Safety defaults
-
-- Parent supervision gate before interaction.
-- Strict server/client sanitizers.
-- One-tap panic + feedback.
-- Regression tests for:
- - profanity/slur filtering
- - one-question/short-response constraints
- - unsafe HTML stripping
-
-## Rollout
-
-1. Launch hosted Fly API/app first.
-2. Keep plugin/installer as optional power-user paths.
-3. Add payment + deploy automation once hosted traffic is stable.
-
-See: `docs/fly-api-rollout.md`
diff --git a/docs/family-launch.md b/docs/family-launch.md
deleted file mode 100644
index 818c26c..0000000
--- a/docs/family-launch.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# Family Launch Guide
-
-This guide is the fastest path to get kids playing with Yappybara on a local network.
-
-Legal and supervision reference: `docs/legal-supervision.md`
-
-## 1) Install in one command
-
-```bash
-make yappybara-install
-```
-
-Optional plugin install in same step:
-
-```bash
-YAPPY_INSTALL_PLUGIN=1 make yappybara-install
-```
-
-## 2) Start a kid-safe session
-
-```bash
-make yappybara-launch
-```
-
-This runs demo mode (no Claude login required) so first sessions start quickly.
-
-## 3) Switch to full Claude mode when ready
-
-```bash
-make interview
-```
-
-Default billing behavior is subscription-first (`YAPPY_BILLING_MODE=subscription`), so accidental API-key charges are avoided unless explicitly enabled.
-
-## 4) Use the website as front door
-
-- Public link: `https://yappybara.dev` (GitHub Pages)
-- Pages offers an instant lightweight demo
-- Full voice + build experience stays local in `interview-app/`
-
-## 5) Publish app requests from parents
-
-After a prototype is built, parents can use **Deploy Your App** in the app tab.
-
-- Requests are stored locally in `interview-app/data/deploy-requests.jsonl`
-- Review queue:
-
-```bash
-make deploy-queue
-```
-
-- Fulfillment is currently manual: payment confirmation, subdomain setup, and Fly.io deploy.
diff --git a/docs/fly-api-rollout.md b/docs/fly-api-rollout.md
deleted file mode 100644
index 2a02314..0000000
--- a/docs/fly-api-rollout.md
+++ /dev/null
@@ -1,130 +0,0 @@
-# Fly.io API Rollout (Non-Technical Parent Friendly)
-
-This is the path to move Yappybara from local-only to a hosted service parents can use with one URL.
-
-## Target architecture
-
-1. `yappybara.dev` (GitHub Pages): marketing + lite demo.
-2. `play.yappybara.dev` (Fly): full Yappybara web app + API from `interview-app/server.js`.
-3. `api` and UI stay same origin on Fly, so no browser CORS complexity.
-4. Persistent app state on Fly Volume via `YAPPY_STORAGE_DIR=/data`.
-
-## Why Fly works for this
-
-- Native app deployment and config (`fly deploy`, `fly.toml`): [Fly Launch](https://fly.io/docs/launch/), [App Config](https://fly.io/docs/reference/configuration/).
-- Persistent storage with volumes: [Fly Volumes](https://fly.io/docs/volumes/overview/).
-- Optional encrypted runtime secrets (only if you choose server-owned billing): [Fly Secrets](https://fly.io/docs/apps/secrets/).
-- Custom subdomains + certs: [Fly Custom Domains](https://fly.io/docs/networking/custom-domain/).
-- Pricing reference: [Fly Pricing](https://fly.io/docs/about/pricing/).
-
-## Repo artifacts added for hosting
-
-- `fly.toml` (repo root; used by Fly GitHub integration)
-- `Dockerfile.fly` (repo root; builds `interview-app/`)
-- `interview-app/Dockerfile` (subdir deploy option)
-- `interview-app/fly.toml.example` (reference config)
-- `interview-app/.dockerignore`
-- `YAPPY_STORAGE_DIR` support in `interview-app/server.js`
-
-## Day-1 hosted deploy
-
-Create app + volume (example region `ord`):
-
-```bash
-fly apps create yappybara-api
-fly volumes create yappybara_data --region ord --size 3
-```
-
-Set required runtime env:
-
-```bash
-fly secrets set YAPPY_MODE=claude \
- YAPPY_BILLING_MODE=user_api \
- YAPPY_DEPLOY_DOMAIN=yappybara.dev \
- YAPPY_DEPLOY_PRICE_USD=9
-```
-
-Deploy:
-
-```bash
-fly deploy --config fly.toml
-```
-
-Smoke test:
-
-```bash
-curl -s https://yappybara-api.fly.dev/api/health
-```
-
-## GitHub auto-deploy
-
-This repo includes `.github/workflows/fly-deploy.yml`.
-
-On every push to `main` that touches `interview-app/`, GitHub Actions runs:
-
-```bash
-flyctl deploy --remote-only --config fly.toml
-```
-
-Configure in GitHub:
-
-1. Add repository secret `FLY_API_TOKEN`.
-2. Optional: add repository variable `FLY_APP_NAME` if app name is not `yappybara-api`.
-3. Ensure Fly app + volume already exist before first workflow run.
-
-## Domain wiring
-
-1. Keep root/apex (`yappybara.dev`) on GitHub Pages.
-2. Add a new subdomain for full app (`play.yappybara.dev`) pointing to Fly.
-3. Run `fly certs add play.yappybara.dev`.
-4. Update `site/` CTA buttons to send parents to `https://play.yappybara.dev`.
-
-## Monetization path (deploy-your-app fee)
-
-Start simple, then automate:
-
-### Phase A: Manual charge + manual deploy (fastest launch)
-
-1. Parent submits `Deploy Your App`.
-2. You invoice manually or send payment link.
-3. After payment, you provision domain + deploy artifact.
-
-### Phase B: Payment-gated queue
-
-1. Add checkout flow (Stripe Payment Links or Checkout): [Stripe Payment Links](https://docs.stripe.com/payment-links).
-2. Store payment status on request (`pending` -> `paid`) via webhook: [Stripe Webhooks](https://docs.stripe.com/webhooks).
-3. Only allow fulfillment when status is `paid`.
-
-### Phase C: Automated fulfillment worker
-
-1. Worker polls paid requests.
-2. Publishes app artifact.
-3. Configures DNS/cert and marks request `live`.
-4. Sends parent completion email.
-
-## Suggested pricing model
-
-Use a simple margin formula per deployment:
-
-`price = fly_runtime_cost + model_cost + domain/dns_ops + support_buffer + margin`
-
-Practical launch strategy:
-
-1. Start with a fixed one-time deployment fee (`$9-$19`).
-2. Track real per-deploy costs for 2-4 weeks.
-3. Adjust price once your real margin is known.
-
-## Operational guardrails
-
-1. Keep one shared Fly app at first; do not create one Fly app per child yet.
-2. Persist all queue/build data to `/data` volume.
-3. Add rate limiting before public launch.
-4. Keep parent-supervision disclaimers visible in hosted UI.
-5. For `YAPPY_BILLING_MODE=user_api`, do not set a server Anthropic key; each family supplies their own key in browser.
-
-## Next technical increments
-
-1. Add `POST /api/deploy-request/:id/mark-paid` (admin-auth protected).
-2. Add an internal worker script for paid-request processing.
-3. Add request status timeline fields (`requested`, `paid`, `provisioning`, `live`, `failed`).
-4. Add email notification hooks (request received / app live).
diff --git a/docs/github-pages.md b/docs/github-pages.md
index 805a196..8790dd6 100644
--- a/docs/github-pages.md
+++ b/docs/github-pages.md
@@ -1,23 +1,32 @@
-# GitHub Pages + yappybara.dev
+# GitHub Pages + `yappybara.dev`
-This repo now includes a static site in `site/` that can be deployed with GitHub Pages at near-zero cost.
+This repo ships a static website from `site/` and deploys it with GitHub Actions.
-## 1) Deploy the Pages site
+Goal: free public landing page, no backend hosting bill.
-1. Push `main` with `site/` and `.github/workflows/pages.yml`.
-2. In GitHub: `Settings -> Pages`, set source to **GitHub Actions**.
-3. Wait for the "Deploy GitHub Pages" workflow to finish.
+## 1) Enable GitHub Pages (Actions)
-## 2) Set the custom domain
+In GitHub:
+1. Open `Settings -> Pages`
+2. Set **Build and deployment** source to **GitHub Actions**
-1. In `Settings -> Pages`, enter `yappybara.dev` as the custom domain.
-2. Ensure HTTPS is enabled (GitHub usually enables this after DNS propagates).
+The workflow `.github/workflows/pages.yml` deploys on pushes to `main` that touch `site/**`.
-`site/CNAME` already contains `yappybara.dev`.
+## 2) Custom domain
-## 3) DNS records in Namecheap
+`site/CNAME` is already set to:
-For apex + `www`, use:
+```text
+yappybara.dev
+```
+
+After Pages is enabled:
+1. In `Settings -> Pages`, set custom domain to `yappybara.dev`
+2. Enable HTTPS once DNS has propagated
+
+## 3) Namecheap DNS records
+
+For GitHub Pages custom domain support:
- `@ A 185.199.108.153`
- `@ A 185.199.109.153`
@@ -25,20 +34,21 @@ For apex + `www`, use:
- `@ A 185.199.111.153`
- `www CNAME obsecurus.github.io`
-These values come from GitHub's custom domain guidance for Pages.
+## 4) DNS automation script
-## 4) Optional automation via Namecheap API
-
-You can update DNS from this repo with:
+Dry run:
```bash
node scripts/configure-namecheap-github-pages.mjs
-node scripts/configure-namecheap-github-pages.mjs --apply
```
-The script reads `.env.secrets` and preserves unrelated existing DNS records while replacing only `@` and `www`.
+Apply:
+
+```bash
+node scripts/configure-namecheap-github-pages.mjs --apply
+```
-### Required `.env.secrets` variables
+Required `.env.secrets` values:
- `NAMECHEAP_API_KEY`
- `NAMECHEAP_API_USER`
@@ -46,6 +56,17 @@ The script reads `.env.secrets` and preserves unrelated existing DNS records whi
- `NAMECHEAP_CLIENT_IP`
- `NAMECHEAP_DOMAIN` (defaults to `yappybara.dev`)
-Notes:
-- Namecheap API requires your client IP to be whitelisted in Namecheap API settings.
-- If your key in `.env.secrets` has smart quotes, the script strips them automatically.
+Optional:
+
+- `GITHUB_PAGES_USER` (defaults to `obsecurus`)
+- `GITHUB_PAGES_CNAME_TARGET` (defaults to `${GITHUB_PAGES_USER}.github.io`)
+
+## 5) Verify
+
+- Pages URL: `https://obsecurus.github.io/yappybara/`
+- Custom domain: `https://yappybara.dev`
+
+If custom domain is still pending:
+- verify DNS records,
+- verify Namecheap API whitelist for `NAMECHEAP_CLIENT_IP`,
+- wait for DNS propagation.
diff --git a/fly.toml b/fly.toml
deleted file mode 100644
index e781625..0000000
--- a/fly.toml
+++ /dev/null
@@ -1,39 +0,0 @@
-app = "yappybara"
-primary_region = "ord"
-
-[build]
- dockerfile = "Dockerfile.fly"
-
-[env]
- PORT = "8080"
- YAPPY_MODE = "claude"
- YAPPY_BILLING_MODE = "user_api"
- YAPPY_STORAGE_DIR = "/data"
- YAPPY_DEPLOY_DOMAIN = "yappybara.dev"
- YAPPY_DEPLOY_PRICE_USD = "9"
- FORCE_HTTP = "true"
- AUTO_GENERATE_CERTS = "false"
-
-[http_service]
- internal_port = 8080
- force_https = true
- auto_start_machines = true
- auto_stop_machines = true
- min_machines_running = 0
- processes = ["app"]
-
- [[http_service.checks]]
- interval = "15s"
- timeout = "5s"
- grace_period = "20s"
- method = "GET"
- path = "/api/health"
-
-[[vm]]
- memory = "1gb"
- cpu_kind = "shared"
- cpus = 1
-
-[[mounts]]
- source = "yappybara_data"
- destination = "/data"
diff --git a/interview-app/.env.example b/interview-app/.env.example
index 51f8a49..a5b4941 100644
--- a/interview-app/.env.example
+++ b/interview-app/.env.example
@@ -1,4 +1,4 @@
-# Minimal env for hosted API mode (Fly.io)
+# Optional env for hosted API mode
PORT=8080
YAPPY_MODE=claude
YAPPY_BILLING_MODE=user_api
diff --git a/interview-app/fly.toml.example b/interview-app/fly.toml.example
deleted file mode 100644
index 1031cd8..0000000
--- a/interview-app/fly.toml.example
+++ /dev/null
@@ -1,39 +0,0 @@
-app = "yappybara-api"
-primary_region = "ord"
-
-[build]
- dockerfile = "Dockerfile"
-
-[env]
- PORT = "8080"
- YAPPY_MODE = "claude"
- YAPPY_BILLING_MODE = "user_api"
- YAPPY_STORAGE_DIR = "/data"
- YAPPY_DEPLOY_DOMAIN = "yappybara.dev"
- YAPPY_DEPLOY_PRICE_USD = "9"
- FORCE_HTTP = "true"
- AUTO_GENERATE_CERTS = "false"
-
-[http_service]
- internal_port = 8080
- force_https = true
- auto_start_machines = true
- auto_stop_machines = true
- min_machines_running = 0
- processes = ["app"]
-
- [[http_service.checks]]
- interval = "15s"
- timeout = "5s"
- grace_period = "20s"
- method = "GET"
- path = "/api/health"
-
-[[vm]]
- memory = "1gb"
- cpu_kind = "shared"
- cpus = 1
-
-[[mounts]]
- source = "yappybara_data"
- destination = "/data"
diff --git a/interview-app/public/index.html b/interview-app/public/index.html
index 5f6c6ca..444d517 100644
--- a/interview-app/public/index.html
+++ b/interview-app/public/index.html
@@ -2168,7 +2168,7 @@
Scan to Connect
Deploy Your App
-
Local save is already done. This request adds your app to the parent deploy queue for Fly.io + domain setup.
+
Local save is already done. This request logs your app for optional manual hosting + domain setup.