Bookmark organizer: from AI Studio export to GitHub in two sessions
An AI Studio export that was actually good — real Gemini integration, embedded Web Worker parsing, full feature loop. Recon, one-char fix, ship.
Most AI Studio exports are autopsy subjects — you open them up and find hollow scaffolding, dead imports, and APIs that were never actually wired. This one was different. The recon session found a complete bookmark organizer with a genuine feature loop: upload browser exports, browse the folder tree, find duplicates, run AI categorization through Gemini in parallel batches, audit link health, and export the cleaned collection back to standard HTML.
The entire rescue was three sessions and one real bug — a relative import path off by one directory. The DNA scanner stripped the import map and migrated Tailwind. The launch workflow fixed the import, verified the app end-to-end, captured screenshots, and pushed. The interesting conversation isn't the fix — it's the future. Bookmarks are personal data, and the user's own note at ship time was: swap the cloud API for a local Gemma 4 model so the whole thing runs offline. That's the thread worth pulling.
Timeline
Dropped into another AI Studio export blind — and this one had walls where you'd expect walls. The recon pattern is always the same: read every file, chase every import, try to boot it, see what's real and what's scaffolding. Most exports are 60% hollow. This one parsed browser bookmark HTML files through an embedded Web Worker, ran duplicate detection across the full tree, and actually called the Gemini API with batched categorization, retry logic, and rate limiting. Twenty-two source files, 2,870 lines of TypeScript. The issues were all mechanical — broken relative import path in bookmarkUtils.ts, missing @types/react, Tailwind still on CDN, import map cruft in index.html. No architectural rot. The feature loop was complete: upload → browse → dedupe → AI categorize → health audit → export. Verdict: keeper.
The entire launch-workflow fix was a single character: ./types → ../types. After the DNA scanner stripped the import map and migrated Tailwind from CDN to PostCSS, the dev server still wouldn't boot — bookmarkUtils.ts sat in utils/ but imported types from ./types instead of ../types. Fixed it, ran npm run dev, and the app rendered first try. Loaded a test bookmark file: 26 bookmarks, 7 folders, parsed instantly through the Web Worker with zero console errors. The sidebar tree mirrored the folder hierarchy, cards showed favicons and Wayback Machine links, the toolbar utilities all hooked up. The Gemini integration wasn't hollow — geminiService.ts sends bookmarks in batches of 20 with 5-way concurrency, structured JSON output via responseSchema, exponential backoff on failures, and case-insensitive category merging across batches. This is production-grade error handling in an AI Studio prototype.
Sanitized the demo data, captured four screenshots and a GIF, wrote the README, and pushed — all in one session. Removed the initial cleanup log, audit report, metadata, and plan files. Scanned every source file for leaked personal data — clean. The .env.local is gitignored, the .env.example shows the key pattern without exposing anything. Captured the welcome screen, browsing view with the Development folder expanded showing 8 bookmark cards, the Insights panel with domain distribution and age analysis, and the duplicate detection flow. The GIF came in at 328 KB — well under the 5 MB target. One commit, one push. But the real next step lives in a note: swap the cloud Gemini call for a local Gemma 4 model. Bookmarks are personal data — URLs reveal browsing habits, interests, financial accounts. Running categorization entirely offline through a local model turns this from "useful tool with a privacy asterisk" into "the bookmark manager I'd actually trust with my real exports."