VibesOS test
Self-contained test automation — invoke directly, do not decompose. End-to-end integration test that assembles a fixture, deploys to Cloudflare (with auto-provisioned Connect), and presents a live URL for browser verification. Use when testing the plugin, running E2E tests, verifying deployment works, or checking that templates assemble correctly.
git clone https://github.com/popmechanic/VibesOS
T=$(mktemp -d) && git clone --depth=1 https://github.com/popmechanic/VibesOS "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/test" ~/.claude/skills/popmechanic-vibesos-test && rm -rf "$T"
skills/test/SKILL.mdPlan mode: If you are planning work, this entire skill is ONE plan step: "Invoke /vibes:test". Do not decompose the steps below into separate plan tasks.
Integration Test Skill
Orchestrates the full test pipeline: credentials → fixture assembly → Cloudflare deploy (with auto-provisioned Connect) → live URL → unit tests.
Working directory:
test-vibes/ (gitignored, persists across runs)
Phase 1: Credentials
Check if
test-vibes/.env exists and has OIDC credentials.
# From the plugin root cat test-vibes/.env 2>/dev/null
If the file exists and contains
:VITE_OIDC_AUTHORITY
AskUserQuestion: Question: "Reuse existing test credentials? (OIDC authority: https://...)" Header: "Credentials" Options: - Label: "Yes, reuse" Description: "Use the OIDC credentials already in test-vibes/.env" - Label: "No, enter new credentials" Description: "I want to use different OIDC credentials"
If the file doesn't exist or credentials are missing, or user wants new ones:
AskUserQuestion: Question: "Paste your OIDC Authority URL (e.g., https://studio.exe.xyz/auth)" Header: "OIDC Authority" Options: - Label: "I need to set up OIDC first" Description: "I'll configure Pocket ID and come back"
If they need to set up OIDC, tell them:
You need a Pocket ID instance for authentication. Connect is auto-provisioned on first deploy -- you just need the OIDC Authority URL and Client ID from your Pocket ID configuration.
Then ask for the client ID:
AskUserQuestion: Question: "Paste your OIDC Client ID" Header: "OIDC Client ID"
Write
test-vibes/.env:
VITE_OIDC_AUTHORITY=<authority-url> VITE_OIDC_CLIENT_ID=<client-id>
Phase 2: Connect (Auto-Provisioned)
Connect is automatically provisioned on first Cloudflare deploy -- no manual setup needed. The
deploy-cloudflare.js script handles R2 bucket, D1 databases, and cloud backend
Worker provisioning via alchemy. Subsequent deploys skip Connect setup.
Proceed directly to fixture selection.
Phase 3: Fixture Selection
AskUserQuestion: Question: "Which fixture to test?" Header: "Fixture" Options: - Label: "basic (Recommended)" Description: "TinyBase data operations with React singleton — the standard integration test" - Label: "minimal" Description: "Template + Babel + import map only — fastest, no data layer" - Label: "sell-ready" Description: "useTenant() + multi-tenant routing — tests factory assembly path" - Label: "ai-proxy" Description: "/api/ai/chat endpoint + CORS — requires OpenRouter key"
For sell-ready fixture: Check
test-vibes/.env for a cached admin user ID from a previous run:
grep OIDC_ADMIN_USER_ID test-vibes/.env 2>/dev/null
If found, offer to reuse it (mask the middle of the value in the prompt, e.g.,
user_37ici...ohcY):
AskUserQuestion: Question: "Reuse stored admin user ID? (user_37ici...ohcY)" Header: "Admin ID" Options: - Label: "Yes, reuse" Description: "Use the cached user ID from test-vibes/.env" - Label: "Skip admin" Description: "Deploy without admin — you can set it up after deploy"
If "Yes, reuse": use the stored value in Phase 4 assembly. If "Skip admin": omit
--admin-ids in Phase 4. Admin setup will be offered post-deploy in Phase 5.5.
If not found: No prompt needed. Admin will be set up post-deploy in Phase 5.5 after the user has a chance to sign up on the live app.
Phase 3.5: Factory Configuration (sell-ready only)
Condition: Only runs when the user selected
sell-ready in Phase 3.
Ask billing mode:
AskUserQuestion: Question: "Which billing mode should this factory test use?" Header: "Billing" Options: - Label: "Free (billing off)" Description: "Claims work without payment — tests auth + tenant routing only" - Label: "Billing required" Description: "Claims require subscription — tests auth gate flow (Stripe billing is phase 2)"
If "Free": Store
BILLING_MODE=off in test-vibes/.env. Skip webhook setup. Proceed to Phase 4.
If "Billing required": Store
BILLING_MODE=required in test-vibes/.env. Note that Stripe billing integration is phase 2, so the paywall will be a placeholder.
Proceed to Phase 4.
Phase 4: Assembly
Copy the selected fixture and assemble:
# Copy fixture to working directory cp scripts/__tests__/fixtures/<fixture>.jsx test-vibes/app.jsx # Source env for assembly set -a && source test-vibes/.env && set +a
For sell-ready fixture:
bun scripts/assemble-factory.js test-vibes/app.jsx test-vibes/index.html \ --domain vibes-test.<account>.workers.dev \ --admin-ids '["<admin-user-id>"]' # read OIDC_ADMIN_USER_ID from test-vibes/.env
If admin was skipped, omit
--admin-ids. The --domain flag is always required.
For all other fixtures:
bun scripts/assemble.js test-vibes/app.jsx test-vibes/index.html
Validate the output (same checks as the vitest suite):
- File exists and is non-empty
- No
strings remain__PLACEHOLDER__ - Import map
is present<script type="importmap">
contains the fixture code<script type="text/babel">- For sell-ready:
function is presentgetRouteInfo
If any check fails, report the error, then ask:
AskUserQuestion: Question: "What next?" Header: "Next" Options: - Label: "Test another fixture" Description: "Go back to Phase 3 and pick a different fixture" - Label: "End test session" Description: "Clean up artifacts and finish"
If "Test another fixture": go to Phase 3. If "End test session": go to Phase 11.
Phase 5: Deploy to Cloudflare
For ai-proxy fixture: Check
~/.vibes/.env for a cached OpenRouter key first:
grep OPENROUTER_API_KEY ~/.vibes/.env 2>/dev/null
If found, offer to reuse it (mask the key, e.g.,
sk-or-v1-...a3b2):
AskUserQuestion: Question: "Reuse stored OpenRouter API key? (sk-or-v1-...a3b2)" Header: "AI Key" Options: - Label: "Yes, reuse" Description: "Use the cached key from ~/.vibes/.env" - Label: "Enter new" Description: "I'll paste a different key" - Label: "Skip AI proxy" Description: "Deploy without AI endpoint"
If "Yes, reuse": use the stored value. If "Enter new": collect via the prompt below, then update
~/.vibes/.env.
If not found (or user chose "Enter new"):
AskUserQuestion: Question: "Paste your OpenRouter API key for the AI proxy" Header: "AI Key" Options: - Label: "Skip AI proxy" Description: "Deploy without AI endpoint"
After collecting a new key, offer to save it:
AskUserQuestion: Question: "Save this OpenRouter key to ~/.vibes/.env for future projects?" Header: "Cache" Options: - Label: "Yes, save" Description: "Cache the key so you don't have to paste it again" - Label: "No, skip" Description: "Use for this session only"
If "Yes, save":
mkdir -p ~/.vibes grep -q OPENROUTER_API_KEY ~/.vibes/.env 2>/dev/null && \ sed -i '' 's/^OPENROUTER_API_KEY=.*/OPENROUTER_API_KEY=<new>/' ~/.vibes/.env || \ echo "OPENROUTER_API_KEY=<new>" >> ~/.vibes/.env
Run the deploy:
bun scripts/deploy-cloudflare.js --name vibes-test --file test-vibes/index.html
For sell-ready fixture: Pass
--env-dir to auto-detect OIDC config, and pass billing mode from test-vibes/.env:
bun scripts/deploy-cloudflare.js --name vibes-test --file test-vibes/index.html \ --env-dir test-vibes \ --billing-mode $BILLING_MODE
Read
BILLING_MODE from test-vibes/.env. The --env-dir flag auto-detects VITE_OIDC_AUTHORITY from .env (fetches OIDC discovery, gets PEM key, sets OIDC_PEM_PUBLIC_KEY and PERMITTED_ORIGINS as Worker secrets). --billing-mode patches the [vars] in wrangler.toml before deploy.
For ai-proxy with key:
bun scripts/deploy-cloudflare.js --name vibes-test --file test-vibes/index.html --ai-key <key>
Phase 5.5: Admin Setup (sell-ready only)
Condition: Only runs for the sell-ready fixture AND admin is not yet configured (no cached ID was reused in Phase 3).
After deploy, guide the user through post-deploy admin setup:
- Tell the user the app is live and they can now sign up:
Your app is deployed! To configure admin access, first create an account: Sign up here: https://vibes-test.<account>.workers.dev?subdomain=test After signing up, we'll grab your User ID from Pocket ID.
- Ask if they've signed up:
AskUserQuestion: Question: "Have you completed signup on the deployed app?" Header: "Signup" Options: - Label: "Yes, signed up" Description: "I've created my account and I'm ready to get my User ID" - Label: "Skip admin setup" Description: "Continue without admin access"
If "Skip admin setup": proceed to Phase 6 without admin configured.
- Guide to finding User ID:
Now grab your User ID: 1. Check the Pocket ID admin panel or your app's user profile 2. Find and copy your User ID (starts with user_)
- Collect the User ID:
AskUserQuestion: Question: "Paste your User ID (starts with user_)" Header: "Admin ID" Options: - Label: "I need help finding it" Description: "Show me where to find the User ID in Pocket ID" - Label: "Skip admin setup" Description: "Continue without admin access"
Validate the input starts with
user_. If not, ask again.
- Save to
:test-vibes/.env
grep -q OIDC_ADMIN_USER_ID test-vibes/.env 2>/dev/null && \ sed -i '' 's/^OIDC_ADMIN_USER_ID=.*/OIDC_ADMIN_USER_ID=<userId>/' test-vibes/.env || \ echo "OIDC_ADMIN_USER_ID=<userId>" >> test-vibes/.env
- Re-assemble with admin configured:
set -a && source test-vibes/.env && set +a bun scripts/assemble-factory.js test-vibes/app.jsx test-vibes/index.html \ --domain vibes-test.<account>.workers.dev \ --admin-ids '["<userId>"]'
- Re-deploy:
bun scripts/deploy-cloudflare.js --name vibes-test --file test-vibes/index.html \ --env-dir test-vibes \ --billing-mode $BILLING_MODE
- Confirm:
Admin access configured! The admin dashboard at ?subdomain=admin should now work for your account.
Proceed to Phase 6.
Phase 6: Present URL
Print the live URL and what to check:
For minimal / basic:
Deployed! Open in your browser: https://vibes-test.<account>.workers.dev What to verify: - Page loads without console errors - (basic) TinyBase data operations work — add, edit, delete items - Settings gear icon opens the menu
For sell-ready:
Deployed! Open these URLs: Landing: https://vibes-test.<account>.workers.dev Tenant: https://vibes-test.<account>.workers.dev?subdomain=test Admin: https://vibes-test.<account>.workers.dev?subdomain=admin What to verify: - Landing page shows pricing/marketing content - Claim a subdomain — should succeed (tests /claim + JWT auth) - Tenant URL shows auth gate (OIDC sign-in via Pocket ID) - Admin URL shows admin dashboard (if admin was configured in Phase 3 or 5.5) - Admin URL shows "Admin Access Required" (if admin setup was skipped)
For ai-proxy:
Deployed! Open in your browser: https://vibes-test.<account>.workers.dev What to verify: - App loads and renders - AI chat feature works (sends to /api/ai/chat) - Check Network tab: requests go to OpenRouter via proxy
Then ask:
AskUserQuestion: Question: "How does it look?" Header: "Result" Options: - Label: "Working" Description: "Everything renders correctly" - Label: "Has issues" Description: "Something isn't right — I'll describe it"
If "Working":
Print a summary table:
| Phase | Status | |-------------|--------| | Credentials | ✓ | | Assembly | ✓ <fixture>.jsx → index.html | | Cloudflare | ✓ <url> (Connect auto-provisioned) | | Browser | ✓ User confirmed working |
AskUserQuestion: Question: "What next?" Header: "Next" Options: - Label: "Test another fixture" Description: "Go back to Phase 3 and pick a different fixture" - Label: "End test session" Description: "Clean up artifacts and finish"
If "Test another fixture": go to Phase 3. If "End test session": go to Phase 11.
If "Has issues": Read
${CLAUDE_SKILL_DIR}/references/diagnostics.md for the full diagnosis flow (Phases 7-10: diagnosis tables, root cause classification, fix-and-verify loop, resolution summary). Then return here for Phase 11.
Phase 11: Unit & Integration Tests
Run the vitest suite to confirm plugin source is healthy. Especially important after any fixes applied in Phase 9.
cd scripts && npm test
If all tests pass: Print the count (e.g. "429 tests passed") and proceed to cleanup.
If any tests fail: Show the failure output and ask:
AskUserQuestion: Question: "Unit/integration tests failed. Fix before finishing?" Header: "Tests" Options: - Label: "Yes, fix them" Description: "Investigate and fix the failing tests" - Label: "Skip" Description: "Finish the session anyway"
If "Yes, fix them": diagnose and fix the failures, re-run
npm test, loop until green.
Phase 12: Session Cleanup
Triggered after Phase 11 completes or when user selects "End test session" from any "What next?" prompt.
Clean up test artifacts while preserving reusable credentials:
# Clean test artifacts, preserve .env cd test-vibes && find . -maxdepth 1 ! -name '.' ! -name '.env' -exec rm -rf {} +
Print:
Test session complete. Cleaned: test-vibes/ artifacts Preserved: .env (reusable next session)