-
-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture.md
RoTSL edited this page Feb 14, 2026
·
1 revision
Technical deep-dive into Wisp's design and implementation.
┌─────────────────────────────────────┐
│ Input Sources │
│ (Files, URLs, Raw HTML) │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ Wisp Scanner (Python/JS) │
│ • Content Density Analysis │
│ • Pattern Recognition │
│ • Context Classification │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ CSS Generator │
│ • Design Token Generation │
│ • Variable Injection │
└──────────────┬──────────────────────┘
│
┌──────────────▼──────────────────────┐
│ Output (CSS/HTML) │
│ • Static Files │
│ • Runtime Enhanced │
└─────────────────────────────────────┘
Measures text-to-element ratio:
ρ = min((text_length / element_count) / 500, 1.0)Where:
-
text_length: Total characters of text content -
element_count: Number of DOM elements -
500: Calibrated maximum density constant
Interpretation:
- ρ > 0.7: High density (compact content)
- 0.3 < ρ ≤ 0.7: Medium density (balanced)
- ρ ≤ 0.3: Low density (sparse content)
Classifies content by element distribution:
ratios = {
'prose': paragraphs / total,
'navigational': headings / total,
'structured': lists / total,
'technical': code_blocks / total
}
π = max(ratios, key=ratios.get)Determines presentation archetype:
if tables or cards > 3:
context = 'dashboard'
elif form_inputs >= 2:
context = 'form'
elif pattern == 'prose':
context = 'narrative'
else:
context = 'minimal'Wisp generates design tokens as CSS variables:
:root {
--wisp-context: narrative;
--wisp-density: 0.45;
--wisp-spacing-unit: 1rem;
--wisp-line-height: 1.7;
--wisp-max-width: 65ch;
--wisp-base-font: 1.125rem;
--wisp-motion: 200ms;
}| Context | Line Height | Max Width | Font Size | Spacing |
|---|---|---|---|---|
| narrative | 1.7 | 65ch | 1.125rem | 1.0rem |
| dashboard | 1.4 | 100% | 0.875rem | 0.5rem |
| form | 1.5 | 60ch | 1.0rem | 1.0rem |
| minimal | 1.6 | 70ch | 1.0rem | 1.0rem |
src/core/scanner.py
-
WispScanner: Main analysis class -
ContentAnalysis: Named tuple for results -
analyze_content_density(): Density calculation -
detect_reading_pattern(): Pattern classification -
detect_context(): Context determination
src/core/fetcher.py
-
WispFetcher: URL fetching and processing -
fetch(): HTTP retrieval with sanitization -
extract_content(): Main content extraction -
generate_html(): Standalone HTML output
src/cli/bake.py
- CLI entry point for static generation
- Arguments: input, output, forced_context
scripts/build.py
- Build automation
- Minification (optional)
- Size reporting
scripts/generate_dashboard.py
- HTML dashboard generation
- Visualization of analysis results
src/core/wisp.js
- Browser-side analysis
- DOM API integration
- Dynamic style injection
- Accessibility enhancements
The fetcher removes potentially dangerous content:
removable_tags = ['script', 'iframe', 'nav', 'footer', 'header',
'aside', 'noscript', 'svg']
removable_attrs = ['onclick', 'onload', 'onerror', 'style']Generated HTML includes:
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
style-src 'unsafe-inline';">- Time Complexity: O(n) where n = DOM node count
- Space Complexity: O(1) for analysis, O(k) for CSS generation (k = constant)
No caching required due to speed:
- Single analysis: <1ms
- CSS generation: <0.5ms
- Total overhead: <2ms per page
| Component | Size | Gzipped |
|---|---|---|
| wisp.css | 2.4KB | ~1.0KB |
| wisp.js | 4.3KB | ~1.8KB |
| Total | 6.7KB | ~2.8KB |
| wisp.min.css | 1.9KB | ~0.8KB |
| wisp.min.js | 2.4KB | ~1.0KB |
| Total Min | 4.3KB | ~1.8KB |
if (matchMedia('(prefers-reduced-motion: reduce)').matches) {
// Disable animations
}
if (matchMedia('(prefers-color-scheme: dark)').matches) {
// Use dark theme
}No JavaScript: Base CSS provides full styling No CSS Variables: Graceful degradation to defaults Old Browsers: Semantic HTML remains accessible
- Parse HTML with BeautifulSoup
- Calculate metrics (density, pattern, depth)
- Determine context
- Generate CSS variables
- Inject into template
- Write output file
- Wait for DOMContentLoaded
- Scan body element
- Calculate metrics
- Inject CSS variables
- Add accessibility enhancements
- Set data-wisp-active attribute
-
test_narrative_detection: Verifies prose classification -
test_dashboard_detection: Tests card/table detection -
test_form_detection: Validates input counting -
test_css_generation: Checks output format -
test_density_calculation: Mathematical accuracy
- Fixture-based HTML testing
- Live URL fetching (network)
- End-to-end CLI testing
Every run produces:
- Context classification
- Confidence metrics
- Performance timing
- Generated CSS variables
Interactive charts showing:
- Context distribution
- Density histograms
- Performance benchmarks
- File size metrics