Changelog
Every commit, pulled live from git every 5 minutes.
Friday, May 29
- GET /billing/revenue-summary: MRR, active subs, recent charges from builder's Stripe Connect account; returns { connected: false } if not set up - RevenueDashboardPanel on dashboard: 3 stat boxes (MRR/subs/volume), recent charges list, Connect Stripe CTA when not connected - POST /push/:appId/subscribe, GET /push/:appId/count, POST /push/:appId/send mounted at /push; uses crypto.subtle VAPID JWT signing via CF Workers - D1 migration 024_push.sql: push_subscriptions table with UNIQUE(app_id, endpoint) - WebPushPanel per-app card: subscriber count, send form (Pro/Studio gate), code sni…Expands templates from 5 stubs to 10 rich production-ready starters across Business, Creator, Marketing, AI, Community, Commerce, and Productivity categories. Each template carries a full prompt that pre-fills the builder via ?prompt= so users land in a ready-to-build state. Templates page gains a category filter bar, search box, and 3-column card grid replacing iframes. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- API: GET /billing/usage-summary returns real usage stats (messages today/month, limits, apps count) - Build page: SmartPaywallModal replaces plain 402 error text — shows usage progress bars, Pro/Studio upgrade buttons wired to /billing/checkout, flame-accented dark modal - Landing page: testimonial strip (3 indie hacker personas, flame left-border cards) - Landing page: HomeHero CTA updated to "Build my app now — it's free →" + star rating social proof badge - Landing page: LiveStats animated count-up with requestAnimationFrame ease-out, flame icon, stronger layout - Landing page: premium fe…
- D1 migration 023_drip.sql: drip_emails table (steps 1/2/3, deduped by user+step) - lib/drip.ts: scheduleDrip() inserts 3 rows on signup; processDripQueue() sends due emails via Resend (welcome ⚡ / day-2 nudge 👀 / day-5 Pro upgrade pitch) - auth.ts /verify: calls scheduleDrip() via waitUntil for new users - index.ts: processDripQueue() wired into the */5 cron alongside health checks - dashboard/page.tsx: OnboardingChecklist modal with 4 steps, flame progress bar, auto-dismiss on completion, localStorage gate, 500ms delayed mount Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Thursday, May 28
- New app_changelogs D1 table (022_app_changelog.sql) with published/draft states - /apps-changelog API route: public list, auth all-entries, AI generate (Pro/Studio), publish toggle, delete - AI uses claude-haiku-4-5 to read last 20 conversation messages and write bullet-point release notes - Public /changelog/[slug] page with dark design, version badges, and per-entry timeline - ChangelogPanel in AppCard: Generate button, editable draft textarea, Publish, Copy Tweet, entries list Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- New /cloudkit/:appId/enable|disable|scaffold API (auth + Studio gate) - CloudKit scaffold returns CloudKitManager.swift + Models.swift with async/await, CKContainer/CKRecord CRUD, subscriptions, and CKError handling - builder.ts /chat now injects CloudKit system prompt when backend_mode='cloudkit' - Dashboard CloudKitPanel: toggle, Swift file viewer with copy buttons, Studio-only gate with upgrade prompt - Fixed pre-existing ChangelogPanel missing-definition build error (added full component wired to /apps-changelog API) - D1 migration 022_cloudkit.sql adds backend_mode column to apps table …
Adds push/email broadcast feature so builders can send email blasts to all waitlist subscribers directly from the dashboard. Gated to Pro and Studio plans. Includes D1 migration, Hono API route with Resend batch delivery, and BroadcastPanel UI component matching the AgentsPanel style. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Apple rejected build 1.0.0 (1) citing guideline 2.5.2 (Performance - Software Requirements): the reviewer observed the app preview tab loading user-built web apps via WKWebView with allowsContentJavaScript=true, which Apple flagged as 'installing or launching executable code'. Fix: swap WKWebView → SFSafariViewController for AppPreviewView. SFSafariViewController is Apple's explicitly approved API for displaying remote web content within apps — equivalent to 'open in Safari' and does not trigger 2.5.2. The user's deployed web apps are fully server-side; no code is downloaded to or executed on-…
- Backend: DELETE /auth/account — wipes all user data in one D1 batch (apps, conversations, messages, sessions, usage_events, domains, connected_services, referrals, ideas, and all nested app sub-tables) then clears the session cookie - iOS APIClient: add delete() method - iOS AccountView: "Delete account" button with confirmationDialog, spinner during deletion, error alert, auto-sign-out on success - Bumped version 1.0.0→1.0.1, build 1→2 Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Wednesday, May 27
- feat · live-clonec0a8a94one-click fork any public app — instant copy, builder pre-loaded, author earns credits
- D1 migration 019: adds fork_count, forked_from, forked_from_slug/name/author columns to apps table - POST /apps/:id/clone: copies HTML from R2, creates new app record, increments source fork_count, awards +25 credits to source author - GET /apps returns fork_count, forked_from_name, forked_from_author for dashboard display - GET /builder/messages returns forked_from_name/author so builder can show fork banner - discover + gallery endpoints now return id and fork_count per app - /app/[slug] share page: real Clone This App button (CloneButton client component) with fork count display - /galler…
- feat · founder-os483272fFounder OS command center — portfolio HQ, AI weekly briefing, 3 actions today
Adds /founder page as the 10th and final premium feature: a Chief-of-Staff command center aggregating the founder's entire Stakgod portfolio in one place. - API: GET /founder/overview (portfolio metrics + 30d activity feed) - API: GET /founder/briefing (Claude Sonnet streaming, SSE, 6h KV cache) - API: GET /founder/actions (Claude Haiku 3 prioritized daily actions, 1h KV cache) - Web: /founder page with metrics bar, 2/3+1/3 briefing+actions layout, app portfolio grid (uptime dot, 7d views, waitlist count, red-team badge), and a 30d unified activity feed - Nav: "Founder OS" link added to pr…
- feat · founder-os3932535Founder OS command center — portfolio HQ, AI weekly briefing, 3 actions today
Adds /founder page as the 10th and final premium feature: a Chief-of-Staff command center that aggregates the founder's entire Stakgod portfolio into one place. Includes Claude Sonnet streaming weekly briefing (6h KV cache), Claude Haiku "3 things to do today" actions (1h KV cache), portfolio metrics bar, app grid with uptime/views/leads/red-team badges, and a 30d activity feed. API routes at GET /founder/overview|/briefing|/actions (auth-required). Also fixes pre-existing TypeScript error in gallery/page.tsx (missing fork_count on GalleryApp type). Co-Authored-By: Claude Sonnet 4.6 <noreply@a…
- D1 migration 017: ideas + idea_purchases tables - Claude Haiku scores every idea: feasibility (0-100), market size, time-to-ship, competition, one-liner, risks, opportunities - API routes: GET /ideas (paginated, sort=new|top, search), GET /ideas/:id (view count bump), POST /ideas (create+score), POST /ideas/:id/buy (free → prompt redirect; paid → Stripe Checkout Session), GET /ideas/:id/success (Stripe callback → builder redirect), GET /ideas/my-purchases, GET /ideas/my-listings - /discover page: new 💡 Idea Market tab via DiscoverTabs client island; idea cards with color-coded score badge (…
5 AI advisors (VC, growth hacker, paranoid CTO, customer champion, contrarian) read your live app HTML from R2 and give brutal, specific feedback via SSE streaming. Sessions stored in D1. Users can ask follow-up questions to any board member and get in-character responses. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- feat · dead-mans-switch696373esleep mode for inactive builders — 14/21/30d inactivity ladder, email alerts, one-click wake
- D1 migration 015: adds last_active_at, dms_stage, dms_sleep_at to users; sleep_mode, sleep_activated_at to apps - lib/dead-mans-switch.ts: runDeadMansSwitch cron (0 9 * * *), wakeUser helper, three branded email templates - routes/dead-mans-switch.ts: GET /dms/status, POST /dms/wake (requireAuth) - routes/auth.ts: update last_active_at + reset dms_stage on every login - routes/builder.ts: update last_active_at + wake sleeping apps on every deploy - index.ts: mount /dms router, add 0 9 * * * cron dispatch - wrangler.toml: add 0 9 * * * to crons array - dashboard/page.tsx: DMS status banner — …
- feat · neural-ab03b3661AI-generated A/B variants — Claude writes copy, splits traffic, declares winner
- D1 migration 016: ab_tests table + active_ab_test column on apps - lib/neural-ab.ts: generateABVariants (Claude Sonnet reads HTML, writes 2 variants), analyzeABTest (statistical winner + plain-English explanation), promoteWinner (R2 rewrite + KV cleanup) - routes/neural-ab.ts: GET /ab/:appId, GET /ab/:appId/active, POST /ab/:appId/start, POST /ab/:testId/analyze (force flag), POST /ab/:testId/promote, POST /ab-event (no-auth beacon) - KV contract: ab:<slug> stores test routing config for serving worker to read - Dashboard: NeuralABPanel component with variant cards, CVR bars, winner badg…
- feat · pitch-machine7d81b0f60-second VC analysis for any app idea — streaming Claude, /pitch page, nav link
- POST /pitch/validate streams Claude analysis (TAM, VC Room, Competitor Map, Exit Value, The One Thing) - Rate limited 3 req/IP/hour via SESSIONS KV — no auth required - /pitch page with dark/flame theme, example ideas, streaming render, CTA to /build - /pitch added to nav, footer Product links, and sitemap (priority 0.9) Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- feat · mission-controld04938024/7 AI ops center — health checks every 5 min, incident alerts, Claude diagnosis
- D1 migration 013: app_health_checks, incidents, mc_reports tables - lib/health-monitor.ts: ping all live apps every 5min, open/resolve incidents, email alerts via Resend (down + resolved), Claude Haiku AI diagnosis on demand - routes/mission-control.ts: GET status/checks/incidents, POST diagnose (1x/hr rate-limit) - wrangler.toml: added '*/5 * * * *' cron alongside weekly digest - index.ts: wired /mc route + health-check cron handler - dashboard: Mission Control panel per app — uptime%, latency, health sparkline (96 bars), incident banner, AI diagnosis with markdown report, '5-min ping' …
- D1 migration 012: credits + ref_code on users, referrals table - GET/POST /referrals — lazy ref code gen, apply code within 7 days - auth.ts: auto-award credits when new user signs up via ?ref= link - login page: reads ?ref= from URL, passes ref_code through magic-link flow - dashboard: InviteEarnPanel with copy link, X share, referral list, apply-code form - types.ts: User interface gets credits, ref_code, created_at fields Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- layout.tsx: Organization + SoftwareApplication + WebSite JSON-LD - sitemap.ts: dynamic — fetches public app slugs for /app/* pages - robots.ts: structured allow/disallow + GPTBot/Claude-Web crawlers - pricing/layout.tsx: canonical + descriptive meta - showcase/layout.tsx: canonical + feature-list meta - changelog/page.tsx: improved meta + canonical Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Join app_daily_stats for today's view count so dashboard renders 'N views today' correctly without a second fetch. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- D1 migration 011: pageviews, daily_stats, waitlist_entries tables - POST /apps/:slug/view — pageview tracking (no auth, CF-rate-limited) - GET /apps/:id/pageviews — 30-day D1 stats + top referrers - POST /apps/:slug/waitlist — public email capture - GET/PATCH /apps/:id/waitlist — manage waitlist entries + toggle - Dashboard: waitlist panel with email list, CSV export, headline editor - /waitlist/[slug] — public-facing waitlist landing page Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- D1 migration 010: build_time_seconds, total_messages on apps (is_public/description already exist from 005) - GET /apps/public — paginated public gallery (no auth, 60s CDN cache) - PATCH /apps/:id/visibility — REST-style visibility toggle (auth required) - /gallery page: hero + 3-col grid of community apps with load-more - /app/[slug] shareable page with rich OG meta tags for Twitter sharing - Gallery link added to nav and footer - Dashboard visibility toggle already wired (POST /apps/:id/visibility) Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Friday, May 22
Apple's review device rejected Stakgod v1.0 because tapping "Sign in with Apple" returned a server error. Two root causes: 1. /auth/apple/ios verified id_tokens against APPLE_CLIENT_ID only (the web Services ID). Native iOS tokens have aud = "com.stakgod.ios" (the bundle), so every iOS sign-in was 401'ing "invalid_id_token". Fix: pass both as accepted audiences to the JWT verifier. 2. Apple ships `email` only on the very first authorization per (user × app) pair — subsequent sign-ins (or repeat-review runs from Apple's tooling, which is what the reviewer hit) include `sub`…
Drops the CF_BROWSER_TOKEN secret entirely. Cloudflare's [browser] binding gives the worker a Fetcher into Chromium that authenticates through the worker's own identity — no Bearer header, no rotating token, no secret-management ceremony. Both /apps/:id/screenshots and /builder/inspiration now use @cloudflare/puppeteer. Screenshot route shares a single browser instance across all 9 shots (one browser + page-per-shot) which is both cheaper (Browser Rendering bills by browser-seconds) and faster (saves ~1s per shot of Chromium boot). Backwards-compat: CF_BROWSER_TOKEN env var stays declared as o…
Marketplace flywheel: every dashboard load now shows what 6 other Stakgod builders shipped in the last 24h. See something cool → click Fork → start a remix → 80/20 revenue share if the original priced it. Compounds the discover surface without forcing users to navigate away. Backend: /discover now accepts ?since=today|24h|week and ?limit=N (capped at 24). Adds an updated_at WHERE clause; existing callers without the param see no behavior change. Edge-cached 60s, so adding this section to every dashboard view is a single shared cache hit per minute across all users. UI: collapsible section betw…
Thursday, May 21
Reframes the "reverse-engineer-a-URL" brainstorm idea with the legal risk surgically removed. Paste any external URL, Cloudflare Browser Rendering takes one full-viewport PNG, we attach it to the chat as a moodboard image, pre-fill a prompt that explicitly asks Claude to draw inspiration from layout/rhythm/palette WITHOUT copying branding or content. Source markup is never exposed to the user or to Claude. Backend: POST /builder/inspiration { url } → screenshot proxy. Hard SSRF rails — http(s) only, blocks localhost / 10./172.16-31./192.168./ 169.254. and our own stakgod.com / stakgod.app / wo…Studio-tier wow moment for the builder chat. Two halves, both gracefully degrade when the dep isn't available: 1. Mic button next to Send. Web Speech API (browser-native, free, zero server roundtrip) appends recognized text into the input box as the user talks. Chrome / Edge only — Safari falls back to a friendly alert. 2. 🔊 Voice toggle in the chat header. When on, every completed assistant reply gets POSTed to /voice/tts → ElevenLabs Turbo v2.5 streaming TTS → mp3 plays back in an Audio element. Toggle persists in localStorage so power users opt in once. …Apple wants 3-10 screenshots per device size for every submission. Solo founders burn 6 hours per app in Figma or pay for Rotato. One-button fix. POST /apps/:id/screenshots → Cloudflare Browser Rendering REST API renders the deployed app at the three currently-required sizes (iPhone 6.9" 1320×2868, iPhone 6.5" 1284×2778, iPad 13" 2064×2752), 3 shots each at top/mid/near-bottom scroll positions. PNGs land in R2 under apps/<slug>/screenshots/<size>/<n>.png and are publicly served through apps-worker — no extra plumbing. Gated to Pro+ since each render burns ~$0.01-0.03 of Browser Rendering compu…
Every Stakgod app now has a co-branded /<slug>/__about__ URL that ships a polished 1-page landing — hero, what-it-does bullets, narrative, share row, footer. Generated from the app's own HTML so the page inherits its color + typography aesthetic. Trust model deliberately narrow: AI generation runs ONLY when the app's owner clicks "📰 Marketing page" in the dashboard (auth-gated POST /apps/:id/marketing). The public worker just serves the cached R2 blob — no AI invocation on the visitor path, no attacker-controllable input in the public flow. - apps/api/src/routes/marketing.ts — POST + DELETE f…
New "✨ 3 takes" button next to Send fans out three parallel Sonnet calls each seeded with a different style direction: - Minimal (Linear / Vercel docs energy) - Playful (Notion / Stripe Atlas energy) - Brutalist (Are.na / Berkshire energy) The other AI builders give you one take per prompt. Compute is cheap; indecision is expensive. This is the conversion engine disguised as a UX feature — 1 button click = 3 messages burned from the daily wall, which means Free users hit message 2-of-5 instead of 5-of-5. Server checks dayN+3 against the plan limit up-front and returns 402 with a upgrade …
The wow-moment demo: scan a QR with your phone, watch your laptop generate UI changes that show up on the device 1-2 seconds later. Lovable / v0 / WeWeb all stop at iframe-in-iframe; this is on-device. How it works: - New "📱 Phone" toggle in the build-page header opens a small QR overlay encoding <deployedUrl>?preview=1 - apps-worker detects ?preview=1 and (a) sets no-store cache headers so phones never re-render stale HTML, (b) injects a 50-line preview poller into <body> - Poller hits /<slug>/__preview__/version every 1.5s, compares the returned R2 etag, calls location.reload() when…
The moat: builders OAuth into Stripe / GitHub / Notion ONCE on their Stakgod account, and every app they ship after that gets credentials auto-injected by the runtime. No more pasting tokens per project, no more `.env` shuffling, no leaked secrets in customer apps. Foundation in this PR: - D1 migration 009 — connected_services (PK user_id+service, AES-GCM encrypted access_token + optional refresh_token, account_id + account_label for dashboard rendering) - lib/connectors.ts — pluggable spec registry. Each provider declares its OAuth endpoints + scope + post-token finalize hook. Adding a …
Wednesday, May 20
Two new drafts for r/SideProject + r/SaaS that lead with the "iOS app just entered Apple's review queue" milestone — fresh news beats stale launch-day copy. Both drafts deliberately ship without invented metrics; framed as questions / hypotheses so Reddit's bullshit detector doesn't eat the post. Co-Authored-By: Claude Opus 4.7 <[email protected]>
Tuesday, May 19
Drops in-app-payments entitlement (StoreKit IAP doesn't need Apple Pay merchant entitlement), adds UIRequiresFullScreen + iPad orientation qualifier so Apple's iPad multitasking validator accepts an iPhone-only build, and lands the ExportOptions.plist used by `xcodebuild exportArchive` to ship the .ipa straight to App Store Connect. Co-Authored-By: Claude Opus 4.7 <[email protected]>
- Split request path so GET (no body) doesn't need a generic B type inferred - Access AuthStore.shared.sessionToken via await (it's @MainActor) - project.yml: DEVELOPMENT_TEAM filled in - Verified: xcodebuild -destination "generic/platform=iOS Simulator" → BUILD SUCCEEDED Co-Authored-By: Claude Opus 4.7 <[email protected]>
apps/ios-app/ — iPhone-only, iOS 17+, scaffolded for xcodegen + Stakgod's existing GH Actions iOS build pipeline. App structure: - App.swift: env stores wire-up, dark-mode-only - 3-tab UI: Apps (WKWebView preview of shipped apps) / Build (chat with Claude via /builder/chat-sync) / Account (plan, restore, sign-out) - Sign in with Apple → POST /auth/apple/ios → session token in Keychain - StoreKit 2 paywall: com.stakgod.ios.plus ($9.99) + com.stakgod.ios.pro ($24.99). Both monthly auto-renewing. Restore button + manage-sub link per Apple Guideline 3.1.2. - NO in-app App Store submission (a…
Monday, May 18
Replaces the static "Generating · X chars" overlay with a stage label that shifts as Claude streams. Stages chosen so each shows for ~3-8s on a typical Sonnet 4.6 build: <200 🧠 Reading your idea… <800 📐 Sketching the layout… <2.2k 🎨 Choosing colors + typography… <4.5k 🧩 Wiring sg.auth · sg.db · sg.payments… <7.5k ✨ Polishing interactions… <11k 📱 Optimizing for mobile… <16k 🔌 Hooking up event handlers… <22k 📦 Bundling everything together… 22k+ 🚀 Almost done — deploying… Char count still shown (smaller, dimmed) so power users can still see the ra…
Removed every surface that offered the 14-day free trial. The trial was an artificial growth lever that contradicts the small-free-tier positioning. New tagline is "Open source · MIT licensed · all Cloudflare" which is the actual differentiator. Surfaces changed: - billing.ts: removed subscription_data.trial_period_days from Stripe Checkout. Cards are charged immediately on subscribe now. - landing page hero banner - pricing page top banner - welcome-email.ts (HTML + plain text variants) — replaced trial callout with "Open source MIT" callout. - docs: cleaned LAUNCH.md + PH_REPLY_PLAYBOOK.…
Saturday, May 16
Round 2 of pre-launch scan caught three classes of issues: CORS bypass (critical, exploitable today): - Old check: origin.endsWith('stakgod.com') - Attacker-owned evil-stakgod.com or stakgod.com.evil.io would match, letting authed JS on those domains read /apps, /builds, etc. via the user's session cookie. - New: exact regex /^https?:\/\/((.+\.)?stakgod\.com|localhost:3000|127\.0\.0\.1:3000)$/ - Verified blocked in prod: evil-stakgod.com → no ACAO header. Next.js: 15.1.4 → 15.5.18 - Closes 26 advisories incl. RCE in React flight protocol, SSRF in middleware, multiple cache-poisoning DoS …Pre-launch scan found 3 catastrophic 402-loops where the plan-gate code checked field names that didn't exist on PlanDef. Each one ALWAYS returned "plan_required" regardless of which plan the user was on: - app-domain.ts: custom_domain → custom_domains (Hobby/Pro/Studio) - mobile.ts (iOS): ios_ship → testflight (Pro/Studio) - mobile.ts (Android): android_ship → app_store (Studio) Also fixed: - builder.ts: narrowed image media_type to Anthropic's 4 allowed literals (was 'string' — would have silently mismatched on jpeg/webp uploads, and TS-broken th…
Final launch-day hardening before tomorrow's PH ship: - Auto-banner on landing (server component, zero JS) — shows ONLY on Sun May 17 UTC, auto-hides at midnight Monday. Links to PH. - /admin/panic + /admin/panic/clear + /admin/errors — admin-gated kill switch (KV flag, 6h TTL) that 503's every /builder/chat. isPanicActive() called from requireCredits middleware as the first check, before even the global budget breaker. - Global onError handler captures every 500 to KV with 24h TTL so I can live-tail at /admin/errors during the spike. - Per-route Twitter cards on /discover and /press…
Launch-prep abuse defense + comms prep: - Global circuit breaker in requireCredits: caches today's total cost_usd in KV (60s TTL); if it crosses GLOBAL_DAILY_BUDGET_USD (default $50) every /builder/chat returns 503 instead of burning more inference. Resets at the next UTC day. Override via env var per-deploy. - Reply playbooks for Product Hunt (10 canned answers) and Hacker News (technical depth, Show HN body, hunter's first comment, anti-marketing guidelines). Tonally tuned per audience. Co-Authored-By: Claude Opus 4.7 <[email protected]>
Previous commit accidentally checked in the next-on-pages bundle output. This removes from tracking + adds a .gitignore so it never happens again. CI rebuilds these fresh on every deploy. Co-Authored-By: Claude Opus 4.7 <[email protected]>
Two consecutive failures: workflow was disabled in e753931 ("manual only") AND configured for pnpm cache despite the repo using package-lock.json. This restores auto-deploy on every push to main, switches to npm install, adds a path filter (skips doc-only pushes), and adds a deploy job for the apps-worker subtree. NOTE: still requires CLOUDFLARE_API_TOKEN repo secret to actually run. Until that's set, deploys remain manual via wrangler from local. Co-Authored-By: Claude Opus 4.7 <[email protected]>
Friday, May 15
Pure CSS/JS animation that loops every 12s: types prompt, shows fake streaming, snaps in a habit-tracker mockup. Plays on every device, no buffering, no autoplay-mute issues, no MP4 hosting cost. Honors prefers-reduced-motion. Replaces the need for a recorded screen capture for launch. Co-Authored-By: Claude Opus 4.7 <[email protected]>
008's ALTER TABLE failed on re-run because digest_unsubscribed_at column already existed from an earlier partial apply, which aborted the whole batch and left email_digests_sent uncreated. 008b skips the ALTER (column is there) and just creates the missing table + index. Verified live in prod D1. Co-Authored-By: Claude Opus 4.7 <[email protected]>
T-24h launch prep: - /press: logos, boilerplate (short/medium/long copy), founder bio, pull quotes, screenshots, story angles, 1-page everything-journalists-need - Dashboard empty state: hero CTA + 6 prompt suggestions linking to /build - /build accepts ?prompt= to prefill the first message - Footer + sitemap include /press - Refreshed docs/LAUNCH.md with T-12hr final checklist Co-Authored-By: Claude Opus 4.7 <[email protected]>
- API /discover returns views_24h per app from KV daily counter - Grid card shows orange "🔥 Trending" pill (top-left) when threshold met - Bonus: scroll-padding-top:80px so anchor jumps clear the sticky header Co-Authored-By: Claude Opus 4.7 <[email protected]>
- Cron Mon 16:00 UTC scans builders with public apps + activity in last 7d - Idempotent per (user_id, ISO-week) — safe if cron double-fires - Skips empty digests entirely (no spam without traction) - One-click unsub honors RFC 8058 List-Unsubscribe-Post + soft-flag on user row - Admin POST /digest/run for manual sends before first cron - Pending: apply infra/d1/migrations/008_email_digest.sql to D1 prod Co-Authored-By: Claude Opus 4.7 <[email protected]>
- feat · seo28f6da6SSR /discover with edge runtime + 60s ISR + ItemList JSON-LD; client island only for sort/search/load-more
- featbda81c8welcome email on first sign-up via Resend (magic-link + Google + Apple), best-effort via waitUntil
- feat09f639b3-step first-run tour in /build (chat → 🎯 select → ship); persists dismissal in localStorage
- fix · auth950d4e2preserve ?next= through Apple+Google+magic-link sign-in (with sanitize-next open-redirect guard)
- featfdf60bdedge cache for /discover /templates /users/leaderboard /stats + Discord/Twitter footer links
- feat807a35fshareable per-app pages /u/{handle}/{slug} with custom OG cards + Twitter share button + builder card
- featdf74226launch promo (14-day free trial on every paid plan) + a11y polish (skip-link, focus rings, aria-labels)
- fix · visual576639fbrighter ambient anime backdrop site-wide; footer Product list now includes Discover/Templates/Changelog; Company column → Community (GitHub + Founders Fund)
- fix · layout602bc70dedupe Discover in nav + auth-aware header (avatar/Dashboard/Sign out when signed in)
Marketing surface ready for Show HN / Product Hunt / Twitter: api: - /stats/public → live counts (apps, builders, ai_calls/wk, builder revenue/wk) cached 60s. Powers landing-page social-proof pill. - /changelog → git log via GH API, parsed into {kind, scope, title, body, sha} cached 5m. Skips merge commits, conventional-commit aware. web: - New /changelog page (edge SSR, 5m revalidate). Groups commits by day, color- coded badges per kind (feat/fix/infra/perf/chore/docs/refactor). - New /api/og?title=…&subtitle=…&kind=… → 1200x630 SVG with our grad…api/src/do/build-room.ts — new BuildRoom Durable Object: - One instance per app_id; holds the WebSocket fan-out for everyone currently editing that app - On connect, sends 'welcome' with current peer list, broadcasts 'join' - Relays 'cursor', 'select', 'typing', 'preview', 'reaction' messages (validated kinds only) to all other clients with from=sender_id - 'ping' → 'pong' for keepalive - Cleans up on close/error api wrangler.toml — DO binding BUILD_ROOM (class_name=BuildRoom) + migration v1-buildroom adds the new class. api routes/builder.ts — GET /builder/room/:app_id (auth + ownership c…
19-row table directly above Founders Fund. Each row: feature, our state (emerald, bold), their state (white/40 muted). Footer notes the 'compared from public docs as of {month}' caveat + a PR-it link to the open repo. The headline: 'Other AI app builders give you a chat box. Stakgod gives you a chat box AND a real BaaS stack baked into every app you ship.' Co-Authored-By: Claude Opus 4.7 <[email protected]>D1 007 (auto-applied via the new admin token): - ALTER apps ADD COLUMN fork_price_cents (default 0 = free) - New fork_purchases table: source/buyer ledger, stripe_session_id unique, amount + application_fee tracking; indexes for both buyer + source. api builder.ts: - /fork now branches on fork_price_cents: * 0 → free fork as before * >0 → returns 402 with Stripe Checkout URL routed via the seller's Connect account; Stakgod takes 20% application_fee_amount * /fork called again with ?session_id=cs_… → verifies payment, writes fork_purchases row, then creates the cloned app.…apps-worker: - handleQueue: POST /__api__/queue/enqueue, GET /__api__/queue, DELETE /:id - Storage layout: appq:{ISO-run_at}:{slug}:{id} → JSON job. ISO prefix means KV's lex-sorted list returns due jobs in chronological order — tick handler scans appq:, takes anything with run_at <= now, runs + deletes. - scheduled() now drains BOTH the recurring cron table (runDueTasks) AND the one-shot queue (processQueue), batched up to 50 jobs/tick. - Action kinds: * webhook → POST url with body, custom method/headers * push → broadcast to all subscribers (or only the original enqueuer …api builder.ts: - ChatBody.images?: ImageAttachment[] (mime + base64) - Validates: max 5 images per turn, allowed mimes png/jpeg/webp/gif - Final user turn becomes Anthropic multipart content blocks: image source base64 + text. Anthropic vision models do the rest. - Persisted-text in D1 gets a '[📎 N images attached]' suffix so chat history shows what the user dropped (without bloating the row with raw bytes). - System prompt gains a VISION INPUT section: 'image without text → match this design; image + text → text wins for intent, image is reference'. build/page.tsx: - 📎 button + hidde…
api routes/users.ts: - New GET /users/leaderboard?by=views|revenue&limit=10 - Aggregates each builder's public apps: * views: live KV scan of appviews:{slug}:total * revenue: SUM(builder_payouts.amount_gross_cents) for the user - Returns { handle, name, avatar_url, apps, total_views, revenue_cents } - Cached 5 min via cache-control header Discover page gets a new ⚒️ 'Top builders' strip below the apps leaderboard — top 5 cards w/ rank + avatar + name + app count + views, each linking to /u/{handle}. Co-Authored-By: Claude Opus 4.7 <[email protected]>D1 006: ALTER users ADD handle (UNIQUE), bio, twitter, website + partial unique index on handle WHERE NOT NULL. API: - routes/users.ts: * GET /users/me — current builder's profile * POST /users/me — update handle/bio/twitter/website (validates handle: lowercase, 3-32 chars, reserved-word check, uniqueness) * GET /users/:handle — PUBLIC: returns profile + their public apps with hydrated KV view counts + total stats - mounted under /users Web: - New /u/[han…apps-worker: - ?embed=1 on the URL: drops X-Frame-Options so the app frames cleanly on third-party sites (Notion, Substack, blog posts), and swaps the full bottom-right Remix badge for a tiny single-pill 'STAKGOD' corner mark. - SDK gains: * sg.share({title, text, url?}) → tries navigator.share (mobile native sheet), falls back to clipboard.writeText with a UTM-tagged deep link. Returns { shared, via: 'native'|'clipboard'|'cancelled'|'unsupported', url }. * sg.embed({width?, height?}) → returns a ready-to-paste <iframe> snippet pointed at the app's own URL with ?embed=1. Sy…apps-worker: - Top-level HTML page-loads now increment view counters in KV (best-effort via ctx.waitUntil so they never block the page). Two keys per app: appviews:{slug}:total + appviews:{slug}:d:{YYYY-MM-DD} (90d TTL). api-worker (now binds APP_DATA + APP_HOSTS so it can read the same KV): - routes/analytics.ts: GET /apps/:id/analytics returns views (total/today + 14-day daily array), db_keys, push.subscribers + push.sent_month, ai calls/cost month + today, email.sent_month, payments.{gross,fee,txns} - routes/discover.ts: * /discover hydrates view_count from KV at query time (colum…sg.ai.image: - apps-worker now binds [ai] AI; /__api__/ai/image runs @cf/black-forest-labs/flux-1-schnell with caller-supplied prompt + steps (1..8, default 4). Returns { base64, data_url, mime, model, steps }. - Same builder-quota path as sg.ai.chat (1 ai_message event/call, $0.003 cost). - Replaces the previous 501 stub; removed the placeholder usage_event insert. Visual editor v2 quick actions: - Floating element-edit prompt now shows 4 one-tap action buttons above the custom-instruction input: 🗑 Delete · 📋 Duplicate · ⬆️ Move up · ⬇️ Move down - Each fires submitElementEdit() with …iOS (apps/codegen-ios/): - project.yml.tmpl: targets now include both Sources and Resources directories - render.sh: curls icon from ${APP_URL}/icon.png into Resources/Assets.xcassets/AppIcon.appiconset/icon-1024.png and emits a Contents.json using the iOS 14+ single-size manifest (covers all device sizes from one 1024). Strips alpha via sips so Apple doesn't reject. Falls back to a flame square if the download fails. Android (apps/codegen-android/): - render.sh: same icon URL, but downscales to mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi via ImageMagick (resize + center-crop). Falls back to the …apps-worker now exports scheduled() in addition to fetch(); wrangler.toml adds [triggers] crons = ['* * * * *'] (every minute, 1440 invocations/day). KV-stored task list: appcron:{slug}:{id} → CronTask. On each minute tick, runDueTasks() lists all due rows, runs them, recomputes next_run, writes back. No DO needed for v0 — flat KV scan, capped at 1000 tasks/tick. Schedule grammar (v0): @hourly | @daily | @weekly | 'HH:MM' (daily UTC) | 'every Nm' (1..1440) Action kinds (v0): { kind:'push', title, body?, url? } → sends to ALL app subscribers { kind:'webhook', url, body_json?, heade…Zero-dep CF Workers implementation in apps-worker/src/lib/webpush.ts: - VAPID JWT signed with ES256 (P-256) using Web Crypto - aes128gcm payload encryption: ECDH P-256 → HKDF → AES-128-GCM - Properly handles WebPush record framing (salt/rs/idlen/keyid header) - Drops subscriptions on 404/410 (push service expiry) apps-worker /__api__/notify/*: - GET /key → server's VAPID public key (base64url) - GET /sw.js → minimal service worker (push + click handlers) - POST /subscribe → store PushSubscription scoped to (slug, ownerId) - POST /unsubscribe → remove (specific end…
apps-worker /__api__/ai/stream: - Proxies Anthropic SSE → tighter SSE only emitting {delta:...} text chunks + a final {done, tokens_in, tokens_out, model} event - Same model router + builder-quota gating + usage_events accounting as sg.ai.chat (one event per completed call) SDK: sg.ai.stream({ system, messages, model, onDelta }) — onDelta(chunk, sofar) fires for every text fragment; resolves to { text, tokens_in, tokens_out, model } when the upstream stream closes. Supports AbortSignal for cancellation. System prompt teaches both sg.ai.chat (one-shot) and sg.ai.stream (typewriter UX) with …