Receber por email
← Voltar para o catálogo

sell

Transforma um aplicativo Vibes em um SaaS multi-inquilino com tenancy baseada em subdomínio. Adiciona autenticação Clerk, controle de acesso por assinatura e gera um aplicativo unificado com página de destino, roteamento de inquilinos e painel de administração.

556estrelas
Atualizado há 2 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add majiayu000/claude-skill-registry

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/sell/svg)](https://www.skillteca.com.br/skills/sell)

Skills relacionadas

Ver todas de Pesquisa e Web →

Alerta por categoria

Receba novas skills de Pesquisa e Web toda segunda

1 email curto, só com as skills novas de Pesquisa e Web. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Display this ASCII art immediately when starting:

░▒▓███████▓▒░▒▓████████▓▒░▒▓█▓▒░      ░▒▓█▓▒░
░▒▓█▓▒░      ░▒▓█▓▒░      ░▒▓█▓▒░      ░▒▓█▓▒░
░▒▓█▓▒░      ░▒▓█▓▒░      ░▒▓█▓▒░      ░▒▓█▓▒░
 ░▒▓██████▓▒░░▒▓██████▓▒░ ░▒▓█▓▒░      ░▒▓█▓▒░
       ░▒▓█▓▒░▒▓█▓▒░      ░▒▓█▓▒░      ░▒▓█▓▒░
       ░▒▓█▓▒░▒▓█▓▒░      ░▒▓█▓▒░      ░▒▓█▓▒░
░▒▓███████▓▒░░▒▓████████▓▒░▒▓████████▓▒░▒▓████████▓▒░

⛔ CRITICAL RULES - READ FIRST ⛔

DO NOT generate code manually. This skill uses pre-built scripts:

| Step | Script | What it does | |------|--------|--------------| | Assembly | assemble-sell.js | Generates unified index.html |

Script location:

node "${CLAUDE_PLUGIN_ROOT}/scripts/assemble-sell.js" ...

NEVER do these manually:

  • ❌ Write HTML/JSX for landing page, tenant app, or admin dashboard
  • ❌ Generate routing logic or authentication code

ALWAYS do these:

  • ✅ Run assemble-sell.js to generate the unified app
  • ✅ Use /vibes:exe to deploy after assembly

Sell - Transform Vibes to SaaS

This skill uses assemble-sell.js to inject the user's app into a pre-built template. The template contains security checks, proper Clerk integration, and Fireproof patterns.

Convert your Vibes app into a multi-tenant SaaS product with:

  • Subdomain-based tenancy (alice.yourdomain.com)
  • Clerk authentication with passkeys
  • Subscription gating via Clerk Billing
  • Per-tenant Fireproof database isolation
  • Marketing landing page
  • Admin dashboard

Architecture

The sell skill generates a single index.html file that handles all routes via client-side subdomain detection:

yourdomain.com          → Landing page
*.yourdomain.com        → Tenant app with auth
admin.yourdomain.com    → Admin dashboard

This approach simplifies deployment - you upload one file and it handles everything.

Workflow Overview

  1. Detect existing app (app.jsx or riff selection)
  2. Configure domain, pricing, and Clerk keys
  3. Assemble unified app (run assembly script)
  4. Deploy with /vibes:exe

Step 1: Detect Existing App

Look for an existing Vibes app to transform:

# Check current directory
ls -la app.jsx index.html 2>/dev/null

# Check for riff directories
ls -d riff-* 2>/dev/null

Decision tree:

  • Found app.jsx → Use directly
  • Found multiple riff-*/app.jsx → Ask user to select one
  • Found nothing → Tell user to run /vibes:vibes first

If riffs exist, ask:

"I found multiple riff variations. Which one would you like to transform into a SaaS product?"

Step 2: Gather ALL Configuration Upfront

Use AskUserQuestion to collect all config in 2 batches before proceeding.

Do NOT ask questions one-by-one. Gather everything upfront, then proceed directly to assembly.

Batch 1: Core Identity

Use the AskUserQuestion tool with these 4 questions:

Question 1: "What should we call this app? (used for database naming, e.g., 'wedding-photos')"
Header: "App Name"
Options: Provide 2 suggestions based on context + user enters via "Other"

Question 2: "What domain will this deploy to?"
Header: "Domain"
Options: ["Use exe.xyz subdomain", "Custom domain"]

Question 3: "Do you want to require paid subscriptions?"
Header: "Billing"
Options: ["No - free access for all", "Yes - subscription required"]

Question 4: "What's your Clerk Publishable Key? (from Clerk Dashboard → API Keys)"
Header: "Clerk Key"
Options: User enters via "Other" (starts with pk_test_ or pk_live_)

Batch 2: Customization

Use the AskUserQuestion tool with these 4 questions:

Question 1: "Display title for your app? (shown in headers and landing page)"
Header: "Title"
Options: Suggest based on app name + user enters via "Other"

Question 2: "Tagline for the landing page?"
Header: "Tagline"
Options: Generate 2 suggestions based on app context + user enters via "Other"

Question 3: "What features should we highlight on the landing page? (comma-separated)"
Header: "Features"
Options: User enters via "Other"

Question 4: "Enable subdomain claiming? (users claim alice.yourapp.com)"
Header: "Registry"
Options: ["Yes - enable subdomain claiming (Recommended)", "No - skip for now (can add later)"]

After Receiving Answers

  1. If user selected "Custom domain", ask for the domain name
  2. If subdomain claiming enabled, ask for:
  3. Clerk PEM Public Key (from Clerk Dashboard → API Keys → "Show JWT Public Key")
  4. Clerk Webhook Secret (optional, for subscription sync)
  5. Admin User IDs default to empty (user can add later via Clerk Dashboard)
  6. Proceed immediately to Step 3 (Assembly) - no more questions

IMPORTANT: Clerk has TWO different keys: | Key | Format | Purpose | |-----|--------|---------| | Publishable Key | pk_test_... | Frontend auth (asked in Batch 1) | | PEM Public Key | -----BEGIN PUBLIC KEY----- | Backend JWT verification (for registry) |

The PEM key is found in Clerk Dashboard → API Keys → scroll down to "PEM Public Key" or "Show JWT Public Key".

Config Values Reference

| Config | Script Flag | Example | |--------|-------------|---------| | App Name | --app-name | wedding-photos | | Domain | --domain | myapp.exe.xyz | | Billing | --billing-mode | off or required | | Clerk Publishable Key | --clerk-key | pk_test_xxx | | Title | --app-title | Wedding Photos | | Tagline | --tagline | Share your special day | | Features | --features | '["Feature 1","Feature 2"]' | | Admin IDs | --admin-ids | '["user_xxx"]' (default: '[]') |

Stored for deployment (not used by assemble-sell.js): | Config | exe.js Flag | Purpose | |--------|-------------|---------| | Clerk PEM Public Key | --clerk-key | Registry JWT verification | | Clerk Webhook Secret | --clerk-webhook-secret | Subscription sync |

Step 3: Assemble (DO NOT GENERATE CODE)

CRITICAL: You MUST use the assembly script. Do NOT generate your own HTML/JSX code. The template has been carefully designed with proper security and Clerk integration that will break if you generate code manually.

3.1 What app.jsx Should Contain

The app.jsx should contain ONLY the user's App component - not SaaS infrastructure. The template provides:

  • CONFIG, CLERK_PUBLISHABLE_KEY, APP_NAME, etc.
  • ClerkProvider, TenantProvider, SubscriptionGate
  • Landing page, admin dashboard, routing
  • Pricing UI via Clerk's <PricingTable /> - DO NOT generate pricing components

⛔ DO NOT generate in app.jsx:

  • Pricing tiers, plans, or subscription UI
  • Landing page sections (hero, features, etc.)
  • Authentication UI (sign in, sign up buttons)

The template handles all of this. Pricing is configured in Clerk Dashboard → Billing → Plans, and displayed via Clerk's PricingTable component.

The assembly script automatically strips:

  • Import statements (template imports everything)
  • export default (template renders App directly)
  • CONFIG declarations (template provides its own)
  • Template constant declarations

3.2 Update App for Tenant Context

The user's app needs to use useTenant() for database scoping. Check if their app has a hardcoded database name:

// BEFORE: Hardcoded name
const { useLiveQuery } = useFireproof("my-app");

// AFTER: Tenant-aware
const { dbName } = useTenant();
const { useLiveQuery } = useFireproof(dbName);

If the app uses a hardcoded name, update it to use useTenant():

  1. Find the useFireproof("...") call
  2. Add const { dbName } = useTenant(); before it
  3. Change to useFireproof(dbName)

The template makes useTenant available globally via window.useTenant.

3.3 Assemble Unified App

Run the assembly script to generate the unified file:

node "${CLAUDE_PLUGIN_ROOT}/scripts/assemble-sell.js" app.jsx index.html \
  --clerk-key "pk_test_xxx" \
  --app-name "wedding-photos" \
  --app-title "Fantasy Wedding" \
  --domain "myapp.exe.xyz" \
  --tagline "Share your wedding photos with guests" \
  --billing-mode "required" \
  -
Compartilhar X LinkedIn