@rankcli/agent-runtime 0.0.30 → 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 +73 -2
- package/dist/index.d.ts +73 -2
- package/dist/index.js +177 -289
- package/dist/index.mjs +177 -289
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -3622,6 +3622,7 @@ var RECIPES = {
|
|
|
3622
3622
|
jekyll: null,
|
|
3623
3623
|
eleventy: null,
|
|
3624
3624
|
pelican: null,
|
|
3625
|
+
sphinx: null,
|
|
3625
3626
|
// Unknown
|
|
3626
3627
|
unknown: null
|
|
3627
3628
|
};
|
|
@@ -7741,234 +7742,156 @@ var ISSUE_DEFINITIONS = {
|
|
|
7741
7742
|
// src/audit/engine.ts
|
|
7742
7743
|
init_http();
|
|
7743
7744
|
|
|
7744
|
-
// src/frameworks/
|
|
7745
|
-
var
|
|
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
|
-
},
|
|
7775
|
-
|
|
7776
|
-
{
|
|
7777
|
-
framework: "sveltekit",
|
|
7778
|
-
language: "typescript",
|
|
7779
|
-
patterns: [/__sveltekit/, /_app\/immutable/, /svelte-kit/],
|
|
7780
|
-
confidence: "high"
|
|
7781
|
-
},
|
|
7782
|
-
// Svelte (standalone)
|
|
7783
|
-
{
|
|
7784
|
-
framework: "svelte",
|
|
7785
|
-
language: "javascript",
|
|
7786
|
-
patterns: [/svelte-\w+/, /__svelte/],
|
|
7787
|
-
confidence: "medium"
|
|
7788
|
-
},
|
|
7789
|
-
// Remix
|
|
7790
|
-
{
|
|
7791
|
-
framework: "remix",
|
|
7792
|
-
language: "typescript",
|
|
7793
|
-
patterns: [/__remix/, /data-remix/],
|
|
7794
|
-
confidence: "high"
|
|
7795
|
-
},
|
|
7796
|
-
// Solid.js
|
|
7797
|
-
{
|
|
7798
|
-
framework: "solidjs",
|
|
7799
|
-
language: "typescript",
|
|
7800
|
-
patterns: [/data-solid/, /_solid/],
|
|
7801
|
-
confidence: "high"
|
|
7802
|
-
},
|
|
7803
|
-
// Qwik
|
|
7804
|
-
{
|
|
7805
|
-
framework: "qwik",
|
|
7806
|
-
language: "typescript",
|
|
7807
|
-
patterns: [/q:container/, /q:base/, /q:version/, /q:id=/, /qwik/],
|
|
7808
|
-
confidence: "high"
|
|
7809
|
-
},
|
|
7810
|
-
// Fresh (Deno)
|
|
7811
|
-
{
|
|
7812
|
-
framework: "fresh",
|
|
7813
|
-
language: "typescript",
|
|
7814
|
-
patterns: [/_frsh\//, /data-fresh/],
|
|
7815
|
-
confidence: "high"
|
|
7816
|
-
},
|
|
7817
|
-
// 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/ },
|
|
7818
7777
|
{
|
|
7819
7778
|
framework: "react",
|
|
7820
7779
|
language: "javascript",
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
//
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
{
|
|
7829
|
-
framework: "vue",
|
|
7830
|
-
language: "javascript",
|
|
7831
|
-
patterns: [/data-v-[a-f0-9]+/, /v-cloak/, /__vue/],
|
|
7832
|
-
confidence: "medium"
|
|
7833
|
-
},
|
|
7834
|
-
// Angular
|
|
7835
|
-
{
|
|
7836
|
-
framework: "angular",
|
|
7837
|
-
language: "typescript",
|
|
7838
|
-
patterns: [/ng-version/, /_ngcontent/, /ng-\w+=/, /\[ng/],
|
|
7839
|
-
confidence: "high"
|
|
7840
|
-
},
|
|
7841
|
-
// ============ Hypermedia Frameworks ============
|
|
7842
|
-
// HTMX
|
|
7843
|
-
{
|
|
7844
|
-
framework: "htmx",
|
|
7845
|
-
language: "unknown",
|
|
7846
|
-
patterns: [/hx-get/, /hx-post/, /hx-trigger/, /hx-swap/, /htmx\.org/],
|
|
7847
|
-
confidence: "high"
|
|
7848
|
-
},
|
|
7849
|
-
// Hotwire/Turbo
|
|
7850
|
-
{
|
|
7851
|
-
framework: "hotwire",
|
|
7852
|
-
language: "ruby",
|
|
7853
|
-
patterns: [/turbo-frame/, /turbo-stream/, /data-turbo/],
|
|
7854
|
-
confidence: "high"
|
|
7855
|
-
},
|
|
7856
|
-
// ============ PHP Frameworks ============
|
|
7857
|
-
// WordPress
|
|
7858
|
-
{
|
|
7859
|
-
framework: "wordpress",
|
|
7860
|
-
language: "php",
|
|
7861
|
-
// Technical signatures only. These patterns run over the whole page, so the old
|
|
7862
|
-
// /wordpress/i matched the word anywhere in the copy: rankcli.dev's own "detects
|
|
7863
|
-
// Rails, Django, Laravel, and WordPress" line was enough to detect its React SPA as
|
|
7864
|
-
// WordPress and then tell it to install an SEO plugin. A generator meta tag is the
|
|
7865
|
-
// one place the page says it about itself.
|
|
7866
|
-
patterns: [/wp-content/, /wp-includes/, /wp-json/, /name=["']generator["'][^>]*content=["']WordPress/i],
|
|
7867
|
-
confidence: "high"
|
|
7868
|
-
},
|
|
7869
|
-
// Laravel
|
|
7870
|
-
{
|
|
7871
|
-
framework: "laravel",
|
|
7872
|
-
language: "php",
|
|
7873
|
-
// /laravel/i had the same problem as WordPress above - it matched the word in prose.
|
|
7874
|
-
patterns: [/laravel_session/, /XSRF-TOKEN/, /@csrf/],
|
|
7875
|
-
confidence: "medium"
|
|
7876
|
-
},
|
|
7877
|
-
// Symfony
|
|
7878
|
-
{
|
|
7879
|
-
framework: "symfony",
|
|
7880
|
-
language: "php",
|
|
7881
|
-
// Likewise /symfony/, which matched any lowercase mention.
|
|
7882
|
-
patterns: [/sf2/, /_sf_/, /profiler\.css/],
|
|
7883
|
-
confidence: "medium"
|
|
7884
|
-
},
|
|
7885
|
-
// ============ Ruby Frameworks ============
|
|
7886
|
-
// Rails
|
|
7887
|
-
{
|
|
7888
|
-
framework: "rails",
|
|
7889
|
-
language: "ruby",
|
|
7890
|
-
patterns: [/csrf-token/, /turbolinks/, /data-turbo/, /rails-ujs/, /action-cable/],
|
|
7891
|
-
confidence: "medium"
|
|
7892
|
-
},
|
|
7893
|
-
// ============ Python Frameworks ============
|
|
7894
|
-
// Django
|
|
7895
|
-
{
|
|
7896
|
-
framework: "django",
|
|
7897
|
-
language: "python",
|
|
7898
|
-
patterns: [/csrfmiddlewaretoken/, /django/, /__debug__\//],
|
|
7899
|
-
confidence: "medium"
|
|
7900
|
-
},
|
|
7901
|
-
// Flask
|
|
7902
|
-
{
|
|
7903
|
-
framework: "flask",
|
|
7904
|
-
language: "python",
|
|
7905
|
-
patterns: [/flask/, /werkzeug/i],
|
|
7906
|
-
confidence: "low"
|
|
7907
|
-
},
|
|
7908
|
-
// FastAPI
|
|
7909
|
-
{
|
|
7910
|
-
framework: "fastapi",
|
|
7911
|
-
language: "python",
|
|
7912
|
-
patterns: [/fastapi/, /openapi\.json/],
|
|
7913
|
-
confidence: "low"
|
|
7914
|
-
},
|
|
7915
|
-
// ============ Java Frameworks ============
|
|
7916
|
-
// Spring Boot
|
|
7917
|
-
{
|
|
7918
|
-
framework: "spring",
|
|
7919
|
-
language: "java",
|
|
7920
|
-
// /th:/ matched "width:" and "height:" in inline CSS, which made almost every styled
|
|
7921
|
-
// page on the web a Spring Boot app - rankcli.dev included, once WordPress stopped
|
|
7922
|
-
// matching first. Thymeleaf attributes are what th: actually means.
|
|
7923
|
-
patterns: [/\sth:[a-z-]+=/, /thymeleaf/, /_csrf/],
|
|
7924
|
-
confidence: "medium"
|
|
7925
|
-
},
|
|
7926
|
-
// ============ C# Frameworks ============
|
|
7927
|
-
// ASP.NET Core
|
|
7928
|
-
{
|
|
7929
|
-
framework: "aspnet",
|
|
7930
|
-
language: "csharp",
|
|
7931
|
-
patterns: [/aspnetcore/, /__RequestVerificationToken/, /_framework\/blazor/],
|
|
7932
|
-
confidence: "medium"
|
|
7933
|
-
},
|
|
7934
|
-
// ============ Elixir Frameworks ============
|
|
7935
|
-
// Phoenix
|
|
7936
|
-
{
|
|
7937
|
-
framework: "phoenix",
|
|
7938
|
-
language: "elixir",
|
|
7939
|
-
patterns: [/phx-/, /live-socket/, /data-phx/],
|
|
7940
|
-
confidence: "high"
|
|
7941
|
-
},
|
|
7942
|
-
// ============ Static Site Generators ============
|
|
7943
|
-
// Hugo
|
|
7944
|
-
{
|
|
7945
|
-
framework: "hugo",
|
|
7946
|
-
language: "go",
|
|
7947
|
-
patterns: [/name=["']generator["'][^>]*content=["']Hugo/i],
|
|
7948
|
-
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>]/]
|
|
7949
7787
|
},
|
|
7950
|
-
|
|
7951
|
-
{
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
},
|
|
7957
|
-
|
|
7958
|
-
{
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
},
|
|
7964
|
-
|
|
7965
|
-
{
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
}
|
|
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 }
|
|
7971
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
|
|
7972
7895
|
var PACKAGE_DEPENDENCIES = [
|
|
7973
7896
|
// Meta-frameworks (check first - more specific)
|
|
7974
7897
|
{ framework: "nextjs", language: "typescript", packages: ["next"], meta_framework: "react" },
|
|
@@ -8018,19 +7941,14 @@ var ELIXIR_DEPENDENCIES = [
|
|
|
8018
7941
|
{ framework: "phoenix", language: "elixir", packages: [":phoenix", "phoenix"] }
|
|
8019
7942
|
];
|
|
8020
7943
|
function detectFromHtml(html) {
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
8024
|
-
|
|
8025
|
-
|
|
8026
|
-
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
};
|
|
8030
|
-
}
|
|
8031
|
-
}
|
|
8032
|
-
}
|
|
8033
|
-
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
|
+
};
|
|
8034
7952
|
}
|
|
8035
7953
|
function detectFromPackageJson(packageJson) {
|
|
8036
7954
|
const allDeps = {
|
|
@@ -8172,52 +8090,14 @@ function detectFromMixExs(mixContent) {
|
|
|
8172
8090
|
return null;
|
|
8173
8091
|
}
|
|
8174
8092
|
function detectFromHeaders(headers) {
|
|
8175
|
-
const
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
}
|
|
8184
|
-
if (poweredBy.includes("remix")) {
|
|
8185
|
-
return { framework: "remix", language: "typescript", confidence: "high", detected_from: "headers" };
|
|
8186
|
-
}
|
|
8187
|
-
if (poweredBy.includes("phusion") || poweredBy.includes("passenger") || poweredBy.includes("puma") || poweredBy.includes("unicorn")) {
|
|
8188
|
-
return { framework: "rails", language: "ruby", confidence: "medium", detected_from: "headers" };
|
|
8189
|
-
}
|
|
8190
|
-
if (poweredBy.includes("gunicorn") || poweredBy.includes("uvicorn") || poweredBy.includes("daphne")) {
|
|
8191
|
-
return null;
|
|
8192
|
-
}
|
|
8193
|
-
if (poweredBy.includes("php")) {
|
|
8194
|
-
return null;
|
|
8195
|
-
}
|
|
8196
|
-
if (server.includes("tomcat") || server.includes("jetty") || poweredBy.includes("spring")) {
|
|
8197
|
-
return { framework: "spring", language: "java", confidence: "medium", detected_from: "headers" };
|
|
8198
|
-
}
|
|
8199
|
-
if (poweredBy.includes("asp.net") || server.includes("kestrel")) {
|
|
8200
|
-
return { framework: "aspnet", language: "csharp", confidence: "high", detected_from: "headers" };
|
|
8201
|
-
}
|
|
8202
|
-
if (poweredBy.includes("phoenix") || poweredBy.includes("cowboy")) {
|
|
8203
|
-
return { framework: "phoenix", language: "elixir", confidence: "medium", detected_from: "headers" };
|
|
8204
|
-
}
|
|
8205
|
-
if (server.includes("gin") || server.includes("echo") || server.includes("fiber")) {
|
|
8206
|
-
return { framework: "go", language: "go", confidence: "medium", detected_from: "headers" };
|
|
8207
|
-
}
|
|
8208
|
-
if (generator.includes("hugo")) {
|
|
8209
|
-
return { framework: "hugo", language: "go", confidence: "high", detected_from: "headers" };
|
|
8210
|
-
}
|
|
8211
|
-
if (generator.includes("jekyll")) {
|
|
8212
|
-
return { framework: "jekyll", language: "ruby", confidence: "high", detected_from: "headers" };
|
|
8213
|
-
}
|
|
8214
|
-
if (generator.includes("eleventy") || generator.includes("11ty")) {
|
|
8215
|
-
return { framework: "eleventy", language: "javascript", confidence: "high", detected_from: "headers" };
|
|
8216
|
-
}
|
|
8217
|
-
if (generator.includes("pelican")) {
|
|
8218
|
-
return { framework: "pelican", language: "python", confidence: "high", detected_from: "headers" };
|
|
8219
|
-
}
|
|
8220
|
-
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
|
+
};
|
|
8221
8101
|
}
|
|
8222
8102
|
function detectFramework(options) {
|
|
8223
8103
|
if (options.packageJson) {
|
|
@@ -8252,13 +8132,16 @@ function detectFramework(options) {
|
|
|
8252
8132
|
const result = detectFromMixExs(options.mixExsContent);
|
|
8253
8133
|
if (result) return result;
|
|
8254
8134
|
}
|
|
8255
|
-
if (options.headers) {
|
|
8256
|
-
const result =
|
|
8257
|
-
if (result)
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
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
|
+
}
|
|
8262
8145
|
}
|
|
8263
8146
|
if (options.files) {
|
|
8264
8147
|
if (options.files.some((f) => f.includes("next.config"))) {
|
|
@@ -8365,6 +8248,7 @@ function getFrameworkDisplayName(framework) {
|
|
|
8365
8248
|
jekyll: "Jekyll",
|
|
8366
8249
|
eleventy: "Eleventy (11ty)",
|
|
8367
8250
|
pelican: "Pelican",
|
|
8251
|
+
sphinx: "Sphinx",
|
|
8368
8252
|
unknown: "Unknown"
|
|
8369
8253
|
};
|
|
8370
8254
|
return names[framework];
|
|
@@ -35740,8 +35624,12 @@ async function analyzeComprehensive(html, url, options = {}) {
|
|
|
35740
35624
|
// src/frameworks/index.ts
|
|
35741
35625
|
var frameworks_exports = {};
|
|
35742
35626
|
__export(frameworks_exports, {
|
|
35627
|
+
SCORE_FLOOR: () => SCORE_FLOOR,
|
|
35628
|
+
SIGNALS: () => SIGNALS,
|
|
35743
35629
|
SUPPORTED_FRAMEWORKS: () => SUPPORTED_FRAMEWORKS,
|
|
35630
|
+
WEIGHT: () => WEIGHT,
|
|
35744
35631
|
detectFramework: () => detectFramework,
|
|
35632
|
+
detectFromEvidence: () => detectFromEvidence,
|
|
35745
35633
|
detectFromHeaders: () => detectFromHeaders,
|
|
35746
35634
|
detectFromHtml: () => detectFromHtml,
|
|
35747
35635
|
detectFromPackageJson: () => detectFromPackageJson,
|