Skip to content

Architecture: Intelligent Site Exploration

This document describes the architecture of LooK's intelligent site exploration system.

System Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Demo Orchestrator                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚                      Pipeline Coordinator                        β”‚β”‚
β”‚  β”‚  explore() β†’ plan() β†’ execute() β†’ finalize()                    β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚                                                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚   State     β”‚  β”‚  Element    β”‚  β”‚ Navigation  β”‚  β”‚  Content    β”‚ β”‚
β”‚  β”‚  Detector   β”‚  β”‚  Discovery  β”‚  β”‚    Graph    β”‚  β”‚  Analyzer   β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚         β”‚                β”‚                β”‚                β”‚         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚                      Demo Engine                                β”‚ β”‚
β”‚  β”‚  Browser Control β”‚ Cursor Tracking β”‚ Recording β”‚ FFmpeg        β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                   β”‚
                                   β–Ό
                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚    Playwright   β”‚
                        β”‚     Browser     β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Component Architecture

1. Demo Orchestrator

The central coordinator that manages the entire demo generation pipeline.

DemoOrchestrator
β”œβ”€β”€ explore(url)         # Phase 1: Site exploration
β”œβ”€β”€ plan()               # Phase 2: Demo planning
β”œβ”€β”€ execute()            # Phase 3: Demo execution
└── finalize()           # Phase 4: Video finalization

Dependencies:
β”œβ”€β”€ StateDetector
β”œβ”€β”€ ElementDiscovery
β”œβ”€β”€ NavigationGraph
β”œβ”€β”€ ContentAnalyzer
β”œβ”€β”€ DemoEngine
β”œβ”€β”€ DemoPlan
β”œβ”€β”€ PacingController
β”œβ”€β”€ ErrorRecovery
└── TransitionManager

2. State Detector

Understands and tracks UI state.

StateDetector
β”œβ”€β”€ detectCurrentState()
β”‚   β”œβ”€β”€ Check for modals
β”‚   β”œβ”€β”€ Check for loading indicators
β”‚   β”œβ”€β”€ Check for cookie banners
β”‚   └── Return UIState
β”‚
β”œβ”€β”€ dismissBlockingElements()
β”‚   β”œβ”€β”€ Find all blocking elements
β”‚   β”œβ”€β”€ Try dismiss strategies:
β”‚   β”‚   β”œβ”€β”€ Click close button
β”‚   β”‚   β”œβ”€β”€ Click backdrop
β”‚   β”‚   └── Press Escape
β”‚   └── Verify dismissed
β”‚
└── waitForContentReady()
    β”œβ”€β”€ Wait for network idle
    β”œβ”€β”€ Wait for loading indicators gone
    └── Wait for DOM stable

3. Element Discovery

Finds and categorizes interactive elements.

ElementDiscovery
β”œβ”€β”€ discoverAll()
β”‚   β”œβ”€β”€ findTabs()
β”‚   β”‚   └── Match TAB_PATTERNS
β”‚   β”œβ”€β”€ findAccordions()
β”‚   β”‚   └── Match ACCORDION_PATTERNS
β”‚   β”œβ”€β”€ findDropdowns()
β”‚   β”‚   └── Match DROPDOWN_PATTERNS
β”‚   β”œβ”€β”€ findCarousels()
β”‚   β”‚   └── Match CAROUSEL_PATTERNS
β”‚   └── findHoverElements()
β”‚       └── Check hover states/tooltips
β”‚
└── rankByDemoValue()
    β”œβ”€β”€ Calculate base score
    β”œβ”€β”€ Apply positive modifiers
    β”œβ”€β”€ Apply negative modifiers
    └── Sort by score

4. Navigation Graph

Maps website structure.

NavigationGraph
β”œβ”€β”€ Nodes (Pages)
β”‚   β”œβ”€β”€ id: unique identifier
β”‚   β”œβ”€β”€ url: page URL
β”‚   β”œβ”€β”€ stateHash: for SPA detection
β”‚   β”œβ”€β”€ children: linked pages
β”‚   └── unexploredLinks: links not clicked
β”‚
β”œβ”€β”€ Edges (Transitions)
β”‚   β”œβ”€β”€ from: source node
β”‚   β”œβ”€β”€ to: target node
β”‚   └── via: link used
β”‚
└── Operations
    β”œβ”€β”€ addNode/addEdge
    β”œβ”€β”€ getPath(from, to)
    β”œβ”€β”€ bfs/dfs traversal
    └── findBestNextNode (AI)

5. Content Analyzer

Semantic understanding of page content.

ContentAnalyzer
β”œβ”€β”€ analyzeStructure()
β”‚   β”œβ”€β”€ Take screenshot
β”‚   β”œβ”€β”€ Send to GPT-4o Vision
β”‚   β”œβ”€β”€ Parse sections:
β”‚   β”‚   β”œβ”€β”€ hero
β”‚   β”‚   β”œβ”€β”€ features
β”‚   β”‚   β”œβ”€β”€ pricing
β”‚   β”‚   β”œβ”€β”€ testimonials
β”‚   β”‚   └── cta
β”‚   └── Return PageContent
β”‚
β”œβ”€β”€ extractProductStory()
β”‚   └── Identify problem β†’ solution β†’ features β†’ CTA
β”‚
└── findDemoMoments()
    └── Identify animations, interactions

Data Flow

Demo Generation Pipeline

1. EXPLORE
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ URL β†’ StateDetector.init()                        β”‚
   β”‚    β†’ dismissBlockingElements()                    β”‚
   β”‚    β†’ NavigationGraph.explore()                    β”‚
   β”‚       β”œβ”€β”€ Visit page                              β”‚
   β”‚       β”œβ”€β”€ ElementDiscovery.discoverAll()          β”‚
   β”‚       β”œβ”€β”€ ContentAnalyzer.analyzeStructure()      β”‚
   β”‚       β”œβ”€β”€ ExplorationStrategy.selectNextAction()  β”‚
   β”‚       └── Repeat for each page                    β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
                          β–Ό
2. PLAN
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ NavigationGraph + Analyses β†’ DemoPlan             β”‚
   β”‚    β”œβ”€β”€ optimizeOrder()                            β”‚
   β”‚    β”œβ”€β”€ allocateTime()                             β”‚
   β”‚    β”œβ”€β”€ Generate timeline                          β”‚
   β”‚    └── Generate narrative                         β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
                          β–Ό
3. EXECUTE
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ DemoPlan β†’ DemoEngine.startRecording()            β”‚
   β”‚    FOR each page in plan:                         β”‚
   β”‚       β”œβ”€β”€ TransitionManager.transitionToPage()    β”‚
   β”‚       β”œβ”€β”€ FOR each action in timeline:            β”‚
   β”‚       β”‚   β”œβ”€β”€ PacingController.getAdjustedDurationβ”‚
   β”‚       β”‚   β”œβ”€β”€ Execute action (scroll/click/hover) β”‚
   β”‚       β”‚   β”œβ”€β”€ ErrorRecovery if needed             β”‚
   β”‚       β”‚   └── Update pacing                       β”‚
   β”‚       └── TransitionManager.transitionToSection() β”‚
   β”‚    DemoEngine.stopRecording()                     β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
                          β–Ό
4. FINALIZE
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ Raw recording β†’ Post-processing                   β”‚
   β”‚    β”œβ”€β”€ Add cursor overlay                         β”‚
   β”‚    β”œβ”€β”€ Add click effects                          β”‚
   β”‚    β”œβ”€β”€ Generate voiceover (TTS)                   β”‚
   β”‚    β”œβ”€β”€ Mix audio                                  β”‚
   β”‚    └── Export final video                         β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

State Detection Flow

Page Load
    β”‚
    β–Ό
detectCurrentState()
    β”‚
    β”œβ”€β”€β”€ Normal ──────────────────────────► Continue demo
    β”‚
    β”œβ”€β”€β”€ Modal ───────► dismissBlockingElements()
    β”‚                        β”‚
    β”‚                        β”œβ”€β”€β”€ Success ──► Continue demo
    β”‚                        β”‚
    β”‚                        └─── Failed ───► Skip/Fallback
    β”‚
    β”œβ”€β”€β”€ Loading ─────► waitForContentReady()
    β”‚                        β”‚
    β”‚                        └─── Ready ────► Continue demo
    β”‚
    └─── Cookie ──────► acceptCookies()
                             β”‚
                             └─── Accepted ─► Continue demo

Element Discovery Flow

discoverAll()
    β”‚
    β”œβ”€β”€ Query DOM for patterns
    β”‚   β”œβ”€β”€ Tab patterns
    β”‚   β”œβ”€β”€ Accordion patterns
    β”‚   β”œβ”€β”€ Dropdown patterns
    β”‚   β”œβ”€β”€ Carousel patterns
    β”‚   └── Hover elements
    β”‚
    β”œβ”€β”€ Create InteractiveElement objects
    β”‚   β”œβ”€β”€ Extract position
    β”‚   β”œβ”€β”€ Extract text
    β”‚   └── Determine visibility
    β”‚
    β”œβ”€β”€ Calculate demo scores
    β”‚   β”œβ”€β”€ Type bonus (tabs +20, carousel +15)
    β”‚   β”œβ”€β”€ Text analysis (feature +15, demo +15)
    β”‚   β”œβ”€β”€ Position (above fold +10)
    β”‚   └── Penalties (login -30, legal -40)
    β”‚
    └── Return sorted list
explore(startUrl)
    β”‚
    β”œβ”€β”€ Create root node
    β”‚
    β”œβ”€β”€ Visit page
    β”‚   β”œβ”€β”€ Wait for content ready
    β”‚   β”œβ”€β”€ Extract links
    β”‚   └── Store in node.unexploredLinks
    β”‚
    β”œβ”€β”€ While unexplored links exist:
    β”‚   β”‚
    β”‚   β”œβ”€β”€ ExplorationStrategy.selectNextAction()
    β”‚   β”‚   β”‚
    β”‚   β”‚   β”œβ”€β”€ 'click' ──► Click link
    β”‚   β”‚   β”‚               β”œβ”€β”€ Create child node
    β”‚   β”‚   β”‚               β”œβ”€β”€ Add edge
    β”‚   β”‚   β”‚               β”œβ”€β”€ Recursively explore
    β”‚   β”‚   β”‚               └── Navigate back
    β”‚   β”‚   β”‚
    β”‚   β”‚   β”œβ”€β”€ 'back' ───► Navigate to parent
    β”‚   β”‚   β”‚
    β”‚   β”‚   └── 'done' ───► Stop exploring this node
    β”‚   β”‚
    β”‚   └── Mark link as explored
    β”‚
    └── Return NavigationGraph

Error Handling

Error Classification

Error
  β”‚
  β”œβ”€β”€ Navigation Failed
  β”‚   └── Strategy: Reload page, retry
  β”‚
  β”œβ”€β”€ Element Not Found
  β”‚   └── Strategy: Find alternatives or skip
  β”‚
  β”œβ”€β”€ Modal Blocked
  β”‚   └── Strategy: Dismiss modal, retry
  β”‚
  β”œβ”€β”€ Timeout
  β”‚   └── Strategy: Skip action
  β”‚
  └── Unknown
      └── Strategy: Log and skip

Recovery Flow

Error occurs
    β”‚
    β–Ό
ErrorRecovery.recover(error, context)
    β”‚
    β”œβ”€β”€ Classify error
    β”‚
    β”œβ”€β”€ Get strategy for error type
    β”‚
    β”œβ”€β”€ Execute strategy (up to maxRetries)
    β”‚   β”‚
    β”‚   β”œβ”€β”€ 'retry' ──► Return to action
    β”‚   β”‚
    β”‚   β”œβ”€β”€ 'skip' ───► Continue to next action
    β”‚   β”‚
    β”‚   └── 'abort' ──► Fallback demo
    β”‚
    └── Return result

AI Integration Points

GPT-4o Vision (Content Analysis)

Screenshot (base64)
    β”‚
    β–Ό
Compress to 1024px, JPEG 80%
    β”‚
    β–Ό
OpenAI GPT-4o Chat Completion
    β”‚
    β”œβ”€β”€ System prompt: Analysis instructions
    β”‚
    └── User prompt: Image + context
    β”‚
    β–Ό
Parse JSON response
    β”‚
    β–Ό
PageContent object

GPT-4o Mini (Decision Making)

Context (current state, options)
    β”‚
    β–Ό
OpenAI GPT-4o-mini Chat Completion
    β”‚
    β”œβ”€β”€ System: Decision criteria
    β”‚
    └── User: Current situation + options
    β”‚
    β–Ό
Parse JSON response
    β”‚
    β–Ό
Action decision

Groq (Script Generation)

Analysis results
    β”‚
    β–Ό
Groq API (llama-3.3-70b)
    β”‚
    β”œβ”€β”€ System: Script writing instructions
    β”‚
    └── User: Product info + style + duration
    β”‚
    β–Ό
Voiceover script text

Performance Considerations

Caching Strategy

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Cache Layers               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ L1: In-memory (current session)         β”‚
β”‚     - Page analyses                      β”‚
β”‚     - Element discoveries                β”‚
β”‚     - Navigation graph                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ L2: File-based (cross-session)          β”‚
β”‚     - Content fingerprints               β”‚
β”‚     - Deduplication hashes               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

API Call Optimization

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           API Call Strategy             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Vision (GPT-4o):                        β”‚
β”‚   - 1 call per page (expensive)         β”‚
β”‚   - Use 'low' detail when possible      β”‚
β”‚   - Compress images aggressively        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Decisions (GPT-4o-mini):                β”‚
β”‚   - Batch decisions when possible       β”‚
β”‚   - Use heuristics first, AI fallback   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Scripts (Groq):                         β”‚
β”‚   - 1 call per demo (free tier)         β”‚
β”‚   - Fall back to OpenAI if needed       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

File Structure

src/v2/
β”œβ”€β”€ demo-orchestrator.js     # Main orchestrator
β”œβ”€β”€ demo-plan.js             # Demo planning
β”œβ”€β”€ pacing-controller.js     # Adaptive timing
β”œβ”€β”€ error-recovery.js        # Error handling
β”œβ”€β”€ transition-manager.js    # Page/section transitions
β”œβ”€β”€ state-detector.js        # UI state detection
β”œβ”€β”€ page-state-machine.js    # State machine
β”œβ”€β”€ element-discovery.js     # Element discovery
β”œβ”€β”€ navigation-graph.js      # Site graph
β”œβ”€β”€ spa-detector.js          # SPA handling
β”œβ”€β”€ exploration-strategy.js  # Navigation strategies
β”œβ”€β”€ content-analyzer.js      # Content understanding
β”œβ”€β”€ site-explorer.js         # (existing, enhanced)
β”œβ”€β”€ demo-engine.js           # (existing, enhanced)
β”œβ”€β”€ ai.js                    # (existing, enhanced)
└── interactions.js          # (existing, enhanced)

tests/
β”œβ”€β”€ unit/
β”‚   β”œβ”€β”€ state-detector.test.js
β”‚   β”œβ”€β”€ element-discovery.test.js
β”‚   β”œβ”€β”€ navigation-graph.test.js
β”‚   β”œβ”€β”€ content-analyzer.test.js
β”‚   └── demo-orchestrator.test.js
└── integration/
    └── full-demo.test.js

Extension Points

Custom Element Patterns

// Add custom tab pattern
elementDiscovery.addPattern('tab', {
  container: '.my-tabs',
  tab: '.my-tab',
  panel: '.my-panel'
});

Custom Exploration Strategy

// Create custom strategy
class MyStrategy extends ExplorationStrategy {
  async selectNextAction(node, links) {
    // Custom logic
  }
}

orchestrator.setStrategy(new MyStrategy());

Custom State Handlers

// Add custom modal selector
stateDetector.addModalSelector('.my-custom-modal');

// Add custom dismiss method
stateDetector.addDismissMethod('my-modal', async (page, selector) => {
  await page.click(`${selector} .custom-close`);
});

Custom Content Analyzers

// Add custom section detector
contentAnalyzer.addSectionPattern('pricing-table', {
  selector: '.pricing-grid',
  type: 'pricing',
  demoScoreBonus: 20
});