# FvRE — Which Tool For What

**Date**: 2026-07-18
**For**: G (operator) and any future Mavis session
**Companion to**: `FVRE-COMPONENT-MAP.md` (the long version)

The component map explains every FvRE component. This doc answers the one question that matters most of the time: **"Given what I'm trying to extract, which FvRE tool do I use?"**

---

## The 30-second answer

| What you're extracting | FvRE tool | Why |
|---|---|---|
| **A local HTML/JS app** (you have the source file) | **Tool C** (Source + Browser) | Same pipeline that hit 95.82% on SmartPantry |
| **A live website** (you only have the URL, no source) | **Tool A** (Browser DOM walk) | Pure browser-based, no source needed |
| **A static HTML site** (no JS, just markup) | **Tool B** (Source HTML/CSS parse) | Fastest, no browser needed |
| **A WordPress/Elementor site** | **elementor-extract CLI subcommand** | Wraps Tool A with Elementor semantic interpretation |

The `scan` tool tells you which one to use if you're not sure. The `cli` orchestrates everything.

---

## Scenario 1: SmartPantry (the 95.82% test)

**Input**: A single local HTML file
- Path: `/workspace/smartpantry-defirebased-archive/smartpantry-defirebased.html`
- Size: 1.1 MB / 23,390 lines
- Contents: SmartPantry v2.7 with all Firebase calls stripped out
- Behavior: vanilla JS SPA, the JS is inline in `<script>` tags, it renders the page on load

**What you have**: the source file, on disk, with the JS still in it.

**What you don't have**: a public URL serving this file. It's a working file, not a live website.

**Which FvRE tool**: **Tool C** (Source + Browser, single pipeline)

**Why Tool C, not A or B**:
- Tool A needs a live URL — we don't have one
- Tool B doesn't run the JS, so it can't see the post-render DOM (would get maybe 5% of the elements)
- Tool C reads the source CSS AND lets the JS run in a browser, then walks the post-JS DOM. Best of both worlds.

**The exact pipeline that ran on SmartPantry** (per `dual-tools-plan.md`):

```
1. operator runs: fv-extract extract <path-to-smartpantry-defirebased.html>
2. CLI (Component G) parses the args
3. CLI runs B-Scan on the file → recommends Tool C (1109 CSS rules + 56 render functions = JS-heavy)
4. CLI invokes Component A (browser_runner) → launches Chromium
5. CLI invokes Component B-C (Tool C) → runs the 7-step pipeline:
   - Step 1: Read source CSS rules (1109)
   - Step 2: Open the file in the headless browser
   - Step 3: Execute the inline JS, wait for render
   - Step 4: Walk the post-JS DOM (5378 elements)
   - Step 5: Capture per-element computed CSS
   - Step 6: Emit Recipe from post-JS DOM → out/body.recipe.json
   - Step 7: Emit Codex = source CSS + computed values + handler NAMES → out/body.codex.json
6. CLI runs Component C (measurement) → compares output to source → 95.82% match
7. CLI runs Component D (generation) → emits HTML+CSS → out/dist/
8. CLI runs Component E (test harness) → verifies the rebuild
```

**The output** that SmartPantry kept:
- `out/body.recipe.json` (structural v0.5) — written by Tool C
- `out/body.codex.json` (codex v0.1: CSS + handler NAMES) — written by Tool C
- `out/dist/body.html` and `body.css` — written by Generation
- `out/final-recipes/home.recipe.json` etc. — for the 7 module recipes (hand-extracted Component H, not generated)

---

## Scenario 2: Elementor website (the 8-page Oscar Tree Academy test)

**Input**: A live URL
- URL: `https://oscarstreeacademy.org.uk/`
- Tech: WordPress + Elementor v3.35.8 + hello-elementor theme
- Behavior: server-rendered HTML, JS hydrates on load

**What you have**: a public URL, no source code (it's a hosted WordPress site, not your codebase).

**What you don't have**: the PHP source, the wp-config, the database. You only have what the browser sees.

**Which FvRE tool**: **`fv-extract elementor-extract` CLI subcommand** (which wraps Tool A + elementor-adapter)

**Why this, not just Tool A**:
- Tool A gives you raw DOM → recipe, but the DOM is just `<div class="elementor-widget-container">` and you don't know what's a heading vs an image vs a button
- Elementor has well-known structural patterns: `.elementor-section` (top-level container), `.elementor-column` (column), `.elementor-widget` (leaf widget with a `data-id`)
- The `elementor-adapter` (added in PR #2) recognizes these patterns and maps them to semantic recipes
- The CLI subcommand `elementor-extract` (added in PR #9) wraps the adapter with the right subprocess invocation

**The exact pipeline that ran on the Elementor site** (per STEP 5 FINAL):

```
1. operator runs: fv-extract elementor-extract <url> --page home
2. CLI (Component G) parses the args
3. CLI invokes Component A (browser_runner) → launches Chromium, navigates to the URL
4. CLI invokes Component B-A (Tool A) → walks the DOM, captures computed CSS
5. CLI applies elementor-adapter:
   - For each .elementor-section: mark as section
   - For each .elementor-column: mark as column
   - For each .elementor-widget: identify the type from class name (heading, image, button, etc.)
   - Map to semantic recipe: heading.default → text-block, image.default → image-block
   - Preserve data-id as fvw.source_id (stable handle for FVW tagging)
6. CLI applies FVW tagging (Component D part 2): write data-* attributes at render time
7. CLI writes out/final-recipes/home.recipe.json (v0.5 with fvw.source_id on every widget)
```

**The output** that the 8 pages produced:
- `out/final-recipes/home.recipe.json` (252 KB, 37 widgets with fvw.source_id populated) — the only one with real data
- `out/final-recipes/{resources,blog,...}.recipe.json` (small, mostly empty) — the 7 pages with markdown cache issues (separate bug)

---

## Side-by-side comparison

| Aspect | SmartPantry (Scenario 1) | Elementor site (Scenario 2) |
|---|---|---|
| **Input** | Local HTML file | Live URL |
| **Source code available?** | Yes (we have the file) | No (it's a hosted WordPress site) |
| **Tool used** | Tool C | Tool A + elementor-adapter |
| **CLI subcommand** | `fv-extract extract <path>` | `fv-extract elementor-extract <url>` |
| **Why this tool** | Has source + needs JS execution | No source, but framework patterns known |
| **Number of components used** | A, B-Scan, B-C, C, D, E, G (7 of 8) | A, B-A, elementor-adapter, D, G (5 of 8) |
| **Accuracy** | 95.82% match | 37/37 widgets captured on home |
| **What's missing from output** | Component H (hand-written) | Component H (hand-written) |

---

## What about other scenarios?

| What you want to extract | FvRE tool | Notes |
|---|---|---|
| A React/TS app on disk | Tool C, but it doesn't understand JSX | Would need a new extractor (Component B-D? not built) |
| A live React/Next.js site | Tool A (no framework adapter for React yet) | Would need a react-adapter (not built) |
| A Vue/Nuxt site | Tool A | Would need a vue-adapter (not built) |
| A SvelteKit site (like Oscar AI) | Tool A | Would need a svelte-adapter (not built) |
| A native mobile app (iOS/Android) | None of the above | Out of scope — FvRE is for web |
| **SnappyMail running in a browser** (the webmail UI) | **Tool A or C** | It's a web app, has a URL OR has source on disk |
| **The MailSo library** (PHP classes inside SnappyMail) | None — hand-extract | See `app-vs-library-vs-framework.md` |
| **The SnappyMail backend** (account mgmt, sessions) | None — hand-extract | See `app-vs-library-vs-framework.md` |

The FvRE is web-specific. For non-web sources (libraries, native apps, CLI tools), you'd need a different engine.

## The three states an app can be in

| State | What you have | What you don't | FvRE tool |
|---|---|---|---|
| **1. Live at a URL** | URL (e.g. `https://mail.example.com`) | Source code | Tool A (browser DOM walk) |
| **2. Source on disk, not running** | Source files (e.g. `/var/www/.../freshmail/`) | Live URL | Tool C (Source + Browser, single pipeline — opens the local file in a headless browser) |
| **3. Both source AND live** | Both | Neither | Tool C if you want source truth, Tool A if you want rendered truth |

**SnappyMail in our setup is STATE 2.** We have the source at `/var/www/freshvibeapps/clients/freshmail/` (786 PHP files, MIT, private GitHub repo). We don't have it deployed live. Tool C works fine on STATE 2 — it opens the local file in a headless browser, same as if it were live.

**We COULD make it STATE 3 in 5 minutes** (deploy to a subdomain, point fv-extract at it), but that's not necessary. Tool C handles STATE 2 directly.

The library parts (MailSo) and framework parts (SnappyMail's backend) are hand-extracted regardless — the FvRE doesn't extract libraries. See `app-vs-library-vs-framework.md` for the full story.

---

## The one thing I want you to remember

**Tool C is the proven path for owned JS-heavy codebases with source on disk.** That's what 95.82% on SmartPantry means. If you ever want to extract from a codebase you have (not a live URL), Tool C is the answer.

For everything else (live URL, framework patterns), use Tool A with the right adapter (elementor-adapter for Elementor, future adapters for other frameworks).

The `scan` tool tells you which one. The CLI orchestrates. The browser_runner makes it all work in a real browser.

That's the whole engine. 7 components working together, with the doctrinal layer (Component H, the 10-item Recipe Book) hand-written afterwards.
