webgl-forensics 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/.github/workflows/forensics.yml +44 -0
  2. package/CLAUDE_CODE.md +49 -0
  3. package/MASTER_PROMPT.md +202 -0
  4. package/README.md +579 -0
  5. package/SKILL.md +1256 -0
  6. package/package.json +53 -0
  7. package/project summary.md +33 -0
  8. package/puppeteer-runner.js +486 -0
  9. package/scripts/00-tech-stack-detect.js +185 -0
  10. package/scripts/01-source-map-extractor.js +73 -0
  11. package/scripts/02-interaction-model.js +129 -0
  12. package/scripts/03-responsive-analysis.js +115 -0
  13. package/scripts/04-page-transitions.js +128 -0
  14. package/scripts/05-loading-sequence.js +124 -0
  15. package/scripts/06-audio-extraction.js +115 -0
  16. package/scripts/07-accessibility-reduced-motion.js +133 -0
  17. package/scripts/08-complexity-scorer.js +138 -0
  18. package/scripts/09-visual-diff-validator.js +113 -0
  19. package/scripts/10-webgpu-extractor.js +248 -0
  20. package/scripts/11-scroll-screenshot-grid.js +76 -0
  21. package/scripts/12-network-waterfall.js +151 -0
  22. package/scripts/13-react-fiber-walker.js +285 -0
  23. package/scripts/14-shader-hotpatch.js +349 -0
  24. package/scripts/15-multipage-crawler.js +221 -0
  25. package/scripts/16-gsap-timeline-recorder.js +335 -0
  26. package/scripts/17-r3f-fiber-serializer.js +316 -0
  27. package/scripts/18-font-extractor.js +290 -0
  28. package/scripts/19-design-token-export.js +85 -0
  29. package/scripts/20-timeline-visualizer.js +61 -0
  30. package/scripts/21-lighthouse-audit.js +35 -0
  31. package/scripts/22-sitemap-crawler.js +128 -0
  32. package/scripts/23-scaffold-generator.js +451 -0
  33. package/scripts/24-ai-reconstruction.js +226 -0
  34. package/scripts/25-shader-annotator.js +226 -0
  35. package/tui.js +196 -0
package/README.md ADDED
@@ -0,0 +1,579 @@
1
+ # webgl-forensics
2
+
3
+ > **The definitive 24-phase reverse-engineering engine for WebGL, Three.js, R3F, GSAP, and animated websites.**
4
+
5
+ Analyze any creative site and extract everything — 3D scenes, shader programs, GSAP timelines, scroll systems, design tokens, fonts, and performance metrics. Then auto-generate a working Next.js starter from the results, or ask an AI to write the reconstruction guide for you.
6
+
7
+ ```bash
8
+ npx webgl-forensics https://cappen.com --scaffold --ai-report
9
+ ```
10
+
11
+ ---
12
+
13
+ ## Table of Contents
14
+
15
+ - [Quick Start](#quick-start)
16
+ - [Installation](#installation)
17
+ - [Usage](#usage)
18
+ - [Interactive Mode (TUI)](#interactive-mode-tui)
19
+ - [CLI Mode](#cli-mode)
20
+ - [All Flags Reference](#all-flags-reference)
21
+ - [Feature Deep Dives](#feature-deep-dives)
22
+ - [--scaffold: Next.js Generator](#--scaffold-nextjs-generator)
23
+ - [--ai-report: Reconstruction Guide](#--ai-report-reconstruction-guide)
24
+ - [--annotate-shaders: GLSL Annotator](#--annotate-shaders-glsl-annotator)
25
+ - [--interactive: TUI Dashboard](#--interactive-tui-dashboard)
26
+ - [--sitemap: Sitemap Crawler](#--sitemap-sitemap-crawler)
27
+ - [--compare: Fidelity Diffing](#--compare-fidelity-diffing)
28
+ - [--record: Video Capture](#--record-video-capture)
29
+ - [The 24 Forensics Phases](#the-24-forensics-phases)
30
+ - [Output Structure](#output-structure)
31
+ - [Architecture](#architecture)
32
+ - [Environment Variables](#environment-variables)
33
+ - [CI/CD Integration](#cicd-integration)
34
+ - [Contributing: Writing Custom Phases](#contributing-writing-custom-phases)
35
+ - [Requirements](#requirements)
36
+
37
+ ---
38
+
39
+ ## Quick Start
40
+
41
+ No install needed:
42
+
43
+ ```bash
44
+ # Analyze any site instantly
45
+ npx webgl-forensics https://site.com
46
+
47
+ # Interactive menu (recommended for first use)
48
+ npx webgl-forensics --interactive
49
+
50
+ # Full cloning pipeline — forensics + scaffold + AI guide
51
+ npx webgl-forensics https://site.com --scaffold --ai-report --screenshots
52
+
53
+ # Analyze WebGL shaders (needs visible browser)
54
+ npx webgl-forensics https://site.com --annotate-shaders --no-headless
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Installation
60
+
61
+ ### Run without installing (recommended)
62
+ ```bash
63
+ npx webgl-forensics [URL] [options]
64
+ ```
65
+
66
+ ### Install globally
67
+ ```bash
68
+ npm install -g webgl-forensics
69
+ webgl-forensics [URL] [options]
70
+ ```
71
+
72
+ ### Install locally in a project
73
+ ```bash
74
+ npm install webgl-forensics
75
+ npx webgl-forensics [URL] [options]
76
+ ```
77
+
78
+ ### Prerequisites
79
+
80
+ | Requirement | Version | Notes |
81
+ |-------------|---------|-------|
82
+ | Node.js | ≥ 18.0.0 | Required |
83
+ | Chromium | Auto-installed | Bundled with Puppeteer |
84
+ | `ANTHROPIC_API_KEY` | Optional | For `--ai-report` and `--annotate-shaders` |
85
+ | `GEMINI_API_KEY` | Optional | Alternative to Anthropic |
86
+
87
+ ---
88
+
89
+ ## Usage
90
+
91
+ ### Interactive Mode (TUI)
92
+
93
+ The easiest way to run. Presents a full terminal menu to configure your forensics run:
94
+
95
+ ```bash
96
+ npx webgl-forensics --interactive
97
+ ```
98
+
99
+ You'll be prompted for:
100
+ - Target URL
101
+ - Analysis scope (all, 3D, animations, scroll, layout)
102
+ - Feature toggles (scaffold, AI report, screenshots, etc.)
103
+ - Browser mode (headless vs. visible)
104
+ - Optional compare URL
105
+ - Output directory
106
+
107
+ Real-time phase progress is shown with spinners and completion status.
108
+
109
+ ---
110
+
111
+ ### CLI Mode
112
+
113
+ #### Minimal run
114
+ ```bash
115
+ npx webgl-forensics https://cappen.com
116
+ ```
117
+
118
+ #### Full cloning pipeline
119
+ ```bash
120
+ npx webgl-forensics https://cappen.com \
121
+ --scaffold \
122
+ --ai-report \
123
+ --sitemap \
124
+ --screenshots \
125
+ --no-headless \
126
+ --format html \
127
+ --history
128
+ ```
129
+
130
+ #### WebGL shader analysis
131
+ ```bash
132
+ # Visible browser is required for some WebGL sites to actually render
133
+ npx webgl-forensics https://site.com \
134
+ --annotate-shaders \
135
+ --focus 3d \
136
+ --no-headless
137
+ ```
138
+
139
+ #### Fidelity check against your clone
140
+ ```bash
141
+ npx webgl-forensics https://site.com \
142
+ --compare http://localhost:3000 \
143
+ --screenshots
144
+ ```
145
+
146
+ #### CI/CD dry run
147
+ ```bash
148
+ npx webgl-forensics https://site.com --dry-run
149
+ ```
150
+
151
+ ---
152
+
153
+ ### All Flags Reference
154
+
155
+ #### v3.1 (new)
156
+ | Flag | Description |
157
+ |------|-------------|
158
+ | `--interactive` | Launch interactive TUI to configure the run |
159
+ | `--scaffold` | Generate a Next.js 15 + TypeScript starter from forensics output |
160
+ | `--ai-report` | Pipe forensics JSON to Claude/Gemini → Markdown reconstruction guide |
161
+ | `--annotate-shaders` | AI-annotate each extracted GLSL shader (math pattern, uniforms, recipe) |
162
+ | `--sitemap` | Parse `/sitemap.xml` for page discovery instead of DOM link crawl |
163
+
164
+ #### v3.0
165
+ | Flag | Description |
166
+ |------|-------------|
167
+ | `--compare [URL]` | Run forensics on two URLs and produce a fidelity diff |
168
+ | `--record` | Record an MP4 video of the full scroll session |
169
+ | `--download-assets` | Download detected `.glb`, `.gltf`, `.woff2`, `.hdr`, `.ttf` files |
170
+ | `--format html` | Output timeline as standalone HTML visualizer |
171
+ | `--history` | Append run complexity score and tech stack to `run-history.json` |
172
+
173
+ #### v2.0
174
+ | Flag | Description |
175
+ |------|-------------|
176
+ | `--focus [scope]` | `all` (default), `3d`, `animations`, `scroll`, `layout` |
177
+ | `--output [path]` | Output directory (default: `./forensics-output`) |
178
+ | `--headless` | Run in headless mode (default) |
179
+ | `--no-headless` | Launch visible browser — some WebGL sites require this |
180
+ | `--screenshots` | Capture 11 scroll-position screenshots |
181
+ | `--multipage` | Crawl all internal pages detected via sitemap or DOM |
182
+ | `--timeout [ms]` | Navigation timeout in ms (default: `30000`) |
183
+ | `--dry-run` | Preview phases and flags without fetching anything |
184
+
185
+ ---
186
+
187
+ ## Feature Deep Dives
188
+
189
+ ### `--scaffold`: Next.js Generator
190
+
191
+ Generates a complete, runnable **Next.js 15 App Router** project pre-wired based on what the forensics found:
192
+
193
+ ```bash
194
+ npx webgl-forensics https://site.com --scaffold
195
+ ```
196
+
197
+ **What gets generated in `./forensics-output/[domain]/scaffold/`:**
198
+
199
+ ```
200
+ scaffold/
201
+ ├── package.json ← Auto-detected deps (gsap, r3f, lenis, etc.)
202
+ ├── tsconfig.json
203
+ ├── next.config.ts
204
+ ├── src/
205
+ │ ├── app/
206
+ │ │ ├── globals.css ← CSS variables extracted from site's design tokens
207
+ │ │ ├── layout.tsx
208
+ │ │ ├── page.tsx ← Home page stub
209
+ │ │ ├── work/page.tsx ← Pages from sitemap (if available)
210
+ │ │ └── about/page.tsx
211
+ │ ├── lib/
212
+ │ │ ├── gsap-setup.ts ← GSAP + auto-detected plugins pre-configured
213
+ │ │ └── lenis.ts ← Smooth scroll wired to GSAP ticker
214
+ │ └── components/
215
+ │ ├── canvas.tsx ← R3F Canvas with detected scene setup
216
+ │ └── preloader.tsx ← Preloader (if site had one)
217
+ └── README.md
218
+ ```
219
+
220
+ **Then just:**
221
+ ```bash
222
+ cd forensics-output/[domain]/scaffold
223
+ npm install
224
+ npm run dev
225
+ ```
226
+
227
+ ---
228
+
229
+ ### `--ai-report`: Reconstruction Guide
230
+
231
+ Pipes the forensics JSON to **Claude** (preferred) or **Gemini** and gets back a detailed Markdown guide for rebuilding the site:
232
+
233
+ ```bash
234
+ ANTHROPIC_API_KEY=sk-ant-xxx npx webgl-forensics https://site.com --ai-report
235
+ ```
236
+
237
+ **Saved as: `reconstruction-guide.md`**
238
+
239
+ The guide includes:
240
+ 1. **Site Overview** — stack summary, complexity rating, what drives it
241
+ 2. **Project Setup** — exact install commands, file structure
242
+ 3. **Design System** — actual hex colors from tokens, typography config, Tailwind snippet
243
+ 4. **Animation System** — GSAP plugin setup, ScrollTrigger patterns, sample tween reconstructions
244
+ 5. **3D / WebGL Layer** — scene setup, detected geometries, camera config
245
+ 6. **Loading & Transitions** — preloader and page transition implementation
246
+ 7. **Critical Notes** — gotchas, performance tips, order of operations
247
+
248
+ **Supports both:**
249
+ - `ANTHROPIC_API_KEY` → Claude Opus (highest quality)
250
+ - `GEMINI_API_KEY` → Gemini 1.5 Pro (alternative)
251
+
252
+ ---
253
+
254
+ ### `--annotate-shaders`: GLSL Annotator
255
+
256
+ Extracts GLSL shader programs from WebGL context and annotates them:
257
+
258
+ ```bash
259
+ ANTHROPIC_API_KEY=sk-ant-xxx npx webgl-forensics https://site.com \
260
+ --annotate-shaders --no-headless
261
+ ```
262
+
263
+ **Saved as: `shader-annotations.json`**
264
+
265
+ Each shader gets:
266
+ ```json
267
+ {
268
+ "type": "fragment",
269
+ "lineCount": 124,
270
+ "uniforms": [
271
+ { "type": "float", "name": "uTime" },
272
+ { "type": "vec2", "name": "uResolution" }
273
+ ],
274
+ "localPatterns": [
275
+ { "name": "Fractional Brownian Motion (fBm)", "desc": "Layered noise for organic textures" }
276
+ ],
277
+ "aiAnnotation": {
278
+ "visualEffect": "Animated fluid noise distortion on a screen-space plane",
279
+ "mathPattern": "Fractional Brownian Motion with 6 octaves",
280
+ "complexity": "moderate",
281
+ "uniforms": [
282
+ { "name": "uTime", "role": "Drives the animation — increment each frame" },
283
+ { "name": "uResolution", "role": "Normalizes UV coordinates to aspect ratio" }
284
+ ],
285
+ "recreationRecipe": "1. Set up a fullscreen plane ..."
286
+ }
287
+ }
288
+ ```
289
+
290
+ **Offline fallback:** Even without an API key, the tool detects math patterns from GLSL source (FBM, Voronoi, SDF, ray marching, chromatic aberration, etc.) and extracts uniforms and varyings.
291
+
292
+ ---
293
+
294
+ ### `--interactive`: TUI Dashboard
295
+
296
+ ```bash
297
+ npx webgl-forensics --interactive
298
+ ```
299
+
300
+ Full terminal UI with:
301
+ - **Prompt-based configuration** — URL, scope, feature toggles, browser mode
302
+ - **Real-time spinner** per phase — shows success/fail + details as each phase runs
303
+ - **Completion summary** — URL, output dir, complexity score, framework detected
304
+
305
+ No config file needed. Great for one-off runs when you want control over what runs.
306
+
307
+ ---
308
+
309
+ ### `--sitemap`: Sitemap Crawler
310
+
311
+ Replaces DOM anchor-crawling with a smarter sitemap-first approach:
312
+
313
+ ```bash
314
+ npx webgl-forensics https://site.com --sitemap --multipage
315
+ ```
316
+
317
+ **Discovery hierarchy:**
318
+ 1. Tries `/sitemap.xml`
319
+ 2. Falls back to `/sitemap_index.xml` → parses child sitemaps
320
+ 3. Falls back to `/page-sitemap.xml`
321
+ 4. Falls back to DOM anchor-crawl if none found
322
+
323
+ **Categorizes URLs by type:**
324
+ - `homepage` — `/`
325
+ - `work` — `/work`, `/projects`, `/portfolio`, `/case-*`
326
+ - `about` — `/about`, `/team`, `/story`
327
+ - `contact` — `/contact`, `/hire`
328
+ - `blog` — `/blog`, `/posts`, `/articles`
329
+ - `other` — everything else
330
+
331
+ URLs sorted by `<priority>` tag. Phase output includes `topPriority[]` for the most important pages.
332
+
333
+ ---
334
+
335
+ ### `--compare`: Fidelity Diffing
336
+
337
+ Runs forensics on two URLs and produces a structured comparison:
338
+
339
+ ```bash
340
+ npx webgl-forensics https://original.com --compare http://localhost:3000
341
+ ```
342
+
343
+ **Output: `comparison-diff.json`**
344
+ ```json
345
+ {
346
+ "fidelityScore": 87.5,
347
+ "techOverlap": ["gsap", "three", "r3f", "lenis"],
348
+ "missingInClone": ["framer-motion"]
349
+ }
350
+ ```
351
+
352
+ `fidelityScore` is 0–100. 100 = identical complexity signature.
353
+
354
+ ---
355
+
356
+ ### `--record`: Video Capture
357
+
358
+ Records a scrolling video of the site:
359
+
360
+ ```bash
361
+ npx webgl-forensics https://site.com --record --no-headless
362
+ ```
363
+
364
+ Saves to `scroll-recording.mp4` in the output directory. The runner scrolls through 10 positions across the full page height, pausing 1s at each, then returns to top.
365
+
366
+ ---
367
+
368
+ ## The 24 Forensics Phases
369
+
370
+ | # | Phase | Script | What It Extracts |
371
+ |---|-------|--------|-----------------|
372
+ | 0 | Tech Stack | `00-tech-stack-detect.js` | Framework, libraries, animation/scroll systems |
373
+ | 1 | Source Maps | `01-source-map-extractor.js` | Webpack chunks, original source references |
374
+ | 2 | Interaction Model | `02-interaction-model.js` | Event listeners, cursor logic, hover behavior |
375
+ | 3 | Responsive Analysis | `03-responsive-analysis.js` | Breakpoints, media queries, viewport behaviors |
376
+ | 4 | Page Transitions | `04-page-transitions.js` | Barba.js, custom router transitions, exit/enter hooks |
377
+ | 5 | Loading Sequence | `05-loading-sequence.js` | Preloader presence, selector, estimated duration |
378
+ | 6 | Audio Extraction | `06-audio-extraction.js` | `AudioContext`, `<audio>` elements, Howler.js |
379
+ | 7 | Accessibility | `07-accessibility-reduced-motion.js` | `prefers-reduced-motion` handling, ARIA patterns |
380
+ | 8 | Complexity Scorer | `08-complexity-scorer.js` | Weighted composite score (0–100) |
381
+ | 9 | Visual Diff | `09-visual-diff-validator.js` | Pixel-level screenshot diff (used by `--compare`) |
382
+ | 10 | WebGPU Extractor | `10-webgpu-extractor.js` | Adapter info, WGSL pipelines, bind groups |
383
+ | 12 | Network Waterfall | `12-network-waterfall.js` | Request timing, resource types, CDN origins |
384
+ | 13 | React Fiber Walker | `13-react-fiber-walker.js` | Full React component tree from `__reactFiber` |
385
+ | 14 | Shader Hot-Patch | `14-shader-hotpatch.js` | Intercepts `compileShader` → captures all GLSL |
386
+ | 15 | MultiPage Crawler | `15-multipage-crawler.js` | BFS crawl of all internal links |
387
+ | 16 | GSAP Timeline Recorder | `16-gsap-timeline-recorder.js` | All tweens, ScrollTriggers, timelines, durations |
388
+ | 17 | R3F Fiber Serializer | `17-r3f-fiber-serializer.js` | Three.js scene graph, materials, geometries |
389
+ | 18 | Font Extractor | `18-font-extractor.js` | Web fonts, CSS `@font-face`, Google Fonts |
390
+ | 19 | Design Token Export | `19-design-token-export.js` | CSS variables, sampled colors, Tailwind scaffold |
391
+ | 20 | Timeline Visualizer | `20-timeline-visualizer.js` | HTML visualization of GSAP timeline data |
392
+ | 21 | Lighthouse Audit | `21-lighthouse-audit.js` | Performance, accessibility, SEO, best practices |
393
+ | 22 | Sitemap Crawler | `22-sitemap-crawler.js` | `/sitemap.xml` → prioritized URL list |
394
+ | 23 | Scaffold Generator | `23-scaffold-generator.js` | Next.js 15 starter from forensics output |
395
+ | 24 | AI Reconstruction | `24-ai-reconstruction.js` | Claude/Gemini rebuild guide |
396
+ | 25 | Shader Annotator | `25-shader-annotator.js` | AI GLSL annotation per shader program |
397
+
398
+ ---
399
+
400
+ ## Output Structure
401
+
402
+ Each run creates a timestamped directory:
403
+
404
+ ```
405
+ forensics-output/
406
+ └── site-com-2026-04-03-01-00/
407
+ ├── forensics-report.json ← Master report — all phases combined
408
+ ├── tech-stack.json
409
+ ├── gsap-timeline.json
410
+ ├── react-fiber-walker.json
411
+ ├── design-token-export.json
412
+ ├── sitemap-crawler.json
413
+ ├── shader-annotations.json ← (--annotate-shaders)
414
+ ├── lighthouse.json ← (Lighthouse)
415
+ ├── timeline.html ← (--format html)
416
+ ├── reconstruction-guide.md ← (--ai-report)
417
+ ├── comparison-diff.json ← (--compare)
418
+ ├── scroll-recording.mp4 ← (--record)
419
+ ├── screenshots/ ← (--screenshots)
420
+ │ ├── scroll-0pct.png
421
+ │ ├── scroll-10pct.png
422
+ │ └── ...
423
+ ├── assets/ ← (--download-assets)
424
+ │ ├── model.glb
425
+ │ └── font.woff2
426
+ └── scaffold/ ← (--scaffold)
427
+ ├── package.json
428
+ ├── src/app/globals.css
429
+ ├── src/app/layout.tsx
430
+ ├── src/lib/gsap-setup.ts
431
+ └── src/components/canvas.tsx
432
+ ```
433
+
434
+ ---
435
+
436
+ ## Architecture
437
+
438
+ ```
439
+ puppeteer-runner.js ← CLI entry point + orchestrator
440
+
441
+ ├── tui.js ← Interactive TUI (chalk + ora + inquirer)
442
+
443
+ └── scripts/
444
+ ├── 00–21 ← Browser-evaluated extraction scripts
445
+ │ (All scripts run inside Puppeteer's page context via page.evaluate())
446
+
447
+ ├── 22-sitemap-crawler.js ← Browser: async fetch + XML parse
448
+ ├── 23-scaffold-generator.js ← Node: file system scaffold writer
449
+ ├── 24-ai-reconstruction.js ← Node: HTTPS → Claude/Gemini API
450
+ └── 25-shader-annotator.js ← Node: offline pattern detect + AI
451
+ ```
452
+
453
+ **Key design decisions:**
454
+ - Scripts 00–22 are **browser-evaluated** (run inside Puppeteer's page context)
455
+ - Scripts 23–25 are **Node.js modules** (run server-side from the runner)
456
+ - All new phase results are attached to the master `forensics-report.json`
457
+ - Everything degrades gracefully — missing API keys → offline fallback, missing packages → skip phase
458
+
459
+ ---
460
+
461
+ ## Environment Variables
462
+
463
+ | Variable | Used By | Purpose |
464
+ |----------|---------|---------|
465
+ | `ANTHROPIC_API_KEY` | `--ai-report`, `--annotate-shaders` | Claude API access (preferred) |
466
+ | `GEMINI_API_KEY` | `--ai-report`, `--annotate-shaders` | Google Gemini API (alternative) |
467
+
468
+ Set before running:
469
+ ```bash
470
+ export ANTHROPIC_API_KEY=sk-ant-your-key-here
471
+ npx webgl-forensics https://site.com --ai-report --annotate-shaders
472
+ ```
473
+
474
+ Or inline:
475
+ ```bash
476
+ ANTHROPIC_API_KEY=sk-ant-xxx npx webgl-forensics https://site.com --ai-report
477
+ ```
478
+
479
+ ---
480
+
481
+ ## CI/CD Integration
482
+
483
+ A GitHub Action is included at `.github/workflows/forensics.yml`. It runs automatically on every PR to `main`:
484
+
485
+ ```yaml
486
+ # .github/workflows/forensics.yml
487
+ name: WebGL Forensics CI
488
+
489
+ on:
490
+ pull_request:
491
+ branches: [main, develop]
492
+
493
+ jobs:
494
+ forensics:
495
+ runs-on: ubuntu-latest
496
+ steps:
497
+ - uses: actions/checkout@v4
498
+ - uses: actions/setup-node@v4
499
+ with: { node-version: '20' }
500
+ - run: npm install
501
+ - run: |
502
+ npx webgl-forensics $SOURCE_URL \
503
+ --compare $COMPARE_URL \
504
+ --output ./forensics-output \
505
+ --headless
506
+ env:
507
+ SOURCE_URL: ${{ vars.FORENSICS_SOURCE_URL }}
508
+ COMPARE_URL: ${{ vars.FORENSICS_COMPARE_URL }}
509
+ - uses: actions/upload-artifact@v4
510
+ with:
511
+ name: forensics-report
512
+ path: forensics-output/
513
+ ```
514
+
515
+ Set `FORENSICS_SOURCE_URL` (original site) and `FORENSICS_COMPARE_URL` (your local or staging URL) as GitHub repository variables.
516
+
517
+ ---
518
+
519
+ ## Contributing: Writing Custom Phases
520
+
521
+ Any `.js` file starting with `custom-` in the `scripts/` folder is **auto-discovered and run**:
522
+
523
+ ```bash
524
+ scripts/custom-my-extractor.js
525
+ ```
526
+
527
+ **Your script must be a self-invoking function that returns a serializable value:**
528
+
529
+ ```javascript
530
+ // scripts/custom-my-extractor.js
531
+ (() => {
532
+ return {
533
+ myData: document.title,
534
+ windowWidth: window.innerWidth,
535
+ };
536
+ })()
537
+ ```
538
+
539
+ The runner will:
540
+ 1. Auto-discover it at startup
541
+ 2. Execute it via `page.evaluate()` in the browser context
542
+ 3. Save output as `custom-my-extractor.json`
543
+ 4. Include it in `forensics-report.json`
544
+
545
+ No registration needed. Drop the file and run.
546
+
547
+ ---
548
+
549
+ ## Requirements
550
+
551
+ - **Node.js** ≥ 18.0.0
552
+ - **Chromium** — automatically installed with Puppeteer
553
+ - **macOS / Linux / Windows** — all supported
554
+ - **GPU** — optional but improves WebGL rendering fidelity with `--no-headless`
555
+
556
+ ### Optional dependencies (auto-installed with npm)
557
+
558
+ | Package | Used For |
559
+ |---------|----------|
560
+ | `puppeteer` | Browser automation |
561
+ | `puppeteer-screen-recorder` | `--record` MP4 output |
562
+ | `lighthouse` | Lighthouse audit phase |
563
+ | `chalk` | Colored output in TUI |
564
+ | `ora` | Spinner progress in TUI |
565
+ | `inquirer` | Interactive prompts in `--interactive` |
566
+
567
+ ---
568
+
569
+ ## License
570
+
571
+ MIT © [404kidwiz](https://github.com/404kidwiz)
572
+
573
+ ---
574
+
575
+ ## Related
576
+
577
+ - [Repo](https://github.com/404kidwiz/webgl-forensics)
578
+ - [Issues](https://github.com/404kidwiz/webgl-forensics/issues)
579
+ - Built with [Antigravity](https://github.com/404kidwiz) — AI coding assistant