Releases: TaewoooPark/UIForge
Release list
v3.62.0 — archive replay header sanitization
Fixes archive replay crashes when recorded response headers contain folded newline-separated values.
- Sanitizes recorded replay headers before
writeHead()so newline-separated values are emitted as comma-separated header values. - Verified against the
https://www.multi-turn.aiarchive case from #1: replay now returns 200 instead of crashing withERR_INVALID_CHAR.
v3.61.0 — restore hardening (malformed HTML + fetch perf)
Patches from stress-testing all five flagship sites end-to-end:
- Malformed-HTML robustness: apple.com ships an unquoted
altthe browser splits into bare attributes (13-inch,colors:) — invalid JSX names that crashed the build. Restore now emits only valid attribute names (nameorns:name) and drops the garbage (alt text — no visual impact). - Asset-completion perf: was sequential with an 8s timeout per asset (minutes on asset-heavy pages) → now 12-way concurrent, 6s timeout.
Re-validated: all 5 build; ui.shadcn.com 0%, vercel 1.8%, apple 1.8% (vs its own replay), linear 5%, framer 19% (the last is live Framer-Motion animation state, not a restore fault — the time-frozen freeze is the right oracle for animated pages).
v3.60.0 — Restore wired into /uiforge:clone (tiered archive→source)
The whole tiered pipeline is now one command. /uiforge:clone <url> --restore runs: detect the stack → Tier A (recover real source from source maps, if any) → Tier B (pixel-identical editable React from the real DOM) → visual gate (prove it).
This replaces the old lossy 'reconstruct styles from computed values' rebuild that drifted. READMEs (EN + KO) now document Restore as editable and pixel-identical, with the verified results:
- ui.shadcn.com → 0.00% pixel difference
- vercel.com → 1.8% (WebGL canvas hero)
- linear.app → 5% (JS-state menu) — and Tier A recovers 421 real source files for it, including the genuine
MobileMenu.tsx.
Five new zero-dep tools ship together: uiforge-detect, uiforge-restore, uiforge-visualgate, uiforge-sourcemap, uiforge-debundle.
v3.59.0 — uiforge-debundle (readable reference, Tier C)
The fallback tier for sites with no source maps: unpack the largest minified JS bundles into a readable reference via webcrack (fetched through npx). Splits webpack modules where the bundle allows and turns modern _jsx/jsxs runtime calls back into JSX.
Honest scope — this is a study aid for logic/handlers, not faithful source: original names, prop names, and types are gone, and modern scope-hoisted bundles (Turbopack/Vite) come out as one deobfuscated file rather than a module tree. For real source use Tier A (sourcemap); for pixel-faithful editable output use Tier B (restore); behavior itself is the Archive's job.
v3.58.0 — uiforge-sourcemap (recover REAL source, Tier A)
The highest-fidelity tier: recover a site's actual original source from JavaScript source maps — when a site ships (or leaks) them, including hidden maps whose comment was stripped but whose .map is still on the CDN (blind-probed).
Reads the archive's JS, follows every sourceMappingURL, fetches + validates the map, and rebuilds the src/ tree from sourcesContent — the real pre-transpile .tsx/.ts with original names, comments, and types. Recovered, not reconstructed. Zero-dep, with path-traversal + SSRF guards and vendor filtering.
Verified:
- linear.app → 288 maps → 421 real app source files — including the genuine
src/components/Layout/MobileMenu.tsxwith itsuseStateopen-state logic (exactly what a static Tier-B restore can't reproduce). - ui.shadcn.com → 0 maps (stripped) → cleanly reports it and routes you to Tier B.
v3.57.0 — uiforge-visualgate (pixel-diff fidelity oracle)
Zero-dep pixel-diff gate: render two targets (url / .html / .png / project dir) and diff them via Playwright + canvas, reporting mismatch %% and the worst-differing region's bounding box so the restore loop can localize what to fix. Waits for webfonts to load/swap, serves a built dist/ or static dir, writes a diff image. This is the oracle that proves a restore is pixel-identical to the original instead of hoping it — it's how v3.56.0 was validated to 0% on shadcn.
v3.56.0 — uiforge-restore (archive → pixel-identical editable React)
The Tier-B flagship: turn an archive into an editable React project that renders pixel-identical to the original — by preservation, not reconstruction.
Loads the archive's real rendered DOM, converts it to JSX keeping every class byte-exact, ships the site's real compiled CSS + real assets, and splits the page into editable section components. Fidelity is by construction — the transform never touches the style channel (no drift, unlike the old rebuild).
Verified end-to-end (build + pixel-gate):
- ui.shadcn.com → 0% (pixel-identical)
- vercel.com → 1.8% (the WebGL canvas hero needs JS — a known static limit)
- linear.app → 5% (JS-state-driven mobile menu — the complex-SPA limit)
Hard-won fixes along the way: SVGs inlined as real JSX so child-combinator CSS ([&>svg]:size-3) still matches; #root{display:contents}; html/body attrs applied for the font/color cascade; boolean attrs; and self-completion of assets the archive lazily skipped (Next.js font subsets).
v3.55.0 — uiforge-detect (stack fingerprinting)
First piece of the archive→editable-source pipeline. uiforge-detect fingerprints a site's stack from the archive, offline, zero-dep — Next/Nuxt/SvelteKit/Astro/Remix/Gatsby/Angular/Vue/React-Vite/CRA/static, plus Tailwind-usage density, rendering mode, bundler, and sourcemap availability (the signal for whether Tier-A real-source recovery is viable). Verified: shadcn (Tailwind, no maps), vercel (Tailwind, 59/60 maps), linear (CSS-in-JS, 59/60 maps).
v3.54.0 — Archive is now a browsable, editable mirror (no more .bin)
You were right: an archive full of data/<hash>.bin blobs is opaque — you can't see what got captured, and you can't edit it. Fixed.
What changed
- Every recorded response is now written under
files/at a real path that mirrors its URL, with a real extension —ui.shadcn.com/_next/static/chunks/….js,…/index.html,…/app.css, API JSON, fonts, images. No opaque blobs (0.binon a typical capture). - It's editable. Change a text response (e.g.
files/<host>/index.html) and re-runserve.mjs— the edit shows up, because the replay server reads files fresh on every request.index.jsonmaps each request → its file. - Static-asset filenames stay clean (per-deploy
?dpl=…cache-busters are dropped from the name); genuinely colliding paths fall back to_blobs/<hash>.
Archive vs Rebuild — which one to edit
The Archive reproduces behavior (the real site running offline); the mirror makes it inspectable and tweakable. But to actually develop a copy — clean React + Tailwind components with your own content — use the Rebuild (/uiforge:clone --react). Archive = behavior, Rebuild = editing. Both are documented in the command playbook now.
Verified end-to-end: a fresh ui.shadcn.com archive renders offline (Next.js boots, real content), and an edit to index.html is reflected on reload.
v3.53.0 — New hero: which one's the copy?
The README now opens on the strongest possible proof of fidelity: two screenshots side by side, no labels — one is the live site, the other is UIForge's copy — and you can't tell which.
- shadcn + vercel hero pairs. Left is the live site; right is a copy rendered by the Freeze with every network request blocked. Each copy is byte-for-byte identical to the live original — same MD5 hash (verified: rendered offline, 10 and 18 requests blocked respectively, output hashes match the live shot exactly). Even vercel's canvas hero lands to the pixel.
- Removed the "Copied, five ways" section — the pre-composited comparison images are superseded by the cleaner live-vs-copy hero.
- Dropped 8 orphaned images (old behavior GIF, the five
copy-*stills, two unused showcase PNGs). - Both
README.mdandREADME.ko.mdupdated in lockstep.
The narrative now flows: stun with pixel-perfect fidelity → the three outputs → and it actually works (the Archive behavior GIFs).