Skip to content
Release log

Build log, in public.

Pre-launch — every entry below is shipped code or a signed PR. Anything we'd like to ship but haven't yet lives in the roadmap section at the bottom.

v0.11

2026-05-23
PRE-LAUNCH

App-shell stability: Clerk's UserButton was emitting hydration mismatch errors on every authenticated route. The shell now hydrates cleanly + the e2e harness no longer flakes on heavy upload paths.

  • fixTopbar's <UserButton /> wrapped in a mount-gate (stable aria-hidden placeholder during SSR + first client render, swap to real Clerk widget after useEffect). Eliminates `Hydration failed because the server rendered HTML didn't match the client` errors on /dashboard, /projects, /projects/new, /projects/[id], /studio, /exports, /billing, /settings. Placeholder dims match the eventual avatar box so there's no layout shift.
  • adde2e/no-hydration-errors.spec.ts — Playwright spec that visits all 8 Topbar routes, listens for any console-error or pageerror matching React #418 / #421 / #423 / #425 codes or `hydrat*` text, fails the build on a regression.
  • perfPlaywright workers capped at 2 locally + 1 retry (CI keeps 1 worker / 2 retries). The studio upload + autosave path saturates Next dev under unbounded parallelism; the cap drops e2e flakes to zero and the full suite runs 21/21 green.

v0.10

2026-05-23
PRE-LAUNCH

Studio uploads now persist + Export current produces a real exact-pixel App Store PNG. Two stacked bugs were silently masking each other in the pre-fix code.

  • add/api/upload/direct — same-origin proxied multipart upload that PUTs to R2 with server credentials. Sidesteps missing R2 bucket-CORS without operator action. Studio's onUpload routes through this; the blob URL is swapped for the durable https URL on success and screenshotRemote flips to true.
  • add/api/r2-proxy — same-origin read proxy for R2 public URLs. Strict key-regex validation (users/<uuid>/(projects/<uuid>|uploads)/<nanoid>.<ext>), content-type allowlist (PNG/JPEG/WEBP), 12 MB cap, immutable cache headers. Lets html-to-image's canvas.drawImage read R2 bytes without tainting the canvas.
  • fixStudio readiness now requires screenshotRemote === true. A blob URL alone (browser-local, stripped on save) no longer counts as ready — the prior signal lied because panels looked ready but vanished on reload.
  • fixExport pixel-ratio double-scaling. html-to-image multiplies canvasWidth by pixelRatio when both are set; the prior code passed both and produced 3782×… instead of 1290×2796. Dropped the redundant canvasWidth/canvasHeight options — single source of truth is `node CSS width × pixelRatio = output px`.
  • adde2e/studio-export-loop.spec.ts — sharp-measured PNG validation. Drives upload → autosave → Export current → captured download → sharp.metadata() asserts format=png + exact 1290×2796 dims + file size > 20 KB (rules out tainted blanks). Cross-surface READY asserted on /dashboard + /projects + /projects/[id] after the export.
  • adde2e/studio-upload-persistence.spec.ts — proves the upload survives autosave + page reload, with the panel still marked READY on the rehydrated /studio surface.

v0.9

2026-05-23
PRE-LAUNCH

Truthful surfaces sweep: Studio, /exports, /projects/[id], /dashboard, and /projects all derive status from one shared readiness model instead of hardcoding `READY` / `DRAFT` regardless of real state.

  • addlib/studio/readiness.ts — single source of truth. evaluatePanel + evaluateStudio + statusOf + statusLabel produce a canonical enum (empty / blocked / partial / ready) that every surface consumes.
  • addlib/studio/project-status.ts — wraps the readiness chain for per-project status across the list + overview surfaces. Same enum, same badge variant, same state-aware next-action (Open studio / Upload in Studio / Prepare in Studio / Open Exports).
  • fixStudio's `EXPORT READY` InfoCell + Export current / Export all buttons now gate on real readiness. Empty projects no longer claim ready or enable export. Defense-in-depth: if a blocked panel is dispatched anyway (DevTools strip), the run logs a Blocked row with the missing-pieces reason instead of silently no-opping.
  • fix/projects/[id]/exports — dead-end `Render now · coming soon` CTA replaced with state-aware `Prepare in Studio` / `Open Studio to export`. Per-device cards show real PANELS X / READY Y counts derived from studio.panels[].deviceId. Header readiness card matches Studio's data-readiness-status.
  • fix/projects/[id] overview — replaced hardcoded `Shot grid · 0 / 24 slots` + 8 empty placeholders + always-`◯ READY` target rows with real panel-derived state. Per-panel checklist surfaces what's blocking; target rows progress READY / PARTIAL / DRAFTING / TARGETED.
  • fix/dashboard rows + /projects cards no longer hardcode `<Badge>Draft</Badge>` on every entry. Both surfaces consume projectStatus() — data-project-status enum + truthful badge label + truthful `X / Y panels ready` sub-line. Cross-surface consistency spec asserts /dashboard / /projects / /projects/[id] all agree per project.

v0.8

2026-05-23
PRE-LAUNCH

Screenshot Studio engine: ASOForge-style constrained pack builder replaces the Fabric.js freeform editor as the primary editing surface. /editor redirects to /studio.

  • addcomponents/studio/* — Phase A engine: one project owns an ordered panel set (headline + subhead + screenshot + theme + layout + device class + frame style per panel). Constrained-by-design produces App Store-ready output without freeform layout decisions.
  • addMulti-panel filmstrip on /studio with ordered selection, duplication, reordering, deletion, and bulk export naming. Each panel renders into the device frame at exact pixel dimensions on export.
  • addStudio is now the default editing route — /projects/[id]/editor server-side redirects to /projects/[id]/studio. The legacy Fabric route is retired from the user path; lib/canvas/* stays as schema infrastructure that Studio reads/writes through.
  • fixStudio device-class switch was a UI lie. Clicking iPhone 6.7 or iPad 13 left iPhone 6.9 visually selected; preview header + filmstrip metadata stuck on the old device. Added aria-pressed + aria-checked + data-active + role=radio markers + an active text-color flip so the selected state is unambiguous. Extracted the switch logic to a pure reducer (lib/studio/device-switch.ts) with 12 unit specs + 3 Playwright specs covering click → selected styling, filmstrip metadata, and selection persistence across page reload (autosave).

v0.7

2026-04-30
PRE-LAUNCH

AI dispatch is real now — Copy + Backdrop both call live models behind a Trigger.dev task that owns the credit ledger transaction.

  • addAI Copy module wired end-to-end: GPT-5 via Vercel AI SDK + Zod, dispatched as a Trigger.dev task, polled for completion.
  • addAI Backdrop module wired end-to-end: gpt-image-1 6-frame composition, six art-direction presets (minimal-light, tactical-dark, warm-organic, playful-gradient, tech-minimal, editorial), result lands in Cloudflare R2.
  • addStatus passthrough at /api/ai/runs/[runId] so the editor can poll any dispatched task.
  • addSentry observability helper (lib/observability/log.ts) replaces every console.error in the API surface.
  • addOG image fonts: Archivo Black + JetBrains Mono fetched from Google's CDN at edge runtime, rendered into every social card.
  • fixEditor save path is now single-source — FabricCanvas's status bar is the only save UI; redundant disabled topbar Save removed.
  • remPolotno scaffolding deleted (PolotnoProvider, PolotnoCanvas) — Fabric.js v7 is the locked canvas.

v0.6

2026-04-30
PREVIEW

Purchase + project-create flows are functional in code but require Stripe price IDs and Trigger.dev secrets in Vercel before traffic can hit them.

  • addStripe Checkout: /api/stripe/checkout POST + new PurchaseButton client island. Surfaces inline errors when Stripe price IDs aren't configured.
  • add/api/projects POST creates real DB rows; new-project wizard COMMIT button now routes into the editor instead of 404-ing.
  • add/api/ai/template-set migrated from synchronous route handler to a Trigger.dev task — closes the credit-ledger invariant violation flagged in audit pass 3.
  • fixMobile horizontal scroll: html { overflow-x: clip } global guard + dropped whitespace-nowrap on the hero headline that overflowed below 375px.

v0.5

2026-04-29
PRE-LAUNCH

Pre-launch hygiene + the work-in-progress banner. Site goes from 'looking ready' to 'visibly building'.

  • addHazard-stripe WIP banner above every page — local-storage dismissable, version-keyed so we can re-arm it for major changes.
  • addBuild-time Clerk live-key guard in next.config.ts: warns by default, fails the Vercel build when STRICT_LAUNCH_CHECKS=1.
  • fixWordmark lockup splits SHOTS / HQ across six surfaces — Header, Footer, sticky CTA bar, auth chrome, sidebar, OG route.
  • fixEvery unwired CTA in the logged-in app surfaces is now visibly disabled with 'coming soon' tooltips. No more silent no-ops.

v0.4

2026-04-28
PRE-LAUNCH

Conversion audit pass — anti-AI-slop sweep, brand-respectful motion, and the /tools/web-hero landing.

  • add/tools/web-hero designer landing for the surface that ships outside App Store.
  • addScroll-reveal motion across marketing surfaces — IntersectionObserver-based, GPU-only transform + opacity, prefers-reduced-motion honored.
  • fixTactical theme contrast: --fg-mute calibrated to 6.2:1 against #0A0A0A (was failing WCAG AA at 4.04:1).
  • fixHero backdrop banding: quality bumped to 95, AVIF format priority, fractalNoise dither overlay to break 8-bit gradient banding.

v0.3

2026-04-25
INTERNAL

Brand-extraction pipeline: paste a URL, the model reads the site's palette, typography, and voice and seeds it into the project.

  • add/api/brand/extract endpoint backed by gpt-5 with Zod-validated BrandProfile schema.
  • addSurface system: every project ships App Store + Web hero + OG card + Discord banner + Product Hunt gallery + GitHub social card from one canvas.
  • perfPipeline diagram tracer animation: pure transform/opacity, runs at 60fps on iOS Safari without GPU thermal throttling.

v0.2

2026-04-15
INTERNAL

Canvas + credit ledger landed. Trigger.dev task graph for the long-running AI work.

  • addFabric.js v7 canvas integrated, state persisted to JSONB. (Polotno was evaluated and rejected — $899/mo not viable for v1.)
  • addCredit ledger: append-only, idempotency-keyed, Stripe meter event reuses the same key.
  • addTrigger.dev v3 tasks: ai-generate-copy, ai-restyle, batch-translate, render-screenshot, upload-to-app-store. Each task is the transaction boundary for debit + AI + meter.

v0.1

2026-04-01
INTERNAL

Initial scaffold. Auth, DB, storage, payments wired before the first feature commit.

  • addNext.js 16 App Router + Clerk auth + Neon Postgres (Drizzle) + Cloudflare R2 + Stripe Billing + sharp render pipeline.
  • addDual theme system (Tactical / Swiss) keyed off CSS variables for instant runtime switching inside the app.

Roadmap

Next ship targets
Not shipped
  • This week
    Stripe checkout live to traffic

    Price IDs configured in Vercel, end-to-end test with a real card. Publishes the existing PurchaseButton flow.

  • This week
    Clerk production keys + DNS

    Custom-domain DNS for the Clerk prod instance, OAuth providers configured, pk_live_/sk_live_ rotated in Vercel, STRICT_LAUNCH_CHECKS=1.

  • Next week
    Translate module UI

    batch-translate task already exists; the 41-locale picker dispatches in parallel.

  • Next week
    Real per-template visual previews

    Replace the 21 stylized placeholders on /templates with actual rendered previews of each template's typography and palette.

  • TBD — gated on the items above
    Lift WIP banner

    Once Stripe + Clerk are live and the translate UI ships, the yellow hazard banner comes off and the site enters public beta.