@rankcli/agent-runtime 0.0.29 → 0.0.31
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.
- package/dist/index.d.mts +249 -151
- package/dist/index.d.ts +249 -151
- package/dist/index.js +354 -302
- package/dist/index.mjs +351 -302
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -3352,7 +3352,9 @@ __export(index_exports, {
|
|
|
3352
3352
|
analyzeUrlSafety: () => analyzeUrlSafety,
|
|
3353
3353
|
analyzers: () => analyzers_exports,
|
|
3354
3354
|
applyFixes: () => applyFixes,
|
|
3355
|
+
assessReplacement: () => assessReplacement,
|
|
3355
3356
|
buildDeterministicFixes: () => buildDeterministicFixes,
|
|
3357
|
+
buildFrameworkGuidance: () => buildFrameworkGuidance,
|
|
3356
3358
|
buildGSCApiRequest: () => buildGSCApiRequest,
|
|
3357
3359
|
buildGSCRequest: () => buildGSCRequest,
|
|
3358
3360
|
calculateAIVisibilityScore: () => calculateAIVisibilityScore,
|
|
@@ -3393,6 +3395,7 @@ __export(index_exports, {
|
|
|
3393
3395
|
createPullRequest: () => createPullRequest,
|
|
3394
3396
|
createSEOCommit: () => createSEOCommit,
|
|
3395
3397
|
createSEOCommits: () => createSEOCommits,
|
|
3398
|
+
describeConcerns: () => describeConcerns,
|
|
3396
3399
|
detectDuplicates: () => detectDuplicates,
|
|
3397
3400
|
detectFramework: () => detectFramework4,
|
|
3398
3401
|
detectGitHubPages: () => detectGitHubPages,
|
|
@@ -3619,6 +3622,7 @@ var RECIPES = {
|
|
|
3619
3622
|
jekyll: null,
|
|
3620
3623
|
eleventy: null,
|
|
3621
3624
|
pelican: null,
|
|
3625
|
+
sphinx: null,
|
|
3622
3626
|
// Unknown
|
|
3623
3627
|
unknown: null
|
|
3624
3628
|
};
|
|
@@ -7738,234 +7742,156 @@ var ISSUE_DEFINITIONS = {
|
|
|
7738
7742
|
// src/audit/engine.ts
|
|
7739
7743
|
init_http();
|
|
7740
7744
|
|
|
7741
|
-
// src/frameworks/
|
|
7742
|
-
var
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
},
|
|
7751
|
-
|
|
7752
|
-
{
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
},
|
|
7758
|
-
|
|
7759
|
-
{
|
|
7760
|
-
|
|
7761
|
-
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
},
|
|
7765
|
-
//
|
|
7766
|
-
{
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
},
|
|
7772
|
-
|
|
7773
|
-
{
|
|
7774
|
-
framework: "sveltekit",
|
|
7775
|
-
language: "typescript",
|
|
7776
|
-
patterns: [/__sveltekit/, /_app\/immutable/, /svelte-kit/],
|
|
7777
|
-
confidence: "high"
|
|
7778
|
-
},
|
|
7779
|
-
// Svelte (standalone)
|
|
7780
|
-
{
|
|
7781
|
-
framework: "svelte",
|
|
7782
|
-
language: "javascript",
|
|
7783
|
-
patterns: [/svelte-\w+/, /__svelte/],
|
|
7784
|
-
confidence: "medium"
|
|
7785
|
-
},
|
|
7786
|
-
// Remix
|
|
7787
|
-
{
|
|
7788
|
-
framework: "remix",
|
|
7789
|
-
language: "typescript",
|
|
7790
|
-
patterns: [/__remix/, /data-remix/],
|
|
7791
|
-
confidence: "high"
|
|
7792
|
-
},
|
|
7793
|
-
// Solid.js
|
|
7794
|
-
{
|
|
7795
|
-
framework: "solidjs",
|
|
7796
|
-
language: "typescript",
|
|
7797
|
-
patterns: [/data-solid/, /_solid/],
|
|
7798
|
-
confidence: "high"
|
|
7799
|
-
},
|
|
7800
|
-
// Qwik
|
|
7801
|
-
{
|
|
7802
|
-
framework: "qwik",
|
|
7803
|
-
language: "typescript",
|
|
7804
|
-
patterns: [/q:container/, /q:base/, /q:version/, /q:id=/, /qwik/],
|
|
7805
|
-
confidence: "high"
|
|
7806
|
-
},
|
|
7807
|
-
// Fresh (Deno)
|
|
7808
|
-
{
|
|
7809
|
-
framework: "fresh",
|
|
7810
|
-
language: "typescript",
|
|
7811
|
-
patterns: [/_frsh\//, /data-fresh/],
|
|
7812
|
-
confidence: "high"
|
|
7813
|
-
},
|
|
7814
|
-
// React (generic - lower priority)
|
|
7745
|
+
// src/frameworks/signals.ts
|
|
7746
|
+
var WEIGHT = { DECISIVE: 100, STRONG: 45, WEAK: 15 };
|
|
7747
|
+
var SCORE_FLOOR = 45;
|
|
7748
|
+
var SIGNALS = [
|
|
7749
|
+
// ---- Meta-frameworks: JavaScript ------------------------------------------------
|
|
7750
|
+
{ framework: "nextjs", language: "typescript", weight: WEIGHT.DECISIVE, name: "next-build-dir", html: /\/_next\/(static|image|data)\// },
|
|
7751
|
+
{ framework: "nextjs", language: "typescript", weight: WEIGHT.DECISIVE, name: "next-data", html: /__NEXT_DATA__|self\.__next_f/ },
|
|
7752
|
+
{ framework: "nextjs", language: "typescript", weight: WEIGHT.DECISIVE, name: "next-mount", html: /<div id=["']__next["']/ },
|
|
7753
|
+
{ framework: "nextjs", language: "typescript", weight: WEIGHT.DECISIVE, name: "next-powered-by", header: /^x-powered-by: next\.js/ },
|
|
7754
|
+
{ framework: "nuxt", language: "typescript", weight: WEIGHT.DECISIVE, name: "nuxt-build-dir", html: /\/_nuxt\// },
|
|
7755
|
+
{ framework: "nuxt", language: "typescript", weight: WEIGHT.DECISIVE, name: "nuxt-payload", html: /__NUXT__|__NUXT_DATA__|<div id="__nuxt"/ },
|
|
7756
|
+
{ framework: "nuxt", language: "typescript", weight: WEIGHT.DECISIVE, name: "nuxt-powered-by", header: /^x-powered-by: nuxt/ },
|
|
7757
|
+
{ framework: "astro", language: "typescript", weight: WEIGHT.DECISIVE, name: "astro-build-dir", html: /\/_astro\// },
|
|
7758
|
+
{ framework: "astro", language: "typescript", weight: WEIGHT.DECISIVE, name: "astro-island", html: /<astro-island|astro-slot|data-astro-(cid|source-file|transition)/ },
|
|
7759
|
+
{ framework: "astro", language: "typescript", weight: WEIGHT.STRONG, name: "astro-generator", html: /name=["']?generator["']?[^>]*content=["']?Astro/i },
|
|
7760
|
+
{ framework: "sveltekit", language: "typescript", weight: WEIGHT.DECISIVE, name: "sveltekit-immutable", html: /\/_app\/immutable\// },
|
|
7761
|
+
{ framework: "sveltekit", language: "typescript", weight: WEIGHT.DECISIVE, name: "sveltekit-runtime", html: /__sveltekit|kit\.start\(/ },
|
|
7762
|
+
{ framework: "remix", language: "typescript", weight: WEIGHT.DECISIVE, name: "remix-context", html: /__remixContext|__remixManifest|__remixRouteModules/ },
|
|
7763
|
+
{ framework: "remix", language: "typescript", weight: WEIGHT.STRONG, name: "remix-build-dir", html: /\/build\/_shared\/|\/build\/entry\.client-/ },
|
|
7764
|
+
{ framework: "gatsby", language: "javascript", weight: WEIGHT.DECISIVE, name: "gatsby-runtime", html: /___gatsby|window\.___chunkMapping/ },
|
|
7765
|
+
{ framework: "gatsby", language: "javascript", weight: WEIGHT.STRONG, name: "gatsby-page-data", html: /\/page-data\/(app-data\.json|sq\/)/ },
|
|
7766
|
+
{ framework: "qwik", language: "typescript", weight: WEIGHT.DECISIVE, name: "qwik-container", html: /q:container|q:base|q:version|qwikloader/ },
|
|
7767
|
+
{ framework: "fresh", language: "typescript", weight: WEIGHT.DECISIVE, name: "fresh-build-dir", html: /\/_frsh\// },
|
|
7768
|
+
{ framework: "solidjs", language: "typescript", weight: WEIGHT.STRONG, name: "solid-hydration", html: /_\$HY\b|data-hk=["']/ },
|
|
7769
|
+
// ---- Base UI libraries: weaker by nature, and that is the point -----------------
|
|
7770
|
+
{ framework: "angular", language: "typescript", weight: WEIGHT.DECISIVE, name: "angular-version", html: /ng-version=["']/ },
|
|
7771
|
+
{ framework: "angular", language: "typescript", weight: WEIGHT.DECISIVE, name: "angular-content-attr", html: /_ngcontent-|_nghost-/ },
|
|
7772
|
+
{ framework: "react", language: "javascript", weight: WEIGHT.STRONG, name: "react-root-marker", html: /data-reactroot|__reactContainer\$|__REACT_DEVTOOLS/ },
|
|
7773
|
+
// A Vite-built SPA: an empty mount point plus Vite's hashed entry bundle. Two weak facts
|
|
7774
|
+
// that together mean something; either one alone does not.
|
|
7775
|
+
{ framework: "react", language: "javascript", weight: WEIGHT.WEAK, name: "react-empty-root", html: /<div id="root"><\/div>/ },
|
|
7776
|
+
{ framework: "react", language: "javascript", weight: WEIGHT.WEAK, name: "react-refresh", html: /RefreshRuntime|react-refresh/ },
|
|
7815
7777
|
{
|
|
7816
7778
|
framework: "react",
|
|
7817
7779
|
language: "javascript",
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
//
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
{
|
|
7826
|
-
framework: "vue",
|
|
7827
|
-
language: "javascript",
|
|
7828
|
-
patterns: [/data-v-[a-f0-9]+/, /v-cloak/, /__vue/],
|
|
7829
|
-
confidence: "medium"
|
|
7830
|
-
},
|
|
7831
|
-
// Angular
|
|
7832
|
-
{
|
|
7833
|
-
framework: "angular",
|
|
7834
|
-
language: "typescript",
|
|
7835
|
-
patterns: [/ng-version/, /_ngcontent/, /ng-\w+=/, /\[ng/],
|
|
7836
|
-
confidence: "high"
|
|
7837
|
-
},
|
|
7838
|
-
// ============ Hypermedia Frameworks ============
|
|
7839
|
-
// HTMX
|
|
7840
|
-
{
|
|
7841
|
-
framework: "htmx",
|
|
7842
|
-
language: "unknown",
|
|
7843
|
-
patterns: [/hx-get/, /hx-post/, /hx-trigger/, /hx-swap/, /htmx\.org/],
|
|
7844
|
-
confidence: "high"
|
|
7845
|
-
},
|
|
7846
|
-
// Hotwire/Turbo
|
|
7847
|
-
{
|
|
7848
|
-
framework: "hotwire",
|
|
7849
|
-
language: "ruby",
|
|
7850
|
-
patterns: [/turbo-frame/, /turbo-stream/, /data-turbo/],
|
|
7851
|
-
confidence: "high"
|
|
7852
|
-
},
|
|
7853
|
-
// ============ PHP Frameworks ============
|
|
7854
|
-
// WordPress
|
|
7855
|
-
{
|
|
7856
|
-
framework: "wordpress",
|
|
7857
|
-
language: "php",
|
|
7858
|
-
// Technical signatures only. These patterns run over the whole page, so the old
|
|
7859
|
-
// /wordpress/i matched the word anywhere in the copy: rankcli.dev's own "detects
|
|
7860
|
-
// Rails, Django, Laravel, and WordPress" line was enough to detect its React SPA as
|
|
7861
|
-
// WordPress and then tell it to install an SEO plugin. A generator meta tag is the
|
|
7862
|
-
// one place the page says it about itself.
|
|
7863
|
-
patterns: [/wp-content/, /wp-includes/, /wp-json/, /name=["']generator["'][^>]*content=["']WordPress/i],
|
|
7864
|
-
confidence: "high"
|
|
7865
|
-
},
|
|
7866
|
-
// Laravel
|
|
7867
|
-
{
|
|
7868
|
-
framework: "laravel",
|
|
7869
|
-
language: "php",
|
|
7870
|
-
// /laravel/i had the same problem as WordPress above - it matched the word in prose.
|
|
7871
|
-
patterns: [/laravel_session/, /XSRF-TOKEN/, /@csrf/],
|
|
7872
|
-
confidence: "medium"
|
|
7873
|
-
},
|
|
7874
|
-
// Symfony
|
|
7875
|
-
{
|
|
7876
|
-
framework: "symfony",
|
|
7877
|
-
language: "php",
|
|
7878
|
-
// Likewise /symfony/, which matched any lowercase mention.
|
|
7879
|
-
patterns: [/sf2/, /_sf_/, /profiler\.css/],
|
|
7880
|
-
confidence: "medium"
|
|
7780
|
+
weight: WEIGHT.STRONG,
|
|
7781
|
+
name: "react-vite-spa",
|
|
7782
|
+
// Vite's entry chunk plus React's conventional mount point. Medium confidence by
|
|
7783
|
+
// construction: #app instead of #root stays unknown, because Vue, Solid and others use it.
|
|
7784
|
+
// Not `<div id="root"></div>`: a prerendered SPA has content inside its mount point, which
|
|
7785
|
+
// is what RankCLI's own site does and what the first version of this signal missed.
|
|
7786
|
+
allHtml: [/<script[^>]+src=["'][^"']+\.js["']/, /<div id="root"[\s>]/]
|
|
7881
7787
|
},
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
{
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
},
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
{
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
},
|
|
7898
|
-
|
|
7899
|
-
{
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
},
|
|
7905
|
-
|
|
7906
|
-
{
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
},
|
|
7912
|
-
|
|
7913
|
-
//
|
|
7914
|
-
{
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
},
|
|
7923
|
-
|
|
7924
|
-
//
|
|
7925
|
-
{
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
//
|
|
7932
|
-
//
|
|
7933
|
-
{
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
patterns: [/phx-/, /live-socket/, /data-phx/],
|
|
7937
|
-
confidence: "high"
|
|
7938
|
-
},
|
|
7939
|
-
// ============ Static Site Generators ============
|
|
7940
|
-
// Hugo
|
|
7941
|
-
{
|
|
7942
|
-
framework: "hugo",
|
|
7943
|
-
language: "go",
|
|
7944
|
-
patterns: [/name=["']generator["'][^>]*content=["']Hugo/i],
|
|
7945
|
-
confidence: "medium"
|
|
7946
|
-
},
|
|
7947
|
-
// Jekyll
|
|
7948
|
-
{
|
|
7949
|
-
framework: "jekyll",
|
|
7950
|
-
language: "ruby",
|
|
7951
|
-
patterns: [/name=["']generator["'][^>]*content=["']Jekyll/i],
|
|
7952
|
-
confidence: "medium"
|
|
7953
|
-
},
|
|
7954
|
-
// Eleventy
|
|
7955
|
-
{
|
|
7956
|
-
framework: "eleventy",
|
|
7957
|
-
language: "javascript",
|
|
7958
|
-
patterns: [/11ty/, /eleventy/, /generator.*eleventy/i],
|
|
7959
|
-
confidence: "medium"
|
|
7960
|
-
},
|
|
7961
|
-
// Pelican
|
|
7962
|
-
{
|
|
7963
|
-
framework: "pelican",
|
|
7964
|
-
language: "python",
|
|
7965
|
-
patterns: [/pelican/, /generator.*pelican/i],
|
|
7966
|
-
confidence: "medium"
|
|
7967
|
-
}
|
|
7788
|
+
{ framework: "vue", language: "javascript", weight: WEIGHT.DECISIVE, name: "vitepress-runtime", html: /__VP_HASH_MAP__|__VP_SITE_DATA__/ },
|
|
7789
|
+
{ framework: "vue", language: "javascript", weight: WEIGHT.DECISIVE, name: "vue-scoped-style", html: /data-v-[0-9a-f]{6,10}\b/ },
|
|
7790
|
+
{ framework: "vue", language: "javascript", weight: WEIGHT.WEAK, name: "vue-cloak", html: /v-cloak|<div id="app"><\/div>/ },
|
|
7791
|
+
{ framework: "svelte", language: "javascript", weight: WEIGHT.WEAK, name: "svelte-class", html: /class=["'][^"']*svelte-[0-9a-z]{6}/ },
|
|
7792
|
+
// ---- Ruby -----------------------------------------------------------------------
|
|
7793
|
+
// csrf-token alone is emitted by Rails, Laravel, Phoenix and Django. csrf-param is Rails.
|
|
7794
|
+
{ framework: "rails", language: "ruby", weight: WEIGHT.DECISIVE, name: "rails-csrf-param", html: /name=["']csrf-param["']/ },
|
|
7795
|
+
{ framework: "rails", language: "ruby", weight: WEIGHT.STRONG, name: "rails-ujs", html: /rails-ujs|turbolinks|data-remote=["']true["']|action_cable|actioncable/ },
|
|
7796
|
+
{ framework: "rails", language: "ruby", weight: WEIGHT.STRONG, name: "rails-session-cookie", header: /^set-cookie: [^;]*_session=/ },
|
|
7797
|
+
{ framework: "rails", language: "ruby", weight: WEIGHT.STRONG, name: "rails-app-server", header: /^(server|x-powered-by): (puma|passenger|unicorn|phusion)/ },
|
|
7798
|
+
{ framework: "hotwire", language: "ruby", weight: WEIGHT.STRONG, name: "turbo-elements", html: /<turbo-frame|<turbo-stream|data-turbo-track/ },
|
|
7799
|
+
// ---- Python ---------------------------------------------------------------------
|
|
7800
|
+
{ framework: "django", language: "python", weight: WEIGHT.DECISIVE, name: "django-csrf-input", html: /name=["']csrfmiddlewaretoken["']/ },
|
|
7801
|
+
{ framework: "django", language: "python", weight: WEIGHT.DECISIVE, name: "django-csrf-cookie", header: /^set-cookie: csrftoken=/ },
|
|
7802
|
+
{ framework: "django", language: "python", weight: WEIGHT.STRONG, name: "django-admin-static", html: /\/static\/admin\/(css|js)\// },
|
|
7803
|
+
{ framework: "django", language: "python", weight: WEIGHT.WEAK, name: "django-wsgi-server", header: /^(server|x-powered-by): (gunicorn|uvicorn|daphne)/ },
|
|
7804
|
+
{ framework: "flask", language: "python", weight: WEIGHT.STRONG, name: "flask-server", header: /^server: werkzeug/ },
|
|
7805
|
+
{ framework: "fastapi", language: "python", weight: WEIGHT.STRONG, name: "fastapi-docs", html: /swagger-ui-bundle\.js[\s\S]{0,200}openapi\.json/ },
|
|
7806
|
+
// ---- PHP ------------------------------------------------------------------------
|
|
7807
|
+
{ framework: "wordpress", language: "php", weight: WEIGHT.DECISIVE, name: "wp-paths", html: /\/wp-content\/|\/wp-includes\/|\/wp-json\// },
|
|
7808
|
+
{ framework: "wordpress", language: "php", weight: WEIGHT.DECISIVE, name: "wp-generator", html: /name=["']?generator["']?[^>]*content=["']?WordPress/i },
|
|
7809
|
+
{ framework: "wordpress", language: "php", weight: WEIGHT.STRONG, name: "wp-powered-by", header: /^x-powered-by: wordpress/ },
|
|
7810
|
+
{ framework: "laravel", language: "php", weight: WEIGHT.DECISIVE, name: "laravel-session-cookie", header: /^set-cookie: laravel_session=/ },
|
|
7811
|
+
{ framework: "laravel", language: "php", weight: WEIGHT.STRONG, name: "laravel-xsrf-cookie", header: /^set-cookie: XSRF-TOKEN=/i },
|
|
7812
|
+
{ framework: "laravel", language: "php", weight: WEIGHT.STRONG, name: "laravel-livewire", html: /livewire|wire:(click|model|submit)/i },
|
|
7813
|
+
{ framework: "laravel", language: "php", weight: WEIGHT.WEAK, name: "laravel-vite-build", html: /\/build\/assets\/app-[A-Za-z0-9_-]{8}\.js/ },
|
|
7814
|
+
{ framework: "symfony", language: "php", weight: WEIGHT.DECISIVE, name: "symfony-profiler", html: /\/_profiler\/|sf-toolbar|sf-dump/ },
|
|
7815
|
+
{ framework: "symfony", language: "php", weight: WEIGHT.STRONG, name: "symfony-cookie", header: /^set-cookie: (sfsession|symfony)/i },
|
|
7816
|
+
// ---- Elixir ---------------------------------------------------------------------
|
|
7817
|
+
{ framework: "phoenix", language: "elixir", weight: WEIGHT.DECISIVE, name: "phoenix-liveview", html: /phx-(click|submit|change|value|hook|socket|main|track-static)/ },
|
|
7818
|
+
{ framework: "phoenix", language: "elixir", weight: WEIGHT.STRONG, name: "phoenix-cowboy", header: /^server: cowboy/ },
|
|
7819
|
+
// ---- Java / C# / Go -------------------------------------------------------------
|
|
7820
|
+
{ framework: "spring", language: "java", weight: WEIGHT.STRONG, name: "thymeleaf-attr", html: /\sth:[a-z-]+=/ },
|
|
7821
|
+
{ framework: "spring", language: "java", weight: WEIGHT.STRONG, name: "spring-server", header: /^server: (apache-coyote|tomcat|jetty)/ },
|
|
7822
|
+
{ framework: "aspnet", language: "csharp", weight: WEIGHT.DECISIVE, name: "aspnet-verification-token", html: /__RequestVerificationToken|__VIEWSTATE/ },
|
|
7823
|
+
{ framework: "aspnet", language: "csharp", weight: WEIGHT.STRONG, name: "aspnet-server", header: /^(server: kestrel|x-powered-by: asp\.net|x-aspnet-version:)/ },
|
|
7824
|
+
// "gin" used to be tested as a substring of the Server header, which matches nginx - the
|
|
7825
|
+
// single most common web server there is. Anchored to the whole value now.
|
|
7826
|
+
{ framework: "go", language: "go", weight: WEIGHT.STRONG, name: "go-server", header: /^server: (gin|echo|fiber|gorilla)(\/|$| )/ },
|
|
7827
|
+
// ---- Hypermedia -----------------------------------------------------------------
|
|
7828
|
+
{ framework: "htmx", language: "unknown", weight: WEIGHT.STRONG, name: "htmx-attrs", html: /\shx-(get|post|put|delete|trigger|swap|target)=/ },
|
|
7829
|
+
{ framework: "htmx", language: "unknown", weight: WEIGHT.DECISIVE, name: "htmx-script", html: /htmx(\.min)?\.js|unpkg\.com\/htmx/ },
|
|
7830
|
+
// ---- Static site generators: they announce themselves -----------------------------
|
|
7831
|
+
{ framework: "hugo", language: "go", weight: WEIGHT.DECISIVE, name: "hugo-generator", html: /name=["']?generator["']?[^>]*content=["']?Hugo/i },
|
|
7832
|
+
{ framework: "hugo", language: "go", weight: WEIGHT.STRONG, name: "hugo-generator-header", header: /^x-generator: hugo/ },
|
|
7833
|
+
{ framework: "jekyll", language: "ruby", weight: WEIGHT.DECISIVE, name: "jekyll-generator", html: /name=["']?generator["']?[^>]*content=["']?Jekyll/i },
|
|
7834
|
+
{ framework: "eleventy", language: "javascript", weight: WEIGHT.DECISIVE, name: "eleventy-generator", html: /name=["']?generator["']?[^>]*content=["']?Eleventy/i },
|
|
7835
|
+
{ framework: "pelican", language: "python", weight: WEIGHT.DECISIVE, name: "pelican-generator", html: /name=["']?generator["']?[^>]*content=["']?Pelican/i },
|
|
7836
|
+
// Sphinx: what nearly every Python project's documentation is built with, and the shape
|
|
7837
|
+
// flask.palletsprojects.com turned out to be. Structural markers only - not the word
|
|
7838
|
+
// "sphinx", which appears in plenty of prose.
|
|
7839
|
+
{ framework: "sphinx", language: "python", weight: WEIGHT.DECISIVE, name: "sphinx-doc-options", html: /_static\/documentation_options\.js/ },
|
|
7840
|
+
{ framework: "sphinx", language: "python", weight: WEIGHT.STRONG, name: "sphinx-theme-markup", html: /class=["'][^"']*sphinxsidebar|sphinx-highlight|_static\/searchtools\.js/ },
|
|
7841
|
+
{ framework: "sphinx", language: "python", weight: WEIGHT.STRONG, name: "docutils-generator", html: /name=["']?generator["']?[^>]*content=["']?Docutils/i }
|
|
7968
7842
|
];
|
|
7843
|
+
function headerLines(headers) {
|
|
7844
|
+
if (!headers) return "";
|
|
7845
|
+
return Object.entries(headers).map(([k, v]) => `${k.toLowerCase()}: ${String(v).toLowerCase()}`).join("\n");
|
|
7846
|
+
}
|
|
7847
|
+
function detectFromEvidence(input) {
|
|
7848
|
+
const html = input.html ?? "";
|
|
7849
|
+
const headers = headerLines(input.headers);
|
|
7850
|
+
const byFramework = /* @__PURE__ */ new Map();
|
|
7851
|
+
for (const signal of SIGNALS) {
|
|
7852
|
+
const headerHit = signal.header && headers && new RegExp(
|
|
7853
|
+
signal.header.source,
|
|
7854
|
+
signal.header.flags.includes("m") ? signal.header.flags : `${signal.header.flags}m`
|
|
7855
|
+
).test(headers);
|
|
7856
|
+
const allHit = signal.allHtml && html && signal.allHtml.every((re) => re.test(html));
|
|
7857
|
+
const hit = signal.html && html && signal.html.test(html) || headerHit || allHit;
|
|
7858
|
+
if (!hit) continue;
|
|
7859
|
+
const existing = byFramework.get(signal.framework);
|
|
7860
|
+
if (existing) {
|
|
7861
|
+
existing.score += signal.weight;
|
|
7862
|
+
existing.matched.push(signal.name);
|
|
7863
|
+
} else {
|
|
7864
|
+
byFramework.set(signal.framework, {
|
|
7865
|
+
framework: signal.framework,
|
|
7866
|
+
language: signal.language,
|
|
7867
|
+
score: signal.weight,
|
|
7868
|
+
matched: [signal.name]
|
|
7869
|
+
});
|
|
7870
|
+
}
|
|
7871
|
+
}
|
|
7872
|
+
const ranked = [...byFramework.values()].sort((a, b) => b.score - a.score || a.framework.localeCompare(b.framework));
|
|
7873
|
+
const best = ranked[0];
|
|
7874
|
+
if (!best || best.score < SCORE_FLOOR) {
|
|
7875
|
+
return {
|
|
7876
|
+
framework: "unknown",
|
|
7877
|
+
language: "unknown",
|
|
7878
|
+
confidence: "low",
|
|
7879
|
+
score: best?.score ?? 0,
|
|
7880
|
+
matched: best?.matched ?? [],
|
|
7881
|
+
alternatives: ranked
|
|
7882
|
+
};
|
|
7883
|
+
}
|
|
7884
|
+
return {
|
|
7885
|
+
framework: best.framework,
|
|
7886
|
+
language: best.language,
|
|
7887
|
+
confidence: best.score >= WEIGHT.DECISIVE ? "high" : "medium",
|
|
7888
|
+
score: best.score,
|
|
7889
|
+
matched: best.matched,
|
|
7890
|
+
alternatives: ranked.slice(1)
|
|
7891
|
+
};
|
|
7892
|
+
}
|
|
7893
|
+
|
|
7894
|
+
// src/frameworks/detector.ts
|
|
7969
7895
|
var PACKAGE_DEPENDENCIES = [
|
|
7970
7896
|
// Meta-frameworks (check first - more specific)
|
|
7971
7897
|
{ framework: "nextjs", language: "typescript", packages: ["next"], meta_framework: "react" },
|
|
@@ -8015,19 +7941,14 @@ var ELIXIR_DEPENDENCIES = [
|
|
|
8015
7941
|
{ framework: "phoenix", language: "elixir", packages: [":phoenix", "phoenix"] }
|
|
8016
7942
|
];
|
|
8017
7943
|
function detectFromHtml(html) {
|
|
8018
|
-
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
8024
|
-
|
|
8025
|
-
|
|
8026
|
-
};
|
|
8027
|
-
}
|
|
8028
|
-
}
|
|
8029
|
-
}
|
|
8030
|
-
return null;
|
|
7944
|
+
const result = detectFromEvidence({ html });
|
|
7945
|
+
if (result.framework === "unknown") return null;
|
|
7946
|
+
return {
|
|
7947
|
+
framework: result.framework,
|
|
7948
|
+
language: result.language,
|
|
7949
|
+
confidence: result.confidence,
|
|
7950
|
+
detected_from: "html"
|
|
7951
|
+
};
|
|
8031
7952
|
}
|
|
8032
7953
|
function detectFromPackageJson(packageJson) {
|
|
8033
7954
|
const allDeps = {
|
|
@@ -8169,52 +8090,14 @@ function detectFromMixExs(mixContent) {
|
|
|
8169
8090
|
return null;
|
|
8170
8091
|
}
|
|
8171
8092
|
function detectFromHeaders(headers) {
|
|
8172
|
-
const
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
}
|
|
8181
|
-
if (poweredBy.includes("remix")) {
|
|
8182
|
-
return { framework: "remix", language: "typescript", confidence: "high", detected_from: "headers" };
|
|
8183
|
-
}
|
|
8184
|
-
if (poweredBy.includes("phusion") || poweredBy.includes("passenger") || poweredBy.includes("puma") || poweredBy.includes("unicorn")) {
|
|
8185
|
-
return { framework: "rails", language: "ruby", confidence: "medium", detected_from: "headers" };
|
|
8186
|
-
}
|
|
8187
|
-
if (poweredBy.includes("gunicorn") || poweredBy.includes("uvicorn") || poweredBy.includes("daphne")) {
|
|
8188
|
-
return null;
|
|
8189
|
-
}
|
|
8190
|
-
if (poweredBy.includes("php")) {
|
|
8191
|
-
return null;
|
|
8192
|
-
}
|
|
8193
|
-
if (server.includes("tomcat") || server.includes("jetty") || poweredBy.includes("spring")) {
|
|
8194
|
-
return { framework: "spring", language: "java", confidence: "medium", detected_from: "headers" };
|
|
8195
|
-
}
|
|
8196
|
-
if (poweredBy.includes("asp.net") || server.includes("kestrel")) {
|
|
8197
|
-
return { framework: "aspnet", language: "csharp", confidence: "high", detected_from: "headers" };
|
|
8198
|
-
}
|
|
8199
|
-
if (poweredBy.includes("phoenix") || poweredBy.includes("cowboy")) {
|
|
8200
|
-
return { framework: "phoenix", language: "elixir", confidence: "medium", detected_from: "headers" };
|
|
8201
|
-
}
|
|
8202
|
-
if (server.includes("gin") || server.includes("echo") || server.includes("fiber")) {
|
|
8203
|
-
return { framework: "go", language: "go", confidence: "medium", detected_from: "headers" };
|
|
8204
|
-
}
|
|
8205
|
-
if (generator.includes("hugo")) {
|
|
8206
|
-
return { framework: "hugo", language: "go", confidence: "high", detected_from: "headers" };
|
|
8207
|
-
}
|
|
8208
|
-
if (generator.includes("jekyll")) {
|
|
8209
|
-
return { framework: "jekyll", language: "ruby", confidence: "high", detected_from: "headers" };
|
|
8210
|
-
}
|
|
8211
|
-
if (generator.includes("eleventy") || generator.includes("11ty")) {
|
|
8212
|
-
return { framework: "eleventy", language: "javascript", confidence: "high", detected_from: "headers" };
|
|
8213
|
-
}
|
|
8214
|
-
if (generator.includes("pelican")) {
|
|
8215
|
-
return { framework: "pelican", language: "python", confidence: "high", detected_from: "headers" };
|
|
8216
|
-
}
|
|
8217
|
-
return null;
|
|
8093
|
+
const result = detectFromEvidence({ headers });
|
|
8094
|
+
if (result.framework === "unknown") return null;
|
|
8095
|
+
return {
|
|
8096
|
+
framework: result.framework,
|
|
8097
|
+
language: result.language,
|
|
8098
|
+
confidence: result.confidence,
|
|
8099
|
+
detected_from: "headers"
|
|
8100
|
+
};
|
|
8218
8101
|
}
|
|
8219
8102
|
function detectFramework(options) {
|
|
8220
8103
|
if (options.packageJson) {
|
|
@@ -8249,13 +8132,16 @@ function detectFramework(options) {
|
|
|
8249
8132
|
const result = detectFromMixExs(options.mixExsContent);
|
|
8250
8133
|
if (result) return result;
|
|
8251
8134
|
}
|
|
8252
|
-
if (options.headers) {
|
|
8253
|
-
const result =
|
|
8254
|
-
if (result)
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8135
|
+
if (options.html || options.headers) {
|
|
8136
|
+
const result = detectFromEvidence({ html: options.html, headers: options.headers });
|
|
8137
|
+
if (result.framework !== "unknown") {
|
|
8138
|
+
return {
|
|
8139
|
+
framework: result.framework,
|
|
8140
|
+
language: result.language,
|
|
8141
|
+
confidence: result.confidence,
|
|
8142
|
+
detected_from: options.html ? "html" : "headers"
|
|
8143
|
+
};
|
|
8144
|
+
}
|
|
8259
8145
|
}
|
|
8260
8146
|
if (options.files) {
|
|
8261
8147
|
if (options.files.some((f) => f.includes("next.config"))) {
|
|
@@ -8362,6 +8248,7 @@ function getFrameworkDisplayName(framework) {
|
|
|
8362
8248
|
jekyll: "Jekyll",
|
|
8363
8249
|
eleventy: "Eleventy (11ty)",
|
|
8364
8250
|
pelican: "Pelican",
|
|
8251
|
+
sphinx: "Sphinx",
|
|
8365
8252
|
unknown: "Unknown"
|
|
8366
8253
|
};
|
|
8367
8254
|
return names[framework];
|
|
@@ -12740,20 +12627,20 @@ function findMissingPreconnects(thirdPartyDomains, existingHints) {
|
|
|
12740
12627
|
}
|
|
12741
12628
|
})
|
|
12742
12629
|
);
|
|
12743
|
-
const
|
|
12630
|
+
const missing2 = [];
|
|
12744
12631
|
for (const domain of thirdPartyDomains) {
|
|
12745
12632
|
try {
|
|
12746
12633
|
const hostname = new URL(domain).hostname;
|
|
12747
12634
|
const recommended = CRITICAL_THIRD_PARTIES[hostname] || [domain];
|
|
12748
12635
|
for (const rec of recommended) {
|
|
12749
12636
|
if (!preconnected.has(rec)) {
|
|
12750
|
-
|
|
12637
|
+
missing2.push(rec);
|
|
12751
12638
|
}
|
|
12752
12639
|
}
|
|
12753
12640
|
} catch {
|
|
12754
12641
|
}
|
|
12755
12642
|
}
|
|
12756
|
-
return [...new Set(
|
|
12643
|
+
return [...new Set(missing2)];
|
|
12757
12644
|
}
|
|
12758
12645
|
function analyzeResourceHints(html, url) {
|
|
12759
12646
|
const issues = [];
|
|
@@ -33049,6 +32936,167 @@ function findAppRoot(files) {
|
|
|
33049
32936
|
return `${nonRoot[0]}/`;
|
|
33050
32937
|
}
|
|
33051
32938
|
|
|
32939
|
+
// src/fixer/safety.ts
|
|
32940
|
+
var HTML_EXT = /\.html?$/i;
|
|
32941
|
+
var SOURCE_EXT = /\.(ts|tsx|js|jsx|mjs|cjs|vue|svelte|astro)$/i;
|
|
32942
|
+
function attributeValues(html, pattern) {
|
|
32943
|
+
const found = /* @__PURE__ */ new Set();
|
|
32944
|
+
for (const match of html.matchAll(pattern)) {
|
|
32945
|
+
const value = match[1]?.trim();
|
|
32946
|
+
if (value) found.add(value);
|
|
32947
|
+
}
|
|
32948
|
+
return found;
|
|
32949
|
+
}
|
|
32950
|
+
function scriptSources(html) {
|
|
32951
|
+
return attributeValues(html, /<script[^>]+src=["']([^"']+)["']/gi);
|
|
32952
|
+
}
|
|
32953
|
+
function stylesheetHrefs(html) {
|
|
32954
|
+
return attributeValues(html, /<link[^>]+href=["']([^"']+)["'][^>]*>/gi);
|
|
32955
|
+
}
|
|
32956
|
+
function verificationTokens(html) {
|
|
32957
|
+
const found = /* @__PURE__ */ new Set();
|
|
32958
|
+
for (const match of html.matchAll(/<meta[^>]+name=["']([^"']*(?:site-verification|verify|verification)[^"']*)["'][^>]*>/gi)) {
|
|
32959
|
+
found.add(match[1].toLowerCase());
|
|
32960
|
+
}
|
|
32961
|
+
return found;
|
|
32962
|
+
}
|
|
32963
|
+
function importSpecifiers(source) {
|
|
32964
|
+
const found = /* @__PURE__ */ new Set();
|
|
32965
|
+
for (const match of source.matchAll(/\bfrom\s+["']([^"']+)["']/g)) found.add(match[1]);
|
|
32966
|
+
for (const match of source.matchAll(/\brequire\(\s*["']([^"']+)["']\s*\)/g)) found.add(match[1]);
|
|
32967
|
+
return found;
|
|
32968
|
+
}
|
|
32969
|
+
function missing(before, after) {
|
|
32970
|
+
return [...before].filter((value) => !after.has(value));
|
|
32971
|
+
}
|
|
32972
|
+
function xmlConcern(xml) {
|
|
32973
|
+
const stack = [];
|
|
32974
|
+
for (const match of xml.matchAll(/<\/?([A-Za-z_][\w:.-]*)[^>]*?(\/?)>/g)) {
|
|
32975
|
+
const [tag, name, selfClosing] = match;
|
|
32976
|
+
if (tag.startsWith("<?") || tag.startsWith("<!")) continue;
|
|
32977
|
+
if (tag.startsWith("</")) {
|
|
32978
|
+
if (stack.pop() !== name) return `unbalanced </${name}>`;
|
|
32979
|
+
} else if (!selfClosing) {
|
|
32980
|
+
stack.push(name);
|
|
32981
|
+
}
|
|
32982
|
+
}
|
|
32983
|
+
return stack.length ? `unclosed <${stack[stack.length - 1]}>` : null;
|
|
32984
|
+
}
|
|
32985
|
+
function sitemapUrlCount(xml) {
|
|
32986
|
+
return [...xml.matchAll(/<loc>/gi)].length;
|
|
32987
|
+
}
|
|
32988
|
+
function newestLastmod(xml) {
|
|
32989
|
+
const dates = [...xml.matchAll(/<lastmod>([^<]+)<\/lastmod>/gi)].map((m) => Date.parse(m[1].trim())).filter((t) => !Number.isNaN(t));
|
|
32990
|
+
return dates.length ? Math.max(...dates) : null;
|
|
32991
|
+
}
|
|
32992
|
+
function jsonLdConcerns(html) {
|
|
32993
|
+
const bad = [];
|
|
32994
|
+
for (const match of html.matchAll(/<script[^>]+type=["']application\/ld\+json["'][^>]*>([\s\S]*?)<\/script>/gi)) {
|
|
32995
|
+
try {
|
|
32996
|
+
JSON.parse(match[1]);
|
|
32997
|
+
} catch (error) {
|
|
32998
|
+
bad.push(error.message);
|
|
32999
|
+
}
|
|
33000
|
+
}
|
|
33001
|
+
return bad;
|
|
33002
|
+
}
|
|
33003
|
+
function assessReplacement(path3, original, replacement) {
|
|
33004
|
+
const concerns = [];
|
|
33005
|
+
const add = (code, detail) => concerns.push({ code, detail });
|
|
33006
|
+
if (/\.json$/i.test(path3) || /\.webmanifest$/i.test(path3)) {
|
|
33007
|
+
try {
|
|
33008
|
+
JSON.parse(replacement);
|
|
33009
|
+
} catch (error) {
|
|
33010
|
+
add("invalid_json", error.message);
|
|
33011
|
+
}
|
|
33012
|
+
}
|
|
33013
|
+
if (/\.xml$/i.test(path3)) {
|
|
33014
|
+
const problem = xmlConcern(replacement);
|
|
33015
|
+
if (problem) add("invalid_xml", problem);
|
|
33016
|
+
}
|
|
33017
|
+
if (HTML_EXT.test(path3)) {
|
|
33018
|
+
for (const problem of jsonLdConcerns(replacement)) add("invalid_json_ld", problem);
|
|
33019
|
+
}
|
|
33020
|
+
if (original === null) return concerns;
|
|
33021
|
+
if (replacement.length < original.length * 0.6) {
|
|
33022
|
+
add("shrunk", `${Math.round(replacement.length / original.length * 100)}% of the original length`);
|
|
33023
|
+
}
|
|
33024
|
+
if (HTML_EXT.test(path3)) {
|
|
33025
|
+
for (const tag of ["</head>", "</body>", "</html>"]) {
|
|
33026
|
+
if (original.includes(tag) && !replacement.includes(tag)) add("lost_closing_tag", tag);
|
|
33027
|
+
}
|
|
33028
|
+
const lostScripts = missing(scriptSources(original), scriptSources(replacement));
|
|
33029
|
+
if (lostScripts.length) add("lost_script", lostScripts.join(", "));
|
|
33030
|
+
const lostStyles = missing(stylesheetHrefs(original), stylesheetHrefs(replacement));
|
|
33031
|
+
if (lostStyles.length) add("lost_stylesheet", lostStyles.join(", "));
|
|
33032
|
+
const lostVerification = missing(verificationTokens(original), verificationTokens(replacement));
|
|
33033
|
+
if (lostVerification.length) add("lost_verification", lostVerification.join(", "));
|
|
33034
|
+
}
|
|
33035
|
+
if (SOURCE_EXT.test(path3)) {
|
|
33036
|
+
const lostImports = missing(importSpecifiers(original), importSpecifiers(replacement));
|
|
33037
|
+
if (lostImports.length) add("lost_import", lostImports.join(", "));
|
|
33038
|
+
}
|
|
33039
|
+
if (/sitemap[^/]*\.xml$/i.test(path3)) {
|
|
33040
|
+
const before = sitemapUrlCount(original);
|
|
33041
|
+
const after = sitemapUrlCount(replacement);
|
|
33042
|
+
if (after < before) add("fewer_sitemap_urls", `${before} -> ${after}`);
|
|
33043
|
+
const newestBefore = newestLastmod(original);
|
|
33044
|
+
const newestAfter = newestLastmod(replacement);
|
|
33045
|
+
if (newestBefore !== null && newestAfter !== null && newestAfter < newestBefore) {
|
|
33046
|
+
add(
|
|
33047
|
+
"lastmod_moved_backwards",
|
|
33048
|
+
`${new Date(newestBefore).toISOString().slice(0, 10)} -> ${new Date(newestAfter).toISOString().slice(0, 10)}`
|
|
33049
|
+
);
|
|
33050
|
+
}
|
|
33051
|
+
}
|
|
33052
|
+
return concerns;
|
|
33053
|
+
}
|
|
33054
|
+
function describeConcerns(concerns) {
|
|
33055
|
+
return concerns.map((c) => `${c.code} (${c.detail})`).join("; ");
|
|
33056
|
+
}
|
|
33057
|
+
|
|
33058
|
+
// src/fixer/framework-guidance.ts
|
|
33059
|
+
var DEFAULT_MAX_CHARS = 4e3;
|
|
33060
|
+
function checkBlock(check) {
|
|
33061
|
+
const fix = check.howToFix?.trim();
|
|
33062
|
+
return [
|
|
33063
|
+
`### ${check.title}${check.code ? ` (${check.code})` : ""}`,
|
|
33064
|
+
check.description?.trim(),
|
|
33065
|
+
fix ? `How this framework wants it fixed:
|
|
33066
|
+
${fix}` : null
|
|
33067
|
+
].filter(Boolean).join("\n");
|
|
33068
|
+
}
|
|
33069
|
+
function buildFrameworkGuidance(recipe, options = {}) {
|
|
33070
|
+
if (!recipe) return "";
|
|
33071
|
+
const budget = options.maxChars ?? DEFAULT_MAX_CHARS;
|
|
33072
|
+
const reported = new Set(options.issueCodes ?? []);
|
|
33073
|
+
const header = [
|
|
33074
|
+
`## ${recipe.display_name} conventions`,
|
|
33075
|
+
`Renders on the server by default: ${recipe.ssr_default ? "yes" : "no"}.`,
|
|
33076
|
+
recipe.seo_challenges?.length ? `Known traps in this framework:
|
|
33077
|
+
${recipe.seo_challenges.map((c) => `- ${c}`).join("\n")}` : null
|
|
33078
|
+
].filter(Boolean).join("\n");
|
|
33079
|
+
const checks = recipe.checks ?? [];
|
|
33080
|
+
const relevant = checks.filter((c) => c.code && reported.has(c.code));
|
|
33081
|
+
const rest = checks.filter((c) => !relevant.includes(c));
|
|
33082
|
+
let out = header;
|
|
33083
|
+
let included = 0;
|
|
33084
|
+
for (const check of [...relevant, ...rest]) {
|
|
33085
|
+
const block = checkBlock(check);
|
|
33086
|
+
if (out.length + block.length + 2 > budget) break;
|
|
33087
|
+
out += `
|
|
33088
|
+
|
|
33089
|
+
${block}`;
|
|
33090
|
+
included++;
|
|
33091
|
+
}
|
|
33092
|
+
if (included < checks.length) {
|
|
33093
|
+
out += `
|
|
33094
|
+
|
|
33095
|
+
_(${checks.length - included} more ${recipe.display_name} checks omitted.)_`;
|
|
33096
|
+
}
|
|
33097
|
+
return out;
|
|
33098
|
+
}
|
|
33099
|
+
|
|
33052
33100
|
// src/git/commit-helper.ts
|
|
33053
33101
|
var import_child_process2 = require("child_process");
|
|
33054
33102
|
var import_util2 = require("util");
|
|
@@ -35576,8 +35624,12 @@ async function analyzeComprehensive(html, url, options = {}) {
|
|
|
35576
35624
|
// src/frameworks/index.ts
|
|
35577
35625
|
var frameworks_exports = {};
|
|
35578
35626
|
__export(frameworks_exports, {
|
|
35627
|
+
SCORE_FLOOR: () => SCORE_FLOOR,
|
|
35628
|
+
SIGNALS: () => SIGNALS,
|
|
35579
35629
|
SUPPORTED_FRAMEWORKS: () => SUPPORTED_FRAMEWORKS,
|
|
35630
|
+
WEIGHT: () => WEIGHT,
|
|
35580
35631
|
detectFramework: () => detectFramework,
|
|
35632
|
+
detectFromEvidence: () => detectFromEvidence,
|
|
35581
35633
|
detectFromHeaders: () => detectFromHeaders,
|
|
35582
35634
|
detectFromHtml: () => detectFromHtml,
|
|
35583
35635
|
detectFromPackageJson: () => detectFromPackageJson,
|
|
@@ -35594,19 +35646,16 @@ __export(frameworks_exports, {
|
|
|
35594
35646
|
loadRecipe: () => loadRecipe
|
|
35595
35647
|
});
|
|
35596
35648
|
var SUPPORTED_FRAMEWORKS = [
|
|
35597
|
-
"react",
|
|
35598
|
-
"nextjs",
|
|
35599
|
-
"vue",
|
|
35600
|
-
"nuxt",
|
|
35601
35649
|
"angular",
|
|
35602
|
-
"svelte",
|
|
35603
|
-
"sveltekit",
|
|
35604
35650
|
"astro",
|
|
35605
|
-
"remix",
|
|
35606
|
-
"gatsby",
|
|
35607
|
-
"rails",
|
|
35608
|
-
"laravel",
|
|
35609
35651
|
"django",
|
|
35652
|
+
"laravel",
|
|
35653
|
+
"nextjs",
|
|
35654
|
+
"nuxt",
|
|
35655
|
+
"rails",
|
|
35656
|
+
"react",
|
|
35657
|
+
"sveltekit",
|
|
35658
|
+
"vue",
|
|
35610
35659
|
"wordpress"
|
|
35611
35660
|
];
|
|
35612
35661
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -35656,7 +35705,9 @@ var SUPPORTED_FRAMEWORKS = [
|
|
|
35656
35705
|
analyzeUrlSafety,
|
|
35657
35706
|
analyzers,
|
|
35658
35707
|
applyFixes,
|
|
35708
|
+
assessReplacement,
|
|
35659
35709
|
buildDeterministicFixes,
|
|
35710
|
+
buildFrameworkGuidance,
|
|
35660
35711
|
buildGSCApiRequest,
|
|
35661
35712
|
buildGSCRequest,
|
|
35662
35713
|
calculateAIVisibilityScore,
|
|
@@ -35697,6 +35748,7 @@ var SUPPORTED_FRAMEWORKS = [
|
|
|
35697
35748
|
createPullRequest,
|
|
35698
35749
|
createSEOCommit,
|
|
35699
35750
|
createSEOCommits,
|
|
35751
|
+
describeConcerns,
|
|
35700
35752
|
detectDuplicates,
|
|
35701
35753
|
detectFramework,
|
|
35702
35754
|
detectGitHubPages,
|