Idle Web Developer
by @jaswir
Make 100s of websites while you're idle. Builds, deploys lovable,v0, quality websites with built-in analytics to help you iterate toward breakout winner and...
clawhub install idle-web-developerπ About This Skill
name: idle-web-developer description: Make 100s of websites while you're idle. Builds, deploys lovable,v0, quality websites with built-in analytics to help you iterate toward breakout winner and hit product market fit. Note for best experience use with HEARTBEAT.md version: 1.0.2 homepage: https://github.com/jaswirraghoe/idle-web-developer metadata: {"openclaw":{"emoji":"π","requires":{"env":["VERCEL_TOKEN"],"bins":["vercel","npm"]},"primaryEnv":"VERCEL_TOKEN","files":["scripts/*"],"os":["darwin","linux"]}}
Website Builder
Autonomously build and ship a polished web app. The idea and design are determined automatically using a dice-based system.
Workflow
0. First-Time Setup (Onboarding Wizard)
Before doing anything else, check whether the skill has been configured.
Config file location:
~/.openclaw/workspace/skills/idle-web-developer/.skill-config
If .skill-config does not exist (or the user explicitly asks to re-run setup with --setup), run the interactive onboarding wizard below.
Onboarding Wizard
Ask the user each question in order. Collect the answers, then write them all to .skill-config at the end. Present each question clearly β one at a time, conversationally.
#### Step A β Vercel Token (required)
> "To deploy your sites, I need your Vercel token. > You can find it at: https://vercel.com/account/tokens > What is your Vercel token?"
Save as VERCEL_TOKEN.
#### Step B β Google Analytics (optional)
> "Would you like to enable Google Analytics on your sites? This is optional β it lets you track page views and user behaviour. > (yes / no)"
GA_MEASUREMENT_ID and GOOGLE_APPLICATION_CREDENTIALS blank.> "What is your Google Application Credentials JSON file path? > (e.g. /home/you/.config/gcloud/service-account.json)"
Save as GOOGLE_APPLICATION_CREDENTIALS.
> "What is your GA4 Measurement ID? > (e.g. G-XXXXXXXXXX β found in Google Analytics β Admin β Data Streams)"
Save as GA_MEASUREMENT_ID.
#### Step C β Supabase Waitlist (optional)
> "Every site includes a 'Join the Waitlist' section so visitors can sign up. > Would you like to connect this to Supabase so emails are actually saved? This is optional β the section always appears, but without credentials submissions won't be stored. > (yes / no)"
SUPABASE_URL and SUPABASE_ANON_KEY blank. The waitlist UI will still be included on every site.> "What is your Supabase project URL? > (e.g. https://abcdefgh.supabase.co)"
Save as SUPABASE_URL.
> "What is your Supabase anon/public key? > (found in Supabase β Project Settings β API β Project API Keys)"
Save as SUPABASE_ANON_KEY.
#### Saving the Config
After collecting all answers, write the config file:
CONFIG="~/.openclaw/workspace/skills/idle-web-developer/.skill-config"cat > "$CONFIG" <
Confirm to the user:
> "β
Setup complete! Your config has been saved.
> You can re-run setup anytime by saying 'set up the website builder' or passing --setup to the script."
Then proceed with the rest of the workflow.
If .skill-config already exists
Load it and continue. No questions needed.
source ~/.openclaw/workspace/skills/idle-web-developer/.skill-config
1. Check for Vercel Token
Verify that deployment is possible.
$VERCEL_TOKEN is set (from config or environment).Never deploy without authentication.
2. π² Roll 1 β What to Build
Generate a number from 1β5:
python3 -c "import random; print(random.randint(1,5))"
| Roll | What to build | |-----|---------------| | 1, 2 | π€ AI Tool | | 3 | ποΈ OpenClaw Web Tool | | 4, 5 | π° Niche Clone |
If Roll = 1 or 2 β AI Tool
Research current AI opportunities.
Search:
web_search "trending AI tools 2026"
Find something original and useful that can realistically be built as a web app.
Examples:
The result must be practical and usable, not just a landing page.
If Roll = 3 β OpenClaw Tool
Research inspiration from the OpenClaw project.
Run:
gh issue list -R openclaw/openclaw --limit 20
Then build something that extends or promotes the OpenClaw ecosystem, such as:
The result should help developers understand or use OpenClaw faster.
If Roll = 4 or 5 β Niche Clone
Do not use a predefined list. Research what's actually making money right now.
Run multiple searches across these sources:
web_search "most profitable micro SaaS 2025 site:starterstory.com"
web_search "bootstrapped SaaS revenue 2025 site:starterstory.com"
web_search "fastest growing AI SaaS startups 2025 site:crunchbase.com"
web_search "profitable niche SaaS ideas 2025"
Look for:
Selection criteria: 1. The product has demonstrated revenue or traction (not just hype) 2. A clear underserved niche exists (industry, role, geography, workflow) 3. The niche version can be meaningfully differentiated β not just a rebrand
Then:
1. Pick the most promising product with clear revenue signal 2. Identify a specific underserved niche β be precise: - β "small businesses" - β "independent veterinary clinics" 3. Build a focused version targeting that niche exactly
The niche is the moat β the narrower, the better.
Example:
Research finds β Otter.ai ($50M ARR, meeting transcription)
Instead of: > AI meeting transcription
Build: > AI meeting transcription for real estate showings β auto-generates buyer feedback summaries and follow-up emails for agents
3. π² Roll 2 β Color Palette
Roll two more times.
Primary Color
python3 -c "import random; print(random.randint(1,6))"
| Roll | Color | Hex | Vibe | |-----|------|------|------| | 1 | Electric Blue | #2563EB | Trustworthy, tech, precise | | 2 | Deep Violet | #7C3AED | Creative, premium, mysterious | | 3 | Emerald | #059669 | Growth, calm, fresh | | 4 | Crimson Red | #DC2626 | Bold, urgent, powerful | | 5 | Amber | #D97706 | Confident, warm, energetic | | 6 | Cyan / Teal | #0891B2 | Clean, modern, sharp |
Background Mode
python3 -c "import random; print(random.randint(1,6))"
| Roll | Mode | Style |
|-----|------|-------|
| 1, 2, 3 | βοΈ Light | White or #FAFAFA base, dark text |
| 4, 5, 6 | π Dark | #070B14 or deep neutral base, light text |
Pair the primary with 1β2 derived accent colors and a neutral set. The palette should feel curated and intentional β never generic.
4. π¨ Building Web Apps
Before building, check previous builds:
memory/side-hustle-builds.md
Do not duplicate existing ideas.
Stack
Design Standards (non-negotiable)
βοΈ Waitlist Signup Section (Required β Always)
Every single site must include a waitlist signup section. This is non-negotiable, regardless of whether Supabase credentials are configured.
The section should be visually prominent β a full-width band, typically placed between the main CTA and the footer. It should:
Placement: Between the mid-page CTA and the Footer (or at the bottom of the hero if the page is short).
Component file: src/components/Waitlist.tsx
Project Structure
apps//
package.json
vite.config.ts
tailwind.config.ts
tsconfig.json
index.html
src/
main.tsx
App.tsx
components/
Nav.tsx
Hero.tsx
Features.tsx
Waitlist.tsx β always present
Testimonials.tsx
CTA.tsx
Footer.tsx
(+ Demo.tsx, Pricing.tsx, FAQ.tsx as needed)
#### Wiring: With Supabase Credentials
If $SUPABASE_URL and $SUPABASE_ANON_KEY are set, the form should POST to Supabase.
Assume the table is named waitlist with columns email, app_name, and app_url. The agent should note in the output that the user may need to create this table in Supabase if it doesn't exist.
SQL to create the table:
create table if not exists waitlist (
id uuid default gen_random_uuid() primary key,
email text not null unique,
app_name text not null,
app_url text,
created_at timestamptz default now()
);
The fetch call in the component β always include app_name and app_url:
const res = await fetch(${SUPABASE_URL}/rest/v1/waitlist, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': SUPABASE_ANON_KEY,
'Authorization': Bearer ${SUPABASE_ANON_KEY},
'Prefer': 'return=minimal',
},
body: JSON.stringify({ email, app_name: APP_NAME, app_url: window.location.origin }),
});
APP_NAME should be a constant at the top of the Waitlist component, set to the product name (e.g. const APP_NAME = 'ErrorLens').
Inject the values at build time via Vite env vars β never hardcode in source:
In vite.config.ts, expose:
define: {
__SUPABASE_URL__: JSON.stringify(process.env.SUPABASE_URL ?? ''),
__SUPABASE_ANON_KEY__: JSON.stringify(process.env.SUPABASE_ANON_KEY ?? ''),
}
Use __SUPABASE_URL__ and __SUPABASE_ANON_KEY__ in the component.
#### Wiring: Without Supabase Credentials
If credentials are absent, still include the full waitlist UI. The form should render and look identical, but on submit show:
> "β Thanks! We'll be in touch soon."
(The submission does nothing server-side β it's a polished placeholder.)
Log a note in build output:
β οΈ Waitlist is UI-only β set SUPABASE_URL and SUPABASE_ANON_KEY to enable real sign-ups
Analytics (Optional)
Check for both conditions before adding any analytics code:
1. $GA_MEASUREMENT_ID is set
2. $GOOGLE_APPLICATION_CREDENTIALS is set or the file exists
If either is missing β skip analytics entirely. Do not add any tracking code.
Only when both are present, add the following to index.html before