Frontend Inferencer Skill
Purpose
Infer frontend technologies by analyzing collected signals from JavaScript, DOM, HTML, and CSS analysis phases.
Input
Raw signals from Phase 2:
javascript_signals - Global variables, DOM attributes, bundle patterns
html_signals - Meta tags, script URLs, CSS classes
http_signals - Headers (for SPA indicators)
Technology Categories
JavaScript Frameworks
| Technology |
Detection Signals |
Weight |
| React |
window.React, data-reactroot, /_next/ |
30-40 |
| Vue.js |
window.Vue, data-v-*, /_nuxt/ |
30-40 |
| Angular |
ng-version, _ngcontent-*, window.ng |
30-40 |
| Svelte |
window.__svelte, data-svelte-h |
30-35 |
| jQuery |
window.jQuery, window.$ |
25-30 |
| Alpine.js |
window.Alpine, x-data, x-init |
25-30 |
Meta-Frameworks
| Technology |
Detection Signals |
Implies |
Weight |
| Next.js |
NEXT_DATA, /_next/static/ |
React, Node.js |
35-40 |
| Nuxt.js |
window.NUXT, /_nuxt/ |
Vue.js, Node.js |
35-40 |
| Gatsby |
window.___gatsby |
React |
35-40 |
| Remix |
__remixContext |
React |
35-40 |
| SvelteKit |
__sveltekit |
Svelte |
35-40 |
| Astro |
data-astro-* |
- |
30-35 |
CSS Frameworks
| Technology |
Detection Signals |
Weight |
| Bootstrap |
btn btn-, container, navbar, col- |
25-30 |
| Tailwind CSS |
bg-, text-, flex, p-, m- |
25-30 |
| Material UI |
MuiButton, MuiGrid, MuiPaper |
30-35 |
| Ant Design |
ant-btn, ant-card, ant-table |
30-35 |
| Chakra UI |
chakra-* classes |
25-30 |
| Foundation |
button, callout, grid-x |
25-30 |
| Bulma |
button is-*, columns, hero |
25-30 |
UI Component Libraries
| Technology |
Detection Signals |
Weight |
| Radix UI |
data-radix-* |
25-30 |
| Headless UI |
data-headlessui-* |
25-30 |
| shadcn/ui |
Combination of Tailwind + Radix patterns |
20-25 |
State Management
| Technology |
Detection Signals |
Weight |
| Redux |
window.REDUX_DEVTOOLS_EXTENSION |
25-30 |
| MobX |
window.__mobxGlobal |
25-30 |
| Zustand |
Bundle patterns |
20-25 |
| Recoil |
Bundle patterns |
20-25 |
Build Tools (from bundle patterns)
| Technology |
Detection Signals |
Weight |
| Webpack |
/bundle.js, .chunk.js, /vendor.js |
20-25 |
| Vite |
/@vite/, .js?v= |
25-30 |
| Parcel |
/parcel-* |
20-25 |
| esbuild |
Bundle patterns |
20-25 |
| Rollup |
Bundle patterns |
20-25 |
Inference Logic
def infer_frontend_technologies(signals):
results = []
# JavaScript Framework Detection
for framework in FRAMEWORK_PATTERNS:
score = 0
evidence = []
# Check global variables
for global_var in framework.globals:
if global_var in signals.javascript_signals.globals:
score += framework.global_weight
evidence.append(f"{global_var} detected")
# Check DOM attributes
for attr in framework.dom_attributes:
if attr in signals.html_signals.dom_attributes:
score += framework.dom_weight
evidence.append(f"{attr} attribute found")
# Check bundle patterns
for pattern in framework.bundle_patterns:
if pattern in signals.javascript_signals.script_urls:
score += framework.bundle_weight
evidence.append(f"Bundle pattern: {pattern}")
if score > 0:
results.append({
"name": framework.name,
"category": framework.category,
"signals": evidence,
"total_weight": score,
"implies": framework.implies
})
# CSS Framework Detection
for css_framework in CSS_FRAMEWORK_PATTERNS:
matches = count_class_matches(
signals.html_signals.css_classes,
css_framework.patterns
)
if matches >= css_framework.min_matches:
score = css_framework.base_weight + (matches * 2)
results.append({
"name": css_framework.name,
"category": "CSS Framework",
"signals": [f"{matches} class patterns matched"],
"total_weight": score
})
return results
Output
{
"skill": "frontend_inferencer",
"results": {
"technologies": [
{
"name": "React",
"category": "JavaScript Framework",
"version": "18.x (if detectable)",
"signals": [
{
"type": "javascript_global",
"value": "window.React detected",
"source": "https://example.com",
"weight": 30
},
{
"type": "dom_attribute",
"value": "data-reactroot found",
"source": "https://example.com",
"weight": 25
}
],
"total_weight": 55,
"implies": []
},
{
"name": "Next.js",
"category": "Meta-Framework",
"version": "13.x",
"signals": [
{
"type": "javascript_global",
"value": "__NEXT_DATA__ found",
"source": "https://example.com",
"weight": 35
},
{
"type": "bundle_pattern",
"value": "/_next/static/ paths",
"source": "https://example.com",
"weight": 30
}
],
"total_weight": 65,
"implies": ["React", "Node.js"]
},
{
"name": "Tailwind CSS",
"category": "CSS Framework",
"signals": [
{
"type": "css_classes",
"value": "15 Tailwind class patterns matched (bg-*, text-*, flex, p-*, etc.)",
"source": "https://example.com",
"weight": 30
}
],
"total_weight": 30
}
],
"implied_technologies": [
{
"name": "Node.js",
"implied_by": ["Next.js"],
"confidence": "High"
}
],
"summary": {
"primary_framework": "Next.js",
"ui_library": "Tailwind CSS",
"state_management": null,
"build_tool": "Webpack (via Next.js)"
}
}
}
Version Detection
React
// From __REACT_DEVTOOLS_GLOBAL_HOOK__
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.get(1).version
// From React DevTools
window.React.version
Angular
<!-- From ng-version attribute -->
<app-root ng-version="16.2.0">
Next.js
// From __NEXT_DATA__
JSON.parse(document.getElementById('__NEXT_DATA__').textContent).nextVersion
Vue.js
// From Vue instance
window.Vue.version
Confidence Calculation
Frontend Technology Confidence:
High (80-100%):
- Direct framework global detected
- Multiple supporting signals
- Version information available
Medium (50-79%):
- Bundle patterns match
- DOM attributes present
- No direct confirmation
Low (20-49%):
- Only CSS class patterns
- Single indirect signal
- Job posting mention only
Error Handling
- Missing signals: Return empty results for category
- Conflicting signals: Include both with notes
- Version detection failure: Omit version, continue
1---2name: frontend-inferencer3description: Infers frontend technologies including React, Angular, Vue, jQuery, Bootstrap, etc.4---56# Frontend Inferencer Skill78## Purpose910Infer frontend technologies by analyzing collected signals from JavaScript, DOM, HTML, and CSS analysis phases.1112## Input1314Raw signals from Phase 2:15- `javascript_signals` - Global variables, DOM attributes, bundle patterns16- `html_signals` - Meta tags, script URLs, CSS classes17- `http_signals` - Headers (for SPA indicators)1819## Technology Categories2021### JavaScript Frameworks2223| Technology | Detection Signals | Weight |24|------------|-------------------|--------|25| React | window.React, data-reactroot, /_next/ | 30-40 |26| Vue.js | window.Vue, data-v-*, /_nuxt/ | 30-40 |27| Angular | ng-version, _ngcontent-*, window.ng | 30-40 |28| Svelte | window.__svelte, data-svelte-h | 30-35 |29| jQuery | window.jQuery, window.$ | 25-30 |30| Alpine.js | window.Alpine, x-data, x-init | 25-30 |3132### Meta-Frameworks3334| Technology | Detection Signals | Implies | Weight |35|------------|-------------------|---------|--------|36| Next.js | __NEXT_DATA__, /_next/static/ | React, Node.js | 35-40 |37| Nuxt.js | window.__NUXT__, /_nuxt/ | Vue.js, Node.js | 35-40 |38| Gatsby | window.___gatsby | React | 35-40 |39| Remix | __remixContext | React | 35-40 |40| SvelteKit | __sveltekit | Svelte | 35-40 |41| Astro | data-astro-* | - | 30-35 |4243### CSS Frameworks4445| Technology | Detection Signals | Weight |46|------------|-------------------|--------|47| Bootstrap | btn btn-*, container, navbar, col-* | 25-30 |48| Tailwind CSS | bg-*, text-*, flex, p-*, m-* | 25-30 |49| Material UI | MuiButton, MuiGrid, MuiPaper | 30-35 |50| Ant Design | ant-btn, ant-card, ant-table | 30-35 |51| Chakra UI | chakra-* classes | 25-30 |52| Foundation | button, callout, grid-x | 25-30 |53| Bulma | button is-*, columns, hero | 25-30 |5455### UI Component Libraries5657| Technology | Detection Signals | Weight |58|------------|-------------------|--------|59| Radix UI | data-radix-* | 25-30 |60| Headless UI | data-headlessui-* | 25-30 |61| shadcn/ui | Combination of Tailwind + Radix patterns | 20-25 |6263### State Management6465| Technology | Detection Signals | Weight |66|------------|-------------------|--------|67| Redux | window.__REDUX_DEVTOOLS_EXTENSION__ | 25-30 |68| MobX | window.__mobxGlobal | 25-30 |69| Zustand | Bundle patterns | 20-25 |70| Recoil | Bundle patterns | 20-25 |7172### Build Tools (from bundle patterns)7374| Technology | Detection Signals | Weight |75|------------|-------------------|--------|76| Webpack | /bundle.js, .chunk.js, /vendor.js | 20-25 |77| Vite | /@vite/, .js?v= | 25-30 |78| Parcel | /parcel-* | 20-25 |79| esbuild | Bundle patterns | 20-25 |80| Rollup | Bundle patterns | 20-25 |8182## Inference Logic8384```python85def infer_frontend_technologies(signals):86 results = []8788 # JavaScript Framework Detection89 for framework in FRAMEWORK_PATTERNS:90 score = 091 evidence = []9293 # Check global variables94 for global_var in framework.globals:95 if global_var in signals.javascript_signals.globals:96 score += framework.global_weight97 evidence.append(f"{global_var} detected")9899 # Check DOM attributes100 for attr in framework.dom_attributes:101 if attr in signals.html_signals.dom_attributes:102 score += framework.dom_weight103 evidence.append(f"{attr} attribute found")104105 # Check bundle patterns106 for pattern in framework.bundle_patterns:107 if pattern in signals.javascript_signals.script_urls:108 score += framework.bundle_weight109 evidence.append(f"Bundle pattern: {pattern}")110111 if score > 0:112 results.append({113 "name": framework.name,114 "category": framework.category,115 "signals": evidence,116 "total_weight": score,117 "implies": framework.implies118 })119120 # CSS Framework Detection121 for css_framework in CSS_FRAMEWORK_PATTERNS:122 matches = count_class_matches(123 signals.html_signals.css_classes,124 css_framework.patterns125 )126127 if matches >= css_framework.min_matches:128 score = css_framework.base_weight + (matches * 2)129 results.append({130 "name": css_framework.name,131 "category": "CSS Framework",132 "signals": [f"{matches} class patterns matched"],133 "total_weight": score134 })135136 return results137```138139## Output140141```json142{143 "skill": "frontend_inferencer",144 "results": {145 "technologies": [146 {147 "name": "React",148 "category": "JavaScript Framework",149 "version": "18.x (if detectable)",150 "signals": [151 {152 "type": "javascript_global",153 "value": "window.React detected",154 "source": "https://example.com",155 "weight": 30156 },157 {158 "type": "dom_attribute",159 "value": "data-reactroot found",160 "source": "https://example.com",161 "weight": 25162 }163 ],164 "total_weight": 55,165 "implies": []166 },167 {168 "name": "Next.js",169 "category": "Meta-Framework",170 "version": "13.x",171 "signals": [172 {173 "type": "javascript_global",174 "value": "__NEXT_DATA__ found",175 "source": "https://example.com",176 "weight": 35177 },178 {179 "type": "bundle_pattern",180 "value": "/_next/static/ paths",181 "source": "https://example.com",182 "weight": 30183 }184 ],185 "total_weight": 65,186 "implies": ["React", "Node.js"]187 },188 {189 "name": "Tailwind CSS",190 "category": "CSS Framework",191 "signals": [192 {193 "type": "css_classes",194 "value": "15 Tailwind class patterns matched (bg-*, text-*, flex, p-*, etc.)",195 "source": "https://example.com",196 "weight": 30197 }198 ],199 "total_weight": 30200 }201 ],202 "implied_technologies": [203 {204 "name": "Node.js",205 "implied_by": ["Next.js"],206 "confidence": "High"207 }208 ],209 "summary": {210 "primary_framework": "Next.js",211 "ui_library": "Tailwind CSS",212 "state_management": null,213 "build_tool": "Webpack (via Next.js)"214 }215 }216}217```218219## Version Detection220221### React222```javascript223// From __REACT_DEVTOOLS_GLOBAL_HOOK__224window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.get(1).version225226// From React DevTools227window.React.version228```229230### Angular231```html232<!-- From ng-version attribute -->233<app-root ng-version="16.2.0">234```235236### Next.js237```javascript238// From __NEXT_DATA__239JSON.parse(document.getElementById('__NEXT_DATA__').textContent).nextVersion240```241242### Vue.js243```javascript244// From Vue instance245window.Vue.version246```247248## Confidence Calculation249250```251Frontend Technology Confidence:252253High (80-100%):254 - Direct framework global detected255 - Multiple supporting signals256 - Version information available257258Medium (50-79%):259 - Bundle patterns match260 - DOM attributes present261 - No direct confirmation262263Low (20-49%):264 - Only CSS class patterns265 - Single indirect signal266 - Job posting mention only267```268269## Error Handling270271- Missing signals: Return empty results for category272- Conflicting signals: Include both with notes273- Version detection failure: Omit version, continue