|
# retoor <retoor@molodetz.nl>
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
from devplacepy.services.jobs.isslop.analysis.signals import (
|
|
AXIS_ORIGIN,
|
|
SEVERITY_MEDIUM,
|
|
SEVERITY_STRONG,
|
|
SEVERITY_WEAK,
|
|
FileContext,
|
|
Signal,
|
|
)
|
|
|
|
PATH_FRAMEWORK_PATTERNS: tuple[tuple[re.Pattern[str], str, str], ...] = (
|
|
(re.compile(r"(^|/)_next/", re.IGNORECASE), "Next.js build output (_next/)", SEVERITY_WEAK),
|
|
(re.compile(r"(^|/)_nuxt/", re.IGNORECASE), "Nuxt build output (_nuxt/)", SEVERITY_WEAK),
|
|
(re.compile(r"(^|/)_astro/", re.IGNORECASE), "Astro build output (_astro/)", SEVERITY_WEAK),
|
|
(re.compile(r"(^|/)\.svelte-kit/", re.IGNORECASE), "SvelteKit build output", SEVERITY_WEAK),
|
|
(re.compile(r"(^|/)webpack-[0-9a-f]{8,}\.js$", re.IGNORECASE), "Webpack runtime chunk", SEVERITY_WEAK),
|
|
(re.compile(r"(^|/)polyfills-[0-9a-f]{6,}\.js$", re.IGNORECASE), "Bundler polyfills chunk", SEVERITY_WEAK),
|
|
(re.compile(r"(^|/)main-app-[0-9a-f]{6,}\.js$", re.IGNORECASE), "Next.js app-router bundle", SEVERITY_MEDIUM),
|
|
(re.compile(r"(^|/)chunks/app/(page|layout|loading|error|not-found)-[0-9a-f]{6,}\.js$", re.IGNORECASE), "Next.js app-router page bundle", SEVERITY_MEDIUM),
|
|
(re.compile(r"(^|/)framework-[0-9a-f]{8,}\.js$", re.IGNORECASE), "Next.js framework chunk", SEVERITY_WEAK),
|
|
(re.compile(r"(^|/)assets/index-[0-9A-Za-z_-]{8,}\.(js|css)$"), "Vite hashed asset bundle", SEVERITY_WEAK),
|
|
(re.compile(r"(^|/)gptengineer\.js$|(^|/)cdn\.gpteng\.co", re.IGNORECASE), "GPT Engineer / Lovable runtime", SEVERITY_STRONG),
|
|
(re.compile(r"(^|/)lovable-uploads/", re.IGNORECASE), "Lovable uploads directory", SEVERITY_STRONG),
|
|
(re.compile(r"(^|/)gatsby-", re.IGNORECASE), "Gatsby build artifact", SEVERITY_WEAK),
|
|
)
|
|
|
|
VITE_HASH_ASSET = re.compile(r"index-[0-9A-Za-z_-]{8,}\.(js|css)$")
|
|
|
|
CONTENT_FRAMEWORK_PATTERNS: tuple[tuple[re.Pattern[str], str], ...] = (
|
|
(re.compile(r"self\.__next_f|__NEXT_DATA__|next/dist/", re.IGNORECASE), "next.js runtime"),
|
|
(re.compile(r"__nuxt|nuxt\.config", re.IGNORECASE), "nuxt runtime"),
|
|
(re.compile(r"astro-island|astro:", re.IGNORECASE), "astro runtime"),
|
|
(re.compile(r"data-radix|@radix-ui|radix-ui", re.IGNORECASE), "radix primitives"),
|
|
(re.compile(r"lucide", re.IGNORECASE), "lucide icons"),
|
|
(re.compile(r"shadcn|class-variance-authority|\bcn\(", re.IGNORECASE), "shadcn/ui"),
|
|
(re.compile(r"tailwind|--tw-", re.IGNORECASE), "tailwind"),
|
|
(re.compile(r"framer-motion", re.IGNORECASE), "framer motion"),
|
|
(re.compile(r"createClient\([^)]*supabase|supabase\.co", re.IGNORECASE), "supabase backend"),
|
|
(re.compile(r"clerk\.|@clerk/", re.IGNORECASE), "clerk auth"),
|
|
)
|
|
|
|
CONTENT_STRONG_MARKERS: tuple[tuple[re.Pattern[str], str], ...] = (
|
|
(re.compile(r"gpteng|lovable|data-lov-id", re.IGNORECASE), "Lovable/GPT-Engineer marker"),
|
|
(re.compile(r"generated by (v0|bolt|base44|lovable)", re.IGNORECASE), "AI builder attribution"),
|
|
)
|
|
|
|
VIBE_COMBO_THRESHOLD: int = 3
|
|
|
|
|
|
def detect_infrastructure(context: FileContext) -> list[Signal]:
|
|
findings: list[Signal] = []
|
|
relative = context.relative
|
|
|
|
for pattern, title, severity in PATH_FRAMEWORK_PATTERNS:
|
|
if pattern.search(relative):
|
|
weight = 3.0 if severity == SEVERITY_STRONG else (1.0 if severity == SEVERITY_MEDIUM else 0.5)
|
|
findings.append(
|
|
Signal("BUILD_ARTIFACT_PATH", f"Framework build artifact path: {title}", severity, AXIS_ORIGIN, weight, 1, relative)
|
|
)
|
|
break
|
|
|
|
text = context.text
|
|
for pattern, marker in CONTENT_STRONG_MARKERS:
|
|
match = pattern.search(text)
|
|
if match:
|
|
findings.append(
|
|
Signal(
|
|
"AI_BUILDER_FINGERPRINT",
|
|
f"AI builder marker in bundle: {marker}",
|
|
SEVERITY_STRONG,
|
|
AXIS_ORIGIN,
|
|
4.0,
|
|
text.count("\n", 0, match.start()) + 1,
|
|
match.group(0)[:100],
|
|
)
|
|
)
|
|
break
|
|
|
|
stack_hits = [label for pattern, label in CONTENT_FRAMEWORK_PATTERNS if pattern.search(text)]
|
|
if len(stack_hits) >= VIBE_COMBO_THRESHOLD:
|
|
findings.append(
|
|
Signal(
|
|
"VIBE_STACK",
|
|
f"Default AI frontend stack in bundle ({len(stack_hits)} libraries)",
|
|
SEVERITY_STRONG if len(stack_hits) >= 5 else SEVERITY_MEDIUM,
|
|
AXIS_ORIGIN,
|
|
3.0,
|
|
1,
|
|
", ".join(stack_hits[:8]),
|
|
)
|
|
)
|
|
return findings
|