diff --git a/docs/superpowers/specs/2026-06-23-remove-juice-simplify-preview-design.md b/docs/superpowers/specs/2026-06-23-remove-juice-simplify-preview-design.md new file mode 100644 index 0000000..c5a2b7e --- /dev/null +++ b/docs/superpowers/specs/2026-06-23-remove-juice-simplify-preview-design.md @@ -0,0 +1,92 @@ +# Spec: Remove Juice & Simplify Preview Module + +**Date:** 2026-06-23 +**Status:** approved + +## Goal + +Remove multi-email-client simulation (Gmail/Outlook) from the preview module, eliminate the `juice` CSS-inlining dependency, and rewrite the dev server in pure Go with SSE-based live reload. + +## Motivation + +- Multi-client CSS simulation has diminishing value — modern email clients render consistently +- `juice` + Node.js adds complexity (npm install, node_modules, separate runtime) +- The project already uses Go for all build tooling; a Node.js dev server is an outlier +- Simplifying to "Modern" and "Source" views covers the real use cases + +## Changes + +### 1. Delete `tools/server/` (entire directory) + +Remove all Node.js artifacts: +- `inliner.mjs` — juice CSS inlining + Gmail/Outlook CSS stripping +- `server.mjs` — Express + WebSocket dev server +- `package.json` / `package-lock.json` +- `node_modules/` — all npm dependencies + +### 2. Rewrite `tools/cli/dev.go` + +- Remove Node.js dependency check +- Remove `exec.Command("node", "server.mjs")` subprocess +- Instead: create and start a pure Go HTTP server (calling into `tools/preview/server.go`) +- Keep the same CLI interface: `go run . dev [--port ]` + +### 3. New file: `tools/preview/server.go` + +Pure Go dev server with: +- **Static file serving** — serve `preview/` directory (index.html, rendered.js) +- **SSE endpoint** (`GET /events`) — Server-Sent Events for browser reload notifications +- **File watcher** — poll `themes/` every 500ms, compare mod times of `.tmpl` files +- **On change detected** — call `preview.RenderAll()` directly (in-process, no subprocess), write `rendered.js`, broadcast SSE `reload` event +- No external Go dependencies — uses `net/http` stdlib only + +### 4. Modify `preview/index.html` + +Frontend changes: +- **Client selector** — reduce from 4 options (Modern/Gmail/Outlook/Raw Source) to 2 (Modern/Source) +- **Remove** `renderedGmail` / `renderedOutlook` variables and all Gmail/Outlook JS logic +- **Simplify** `getRendered()` — always returns `rendered` +- **Simplify** `transform()` — only handles `source` mode (HTML escaping) +- **Remove** Client Simulation indicators panel (HTML section + JS in `updatePanel()`) +- **Remove** static-mode warning message ("Gmail / Outlook simulation is approximate...") +- **Replace** WebSocket with SSE (`new EventSource('/events')`) +- **SSE reload handler** — dynamically reload `rendered.js` on `reload` event, re-render iframe without losing current theme/template/viewport selection +- **Simplify** `setDevMode()` — remove multi-client disclaimer + +### 5. Update `AGENTS.md` + +- Remove references to Juice, Node.js, Gmail/Outlook variants +- Update dev server description to reflect pure Go implementation + +## Non-Changes + +- `tools/preview/engine.go` — template rendering engine unchanged +- `tools/preview/funcs.go` — template functions unchanged +- `tools/preview/locale.go` — locale data unchanged +- `tools/config/` — config loading unchanged +- `tools/data/templates_config.json` — unchanged +- `tools/cli/preview.go` — preview command unchanged +- `tools/cli/commands.go` — command registration unchanged +- All theme `.tmpl` files — unchanged + +## Behavior + +### Static preview (open `preview/index.html` directly) +- Works via `file://` protocol as before +- Two view modes: Modern (rendered HTML in iframe) and Source (escaped HTML source) +- No dev-mode warnings needed + +### Dev mode (`go run . dev`) +- `go run . dev` starts the Go HTTP server on port 3456 (configurable) +- On startup: runs preview engine once, writes `rendered.js` +- Serves `preview/` as static files +- Watches `themes/` for `.tmpl` changes (500ms polling) +- On change: re-renders affected themes, updates `rendered.js`, pushes SSE event +- Browser auto-reloads preview content without page refresh (preserves UI state) + +## Constraints + +- No new Go dependencies — SSE and file polling use stdlib only +- No Node.js requirement +- `preview/rendered.js` format stays compatible: `window.__RENDERED__`, `window.__REGISTRY__`, `window.__PARAMS__` +- Preview still works with `file://` protocol (no server needed for basic use)