@iflow-mcp/jakeliume-webpeel 0.22.0
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/LICENSE +15 -0
- package/README.md +313 -0
- package/dist/cache.d.ts +30 -0
- package/dist/cache.js +139 -0
- package/dist/cli/commands/auth.d.ts +5 -0
- package/dist/cli/commands/auth.js +411 -0
- package/dist/cli/commands/doctor.d.ts +37 -0
- package/dist/cli/commands/doctor.js +371 -0
- package/dist/cli/commands/fetch.d.ts +6 -0
- package/dist/cli/commands/fetch.js +1345 -0
- package/dist/cli/commands/guide.d.ts +2 -0
- package/dist/cli/commands/guide.js +183 -0
- package/dist/cli/commands/interact.d.ts +5 -0
- package/dist/cli/commands/interact.js +840 -0
- package/dist/cli/commands/jobs.d.ts +5 -0
- package/dist/cli/commands/jobs.js +997 -0
- package/dist/cli/commands/monitor.d.ts +12 -0
- package/dist/cli/commands/monitor.js +197 -0
- package/dist/cli/commands/observe.d.ts +12 -0
- package/dist/cli/commands/observe.js +158 -0
- package/dist/cli/commands/screenshot.d.ts +5 -0
- package/dist/cli/commands/screenshot.js +282 -0
- package/dist/cli/commands/search.d.ts +5 -0
- package/dist/cli/commands/search.js +1021 -0
- package/dist/cli/commands/setup.d.ts +13 -0
- package/dist/cli/commands/setup.js +244 -0
- package/dist/cli/commands/skill.d.ts +15 -0
- package/dist/cli/commands/skill.js +195 -0
- package/dist/cli/utils.d.ts +84 -0
- package/dist/cli/utils.js +806 -0
- package/dist/cli-auth.d.ts +75 -0
- package/dist/cli-auth.js +369 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.js +99 -0
- package/dist/core/actions.d.ts +69 -0
- package/dist/core/actions.js +495 -0
- package/dist/core/agent.d.ts +98 -0
- package/dist/core/agent.js +558 -0
- package/dist/core/answer.d.ts +42 -0
- package/dist/core/answer.js +395 -0
- package/dist/core/application-tracker.d.ts +84 -0
- package/dist/core/application-tracker.js +184 -0
- package/dist/core/apply.d.ts +162 -0
- package/dist/core/apply.js +816 -0
- package/dist/core/auth-detection.d.ts +35 -0
- package/dist/core/auth-detection.js +358 -0
- package/dist/core/auto-extract.d.ts +82 -0
- package/dist/core/auto-extract.js +604 -0
- package/dist/core/auto-interact.d.ts +23 -0
- package/dist/core/auto-interact.js +246 -0
- package/dist/core/bm25-filter.d.ts +66 -0
- package/dist/core/bm25-filter.js +288 -0
- package/dist/core/branding.d.ts +54 -0
- package/dist/core/branding.js +234 -0
- package/dist/core/browser-fetch.d.ts +323 -0
- package/dist/core/browser-fetch.js +1600 -0
- package/dist/core/browser-pool.d.ts +91 -0
- package/dist/core/browser-pool.js +550 -0
- package/dist/core/budget.d.ts +42 -0
- package/dist/core/budget.js +324 -0
- package/dist/core/business-intel.d.ts +47 -0
- package/dist/core/business-intel.js +279 -0
- package/dist/core/cache.d.ts +13 -0
- package/dist/core/cache.js +121 -0
- package/dist/core/cf-worker-proxy.d.ts +32 -0
- package/dist/core/cf-worker-proxy.js +87 -0
- package/dist/core/challenge-detection.d.ts +26 -0
- package/dist/core/challenge-detection.js +468 -0
- package/dist/core/change-tracking.d.ts +75 -0
- package/dist/core/change-tracking.js +276 -0
- package/dist/core/chunker.d.ts +46 -0
- package/dist/core/chunker.js +249 -0
- package/dist/core/chunking.d.ts +42 -0
- package/dist/core/chunking.js +181 -0
- package/dist/core/circuit-breaker.d.ts +44 -0
- package/dist/core/circuit-breaker.js +85 -0
- package/dist/core/content-pruner.d.ts +47 -0
- package/dist/core/content-pruner.js +425 -0
- package/dist/core/cookie-cache.d.ts +60 -0
- package/dist/core/cookie-cache.js +163 -0
- package/dist/core/crawl-checkpoint.d.ts +54 -0
- package/dist/core/crawl-checkpoint.js +104 -0
- package/dist/core/crawler.d.ts +84 -0
- package/dist/core/crawler.js +349 -0
- package/dist/core/cross-verify.d.ts +27 -0
- package/dist/core/cross-verify.js +93 -0
- package/dist/core/deep-fetch.d.ts +74 -0
- package/dist/core/deep-fetch.js +405 -0
- package/dist/core/deep-research.d.ts +141 -0
- package/dist/core/deep-research.js +972 -0
- package/dist/core/design-analysis.d.ts +70 -0
- package/dist/core/design-analysis.js +490 -0
- package/dist/core/design-compare.d.ts +38 -0
- package/dist/core/design-compare.js +264 -0
- package/dist/core/diff.d.ts +61 -0
- package/dist/core/diff.js +289 -0
- package/dist/core/dns-cache.d.ts +20 -0
- package/dist/core/dns-cache.js +198 -0
- package/dist/core/documents.d.ts +23 -0
- package/dist/core/documents.js +123 -0
- package/dist/core/domain-memory.d.ts +66 -0
- package/dist/core/domain-memory.js +163 -0
- package/dist/core/domain-verify.d.ts +40 -0
- package/dist/core/domain-verify.js +379 -0
- package/dist/core/engine-ranker.d.ts +112 -0
- package/dist/core/engine-ranker.js +395 -0
- package/dist/core/extract-inline.d.ts +38 -0
- package/dist/core/extract-inline.js +215 -0
- package/dist/core/extract-listings.d.ts +38 -0
- package/dist/core/extract-listings.js +461 -0
- package/dist/core/extract.d.ts +9 -0
- package/dist/core/extract.js +139 -0
- package/dist/core/fetch-cache.d.ts +57 -0
- package/dist/core/fetch-cache.js +95 -0
- package/dist/core/fetcher.d.ts +13 -0
- package/dist/core/fetcher.js +12 -0
- package/dist/core/google-cache.d.ts +29 -0
- package/dist/core/google-cache.js +180 -0
- package/dist/core/google-serp-parser.d.ts +82 -0
- package/dist/core/google-serp-parser.js +287 -0
- package/dist/core/hotel-search.d.ts +122 -0
- package/dist/core/hotel-search.js +382 -0
- package/dist/core/http-fetch.d.ts +72 -0
- package/dist/core/http-fetch.js +820 -0
- package/dist/core/human.d.ts +175 -0
- package/dist/core/human.js +680 -0
- package/dist/core/image-caption.d.ts +44 -0
- package/dist/core/image-caption.js +271 -0
- package/dist/core/jobs.d.ts +75 -0
- package/dist/core/jobs.js +634 -0
- package/dist/core/json-ld.d.ts +15 -0
- package/dist/core/json-ld.js +617 -0
- package/dist/core/language-detect.d.ts +18 -0
- package/dist/core/language-detect.js +135 -0
- package/dist/core/links.d.ts +10 -0
- package/dist/core/links.js +44 -0
- package/dist/core/llm-extract.d.ts +71 -0
- package/dist/core/llm-extract.js +507 -0
- package/dist/core/llm-provider.d.ts +100 -0
- package/dist/core/llm-provider.js +702 -0
- package/dist/core/local-search.d.ts +60 -0
- package/dist/core/local-search.js +308 -0
- package/dist/core/logger.d.ts +28 -0
- package/dist/core/logger.js +104 -0
- package/dist/core/map.d.ts +33 -0
- package/dist/core/map.js +127 -0
- package/dist/core/markdown.d.ts +92 -0
- package/dist/core/markdown.js +809 -0
- package/dist/core/metadata.d.ts +34 -0
- package/dist/core/metadata.js +422 -0
- package/dist/core/observe.d.ts +113 -0
- package/dist/core/observe.js +395 -0
- package/dist/core/ocr.d.ts +12 -0
- package/dist/core/ocr.js +33 -0
- package/dist/core/paginate.d.ts +31 -0
- package/dist/core/paginate.js +106 -0
- package/dist/core/pdf.d.ts +8 -0
- package/dist/core/pdf.js +25 -0
- package/dist/core/peel-tls.d.ts +25 -0
- package/dist/core/peel-tls.js +220 -0
- package/dist/core/pipeline.d.ts +132 -0
- package/dist/core/pipeline.js +1666 -0
- package/dist/core/profiles.d.ts +61 -0
- package/dist/core/profiles.js +350 -0
- package/dist/core/prompt-guard.d.ts +30 -0
- package/dist/core/prompt-guard.js +119 -0
- package/dist/core/proxy-config.d.ts +90 -0
- package/dist/core/proxy-config.js +172 -0
- package/dist/core/quick-answer.d.ts +53 -0
- package/dist/core/quick-answer.js +833 -0
- package/dist/core/rate-governor.d.ts +80 -0
- package/dist/core/rate-governor.js +238 -0
- package/dist/core/readability.d.ts +57 -0
- package/dist/core/readability.js +533 -0
- package/dist/core/research.d.ts +66 -0
- package/dist/core/research.js +270 -0
- package/dist/core/retry.d.ts +60 -0
- package/dist/core/retry.js +119 -0
- package/dist/core/safe-browsing.d.ts +30 -0
- package/dist/core/safe-browsing.js +206 -0
- package/dist/core/schema-extraction.d.ts +66 -0
- package/dist/core/schema-extraction.js +352 -0
- package/dist/core/schema-postprocess.d.ts +32 -0
- package/dist/core/schema-postprocess.js +469 -0
- package/dist/core/schema-templates.d.ts +19 -0
- package/dist/core/schema-templates.js +143 -0
- package/dist/core/screenshot.d.ts +224 -0
- package/dist/core/screenshot.js +207 -0
- package/dist/core/search-engines.d.ts +25 -0
- package/dist/core/search-engines.js +182 -0
- package/dist/core/search-provider.d.ts +243 -0
- package/dist/core/search-provider.js +1629 -0
- package/dist/core/searxng-provider.d.ts +35 -0
- package/dist/core/searxng-provider.js +105 -0
- package/dist/core/selective-evidence.d.ts +151 -0
- package/dist/core/selective-evidence.js +389 -0
- package/dist/core/site-search.d.ts +44 -0
- package/dist/core/site-search.js +252 -0
- package/dist/core/sitemap.d.ts +23 -0
- package/dist/core/sitemap.js +105 -0
- package/dist/core/source-credibility.d.ts +29 -0
- package/dist/core/source-credibility.js +584 -0
- package/dist/core/source-scoring.d.ts +166 -0
- package/dist/core/source-scoring.js +396 -0
- package/dist/core/stemmer.d.ts +38 -0
- package/dist/core/stemmer.js +509 -0
- package/dist/core/strategies.d.ts +104 -0
- package/dist/core/strategies.js +1044 -0
- package/dist/core/strategy-hooks.d.ts +145 -0
- package/dist/core/strategy-hooks.js +74 -0
- package/dist/core/structured-extract.d.ts +43 -0
- package/dist/core/structured-extract.js +550 -0
- package/dist/core/summarize.d.ts +17 -0
- package/dist/core/summarize.js +78 -0
- package/dist/core/synonyms.d.ts +42 -0
- package/dist/core/synonyms.js +184 -0
- package/dist/core/system-monitor.d.ts +61 -0
- package/dist/core/system-monitor.js +133 -0
- package/dist/core/table-format.d.ts +30 -0
- package/dist/core/table-format.js +146 -0
- package/dist/core/threat-feeds.d.ts +23 -0
- package/dist/core/threat-feeds.js +104 -0
- package/dist/core/timing.d.ts +21 -0
- package/dist/core/timing.js +33 -0
- package/dist/core/transcript-export.d.ts +47 -0
- package/dist/core/transcript-export.js +107 -0
- package/dist/core/user-agents.d.ts +82 -0
- package/dist/core/user-agents.js +239 -0
- package/dist/core/vertical-search.d.ts +54 -0
- package/dist/core/vertical-search.js +158 -0
- package/dist/core/watch-manager.d.ts +175 -0
- package/dist/core/watch-manager.js +416 -0
- package/dist/core/watch.d.ts +101 -0
- package/dist/core/watch.js +389 -0
- package/dist/core/youtube.d.ts +130 -0
- package/dist/core/youtube.js +1175 -0
- package/dist/ee/challenge-re-export.d.ts +1 -0
- package/dist/ee/challenge-re-export.js +1 -0
- package/dist/ee/challenge-solver.d.ts +72 -0
- package/dist/ee/challenge-solver.js +720 -0
- package/dist/ee/domain-extractors.d.ts +8 -0
- package/dist/ee/domain-extractors.js +8 -0
- package/dist/ee/domain-intel.d.ts +16 -0
- package/dist/ee/domain-intel.js +133 -0
- package/dist/ee/extractors/allrecipes.d.ts +2 -0
- package/dist/ee/extractors/allrecipes.js +120 -0
- package/dist/ee/extractors/amazon.d.ts +2 -0
- package/dist/ee/extractors/amazon.js +78 -0
- package/dist/ee/extractors/arxiv.d.ts +2 -0
- package/dist/ee/extractors/arxiv.js +137 -0
- package/dist/ee/extractors/bestbuy.d.ts +2 -0
- package/dist/ee/extractors/bestbuy.js +78 -0
- package/dist/ee/extractors/carscom.d.ts +2 -0
- package/dist/ee/extractors/carscom.js +121 -0
- package/dist/ee/extractors/coingecko.d.ts +2 -0
- package/dist/ee/extractors/coingecko.js +134 -0
- package/dist/ee/extractors/craigslist.d.ts +2 -0
- package/dist/ee/extractors/craigslist.js +92 -0
- package/dist/ee/extractors/devto.d.ts +2 -0
- package/dist/ee/extractors/devto.js +135 -0
- package/dist/ee/extractors/ebay.d.ts +2 -0
- package/dist/ee/extractors/ebay.js +90 -0
- package/dist/ee/extractors/espn.d.ts +2 -0
- package/dist/ee/extractors/espn.js +260 -0
- package/dist/ee/extractors/etsy.d.ts +2 -0
- package/dist/ee/extractors/etsy.js +52 -0
- package/dist/ee/extractors/facebook.d.ts +2 -0
- package/dist/ee/extractors/facebook.js +46 -0
- package/dist/ee/extractors/github.d.ts +2 -0
- package/dist/ee/extractors/github.js +196 -0
- package/dist/ee/extractors/google-flights.d.ts +2 -0
- package/dist/ee/extractors/google-flights.js +176 -0
- package/dist/ee/extractors/hackernews.d.ts +2 -0
- package/dist/ee/extractors/hackernews.js +147 -0
- package/dist/ee/extractors/imdb.d.ts +2 -0
- package/dist/ee/extractors/imdb.js +172 -0
- package/dist/ee/extractors/index.d.ts +26 -0
- package/dist/ee/extractors/index.js +247 -0
- package/dist/ee/extractors/instagram.d.ts +2 -0
- package/dist/ee/extractors/instagram.js +102 -0
- package/dist/ee/extractors/kalshi.d.ts +2 -0
- package/dist/ee/extractors/kalshi.js +121 -0
- package/dist/ee/extractors/kayak-cars.d.ts +2 -0
- package/dist/ee/extractors/kayak-cars.js +270 -0
- package/dist/ee/extractors/linkedin.d.ts +2 -0
- package/dist/ee/extractors/linkedin.js +113 -0
- package/dist/ee/extractors/medium.d.ts +2 -0
- package/dist/ee/extractors/medium.js +130 -0
- package/dist/ee/extractors/news.d.ts +4 -0
- package/dist/ee/extractors/news.js +173 -0
- package/dist/ee/extractors/npm.d.ts +2 -0
- package/dist/ee/extractors/npm.js +86 -0
- package/dist/ee/extractors/pdf.d.ts +2 -0
- package/dist/ee/extractors/pdf.js +108 -0
- package/dist/ee/extractors/pinterest.d.ts +2 -0
- package/dist/ee/extractors/pinterest.js +34 -0
- package/dist/ee/extractors/polymarket.d.ts +2 -0
- package/dist/ee/extractors/polymarket.js +358 -0
- package/dist/ee/extractors/producthunt.d.ts +2 -0
- package/dist/ee/extractors/producthunt.js +88 -0
- package/dist/ee/extractors/pubmed.d.ts +2 -0
- package/dist/ee/extractors/pubmed.js +162 -0
- package/dist/ee/extractors/pypi.d.ts +2 -0
- package/dist/ee/extractors/pypi.js +80 -0
- package/dist/ee/extractors/reddit.d.ts +2 -0
- package/dist/ee/extractors/reddit.js +438 -0
- package/dist/ee/extractors/redfin.d.ts +2 -0
- package/dist/ee/extractors/redfin.js +156 -0
- package/dist/ee/extractors/semanticscholar.d.ts +2 -0
- package/dist/ee/extractors/semanticscholar.js +131 -0
- package/dist/ee/extractors/shared.d.ts +12 -0
- package/dist/ee/extractors/shared.js +76 -0
- package/dist/ee/extractors/soundcloud.d.ts +2 -0
- package/dist/ee/extractors/soundcloud.js +34 -0
- package/dist/ee/extractors/sportsbetting.d.ts +2 -0
- package/dist/ee/extractors/sportsbetting.js +37 -0
- package/dist/ee/extractors/spotify.d.ts +2 -0
- package/dist/ee/extractors/spotify.js +34 -0
- package/dist/ee/extractors/stackoverflow.d.ts +2 -0
- package/dist/ee/extractors/stackoverflow.js +61 -0
- package/dist/ee/extractors/substack.d.ts +2 -0
- package/dist/ee/extractors/substack.js +115 -0
- package/dist/ee/extractors/substackroot.d.ts +2 -0
- package/dist/ee/extractors/substackroot.js +46 -0
- package/dist/ee/extractors/tiktok.d.ts +2 -0
- package/dist/ee/extractors/tiktok.js +29 -0
- package/dist/ee/extractors/tradingview.d.ts +2 -0
- package/dist/ee/extractors/tradingview.js +182 -0
- package/dist/ee/extractors/twitch.d.ts +2 -0
- package/dist/ee/extractors/twitch.js +36 -0
- package/dist/ee/extractors/twitter.d.ts +2 -0
- package/dist/ee/extractors/twitter.js +327 -0
- package/dist/ee/extractors/types.d.ts +14 -0
- package/dist/ee/extractors/types.js +1 -0
- package/dist/ee/extractors/walmart.d.ts +2 -0
- package/dist/ee/extractors/walmart.js +50 -0
- package/dist/ee/extractors/weather.d.ts +2 -0
- package/dist/ee/extractors/weather.js +133 -0
- package/dist/ee/extractors/wikipedia.d.ts +4 -0
- package/dist/ee/extractors/wikipedia.js +235 -0
- package/dist/ee/extractors/yelp.d.ts +2 -0
- package/dist/ee/extractors/yelp.js +216 -0
- package/dist/ee/extractors/youtube.d.ts +2 -0
- package/dist/ee/extractors/youtube.js +189 -0
- package/dist/ee/extractors/zillow.d.ts +54 -0
- package/dist/ee/extractors/zillow.js +247 -0
- package/dist/ee/extractors-re-export.d.ts +1 -0
- package/dist/ee/extractors-re-export.js +1 -0
- package/dist/ee/premium-hooks.d.ts +20 -0
- package/dist/ee/premium-hooks.js +50 -0
- package/dist/ee/spa-detection.d.ts +2 -0
- package/dist/ee/spa-detection.js +2 -0
- package/dist/ee/stability.d.ts +4 -0
- package/dist/ee/stability.js +29 -0
- package/dist/ee/swr-cache.d.ts +14 -0
- package/dist/ee/swr-cache.js +34 -0
- package/dist/index.d.ts +143 -0
- package/dist/index.js +291 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.js +2 -0
- package/dist/integrations/langchain.d.ts +64 -0
- package/dist/integrations/langchain.js +115 -0
- package/dist/integrations/llamaindex.d.ts +50 -0
- package/dist/integrations/llamaindex.js +91 -0
- package/dist/mcp/handlers/act.d.ts +5 -0
- package/dist/mcp/handlers/act.js +34 -0
- package/dist/mcp/handlers/definitions.d.ts +6 -0
- package/dist/mcp/handlers/definitions.js +395 -0
- package/dist/mcp/handlers/extract.d.ts +7 -0
- package/dist/mcp/handlers/extract.js +135 -0
- package/dist/mcp/handlers/fetch.d.ts +6 -0
- package/dist/mcp/handlers/fetch.js +98 -0
- package/dist/mcp/handlers/find.d.ts +5 -0
- package/dist/mcp/handlers/find.js +137 -0
- package/dist/mcp/handlers/index.d.ts +13 -0
- package/dist/mcp/handlers/index.js +63 -0
- package/dist/mcp/handlers/legacy.d.ts +25 -0
- package/dist/mcp/handlers/legacy.js +450 -0
- package/dist/mcp/handlers/meta.d.ts +6 -0
- package/dist/mcp/handlers/meta.js +40 -0
- package/dist/mcp/handlers/monitor.d.ts +5 -0
- package/dist/mcp/handlers/monitor.js +41 -0
- package/dist/mcp/handlers/observe.d.ts +8 -0
- package/dist/mcp/handlers/observe.js +37 -0
- package/dist/mcp/handlers/read.d.ts +6 -0
- package/dist/mcp/handlers/read.js +78 -0
- package/dist/mcp/handlers/see.d.ts +5 -0
- package/dist/mcp/handlers/see.js +75 -0
- package/dist/mcp/handlers/types.d.ts +29 -0
- package/dist/mcp/handlers/types.js +28 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +108 -0
- package/dist/mcp/smart-router.d.ts +23 -0
- package/dist/mcp/smart-router.js +178 -0
- package/dist/server/app.d.ts +14 -0
- package/dist/server/app.js +632 -0
- package/dist/server/auth-store.d.ts +28 -0
- package/dist/server/auth-store.js +88 -0
- package/dist/server/bull-queues.d.ts +60 -0
- package/dist/server/bull-queues.js +90 -0
- package/dist/server/email-service.d.ts +55 -0
- package/dist/server/email-service.js +291 -0
- package/dist/server/job-queue.d.ts +100 -0
- package/dist/server/job-queue.js +145 -0
- package/dist/server/logger.d.ts +10 -0
- package/dist/server/logger.js +37 -0
- package/dist/server/middleware/audit-log.d.ts +14 -0
- package/dist/server/middleware/audit-log.js +73 -0
- package/dist/server/middleware/auth.d.ts +35 -0
- package/dist/server/middleware/auth.js +225 -0
- package/dist/server/middleware/rate-limit.d.ts +50 -0
- package/dist/server/middleware/rate-limit.js +270 -0
- package/dist/server/middleware/scope-guard.d.ts +25 -0
- package/dist/server/middleware/scope-guard.js +45 -0
- package/dist/server/middleware/url-validator.d.ts +15 -0
- package/dist/server/middleware/url-validator.js +201 -0
- package/dist/server/openapi.yaml +6418 -0
- package/dist/server/pg-auth-store.d.ts +146 -0
- package/dist/server/pg-auth-store.js +576 -0
- package/dist/server/pg-job-queue.d.ts +59 -0
- package/dist/server/pg-job-queue.js +375 -0
- package/dist/server/routes/activity.d.ts +6 -0
- package/dist/server/routes/activity.js +79 -0
- package/dist/server/routes/admin-active.d.ts +7 -0
- package/dist/server/routes/admin-active.js +120 -0
- package/dist/server/routes/admin-stats.d.ts +7 -0
- package/dist/server/routes/admin-stats.js +176 -0
- package/dist/server/routes/agent.d.ts +24 -0
- package/dist/server/routes/agent.js +480 -0
- package/dist/server/routes/answer.d.ts +5 -0
- package/dist/server/routes/answer.js +125 -0
- package/dist/server/routes/ask.d.ts +28 -0
- package/dist/server/routes/ask.js +295 -0
- package/dist/server/routes/batch.d.ts +6 -0
- package/dist/server/routes/batch.js +493 -0
- package/dist/server/routes/cache-warm.d.ts +25 -0
- package/dist/server/routes/cache-warm.js +212 -0
- package/dist/server/routes/cli-usage.d.ts +6 -0
- package/dist/server/routes/cli-usage.js +127 -0
- package/dist/server/routes/compat.d.ts +23 -0
- package/dist/server/routes/compat.js +652 -0
- package/dist/server/routes/crawl.d.ts +13 -0
- package/dist/server/routes/crawl.js +287 -0
- package/dist/server/routes/deep-fetch.d.ts +8 -0
- package/dist/server/routes/deep-fetch.js +57 -0
- package/dist/server/routes/deep-research.d.ts +11 -0
- package/dist/server/routes/deep-research.js +232 -0
- package/dist/server/routes/demo.d.ts +24 -0
- package/dist/server/routes/demo.js +517 -0
- package/dist/server/routes/do.d.ts +8 -0
- package/dist/server/routes/do.js +72 -0
- package/dist/server/routes/extract.d.ts +14 -0
- package/dist/server/routes/extract.js +325 -0
- package/dist/server/routes/feed.d.ts +15 -0
- package/dist/server/routes/feed.js +311 -0
- package/dist/server/routes/fetch-queue.d.ts +13 -0
- package/dist/server/routes/fetch-queue.js +357 -0
- package/dist/server/routes/fetch.d.ts +7 -0
- package/dist/server/routes/fetch.js +1274 -0
- package/dist/server/routes/go.d.ts +14 -0
- package/dist/server/routes/go.js +81 -0
- package/dist/server/routes/health.d.ts +11 -0
- package/dist/server/routes/health.js +141 -0
- package/dist/server/routes/jobs.d.ts +7 -0
- package/dist/server/routes/jobs.js +574 -0
- package/dist/server/routes/map.d.ts +11 -0
- package/dist/server/routes/map.js +116 -0
- package/dist/server/routes/mcp.d.ts +14 -0
- package/dist/server/routes/mcp.js +197 -0
- package/dist/server/routes/metrics.d.ts +37 -0
- package/dist/server/routes/metrics.js +149 -0
- package/dist/server/routes/oauth.d.ts +9 -0
- package/dist/server/routes/oauth.js +396 -0
- package/dist/server/routes/playground.d.ts +17 -0
- package/dist/server/routes/playground.js +283 -0
- package/dist/server/routes/reader.d.ts +18 -0
- package/dist/server/routes/reader.js +192 -0
- package/dist/server/routes/research.d.ts +14 -0
- package/dist/server/routes/research.js +482 -0
- package/dist/server/routes/screenshot.d.ts +22 -0
- package/dist/server/routes/screenshot.js +820 -0
- package/dist/server/routes/search.d.ts +6 -0
- package/dist/server/routes/search.js +874 -0
- package/dist/server/routes/session.d.ts +17 -0
- package/dist/server/routes/session.js +548 -0
- package/dist/server/routes/share.d.ts +18 -0
- package/dist/server/routes/share.js +462 -0
- package/dist/server/routes/smart-search/handlers/cars.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/cars.js +102 -0
- package/dist/server/routes/smart-search/handlers/flights.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/flights.js +72 -0
- package/dist/server/routes/smart-search/handlers/general.d.ts +13 -0
- package/dist/server/routes/smart-search/handlers/general.js +717 -0
- package/dist/server/routes/smart-search/handlers/hotels.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/hotels.js +88 -0
- package/dist/server/routes/smart-search/handlers/products.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/products.js +1309 -0
- package/dist/server/routes/smart-search/handlers/rental.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/rental.js +154 -0
- package/dist/server/routes/smart-search/handlers/restaurants.d.ts +2 -0
- package/dist/server/routes/smart-search/handlers/restaurants.js +225 -0
- package/dist/server/routes/smart-search/handlers/transit-verdict.d.ts +41 -0
- package/dist/server/routes/smart-search/handlers/transit-verdict.js +224 -0
- package/dist/server/routes/smart-search/index.d.ts +19 -0
- package/dist/server/routes/smart-search/index.js +546 -0
- package/dist/server/routes/smart-search/intent.d.ts +3 -0
- package/dist/server/routes/smart-search/intent.js +264 -0
- package/dist/server/routes/smart-search/llm.d.ts +16 -0
- package/dist/server/routes/smart-search/llm.js +70 -0
- package/dist/server/routes/smart-search/sources/reddit.d.ts +18 -0
- package/dist/server/routes/smart-search/sources/reddit.js +34 -0
- package/dist/server/routes/smart-search/sources/yelp.d.ts +25 -0
- package/dist/server/routes/smart-search/sources/yelp.js +171 -0
- package/dist/server/routes/smart-search/sources/youtube.d.ts +8 -0
- package/dist/server/routes/smart-search/sources/youtube.js +9 -0
- package/dist/server/routes/smart-search/types.d.ts +81 -0
- package/dist/server/routes/smart-search/types.js +1 -0
- package/dist/server/routes/smart-search/utils.d.ts +20 -0
- package/dist/server/routes/smart-search/utils.js +146 -0
- package/dist/server/routes/stats.d.ts +6 -0
- package/dist/server/routes/stats.js +71 -0
- package/dist/server/routes/stripe.d.ts +15 -0
- package/dist/server/routes/stripe.js +296 -0
- package/dist/server/routes/transcript-export.d.ts +10 -0
- package/dist/server/routes/transcript-export.js +178 -0
- package/dist/server/routes/usage.d.ts +9 -0
- package/dist/server/routes/usage.js +279 -0
- package/dist/server/routes/users.d.ts +8 -0
- package/dist/server/routes/users.js +1867 -0
- package/dist/server/routes/watch.d.ts +15 -0
- package/dist/server/routes/watch.js +309 -0
- package/dist/server/routes/webhooks.d.ts +26 -0
- package/dist/server/routes/webhooks.js +170 -0
- package/dist/server/routes/youtube.d.ts +6 -0
- package/dist/server/routes/youtube.js +130 -0
- package/dist/server/sentry.d.ts +14 -0
- package/dist/server/sentry.js +104 -0
- package/dist/server/types.d.ts +15 -0
- package/dist/server/types.js +7 -0
- package/dist/server/utils/response.d.ts +44 -0
- package/dist/server/utils/response.js +69 -0
- package/dist/server/utils/sse.d.ts +22 -0
- package/dist/server/utils/sse.js +38 -0
- package/dist/types.d.ts +552 -0
- package/dist/types.js +39 -0
- package/llms.txt +105 -0
- package/package.json +189 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design Analysis — Structured visual design intelligence extraction.
|
|
3
|
+
*
|
|
4
|
+
* Runs entirely in the browser via page.evaluate(), returning a rich
|
|
5
|
+
* DesignAnalysis object that an AI agent can reason about without
|
|
6
|
+
* vision models.
|
|
7
|
+
*/
|
|
8
|
+
import type { Page } from 'playwright';
|
|
9
|
+
export interface EffectInstance {
|
|
10
|
+
selector: string;
|
|
11
|
+
properties: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
export interface DesignAnalysis {
|
|
14
|
+
visualEffects: {
|
|
15
|
+
glassmorphism: EffectInstance[];
|
|
16
|
+
shadows: EffectInstance[];
|
|
17
|
+
gradients: EffectInstance[];
|
|
18
|
+
animations: EffectInstance[];
|
|
19
|
+
transforms: EffectInstance[];
|
|
20
|
+
filters: EffectInstance[];
|
|
21
|
+
};
|
|
22
|
+
palette: {
|
|
23
|
+
dominant: string[];
|
|
24
|
+
backgrounds: string[];
|
|
25
|
+
texts: string[];
|
|
26
|
+
accents: string[];
|
|
27
|
+
gradientColors: string[];
|
|
28
|
+
scheme: 'light' | 'dark' | 'mixed';
|
|
29
|
+
};
|
|
30
|
+
layout: {
|
|
31
|
+
sections: Array<{
|
|
32
|
+
tag: string;
|
|
33
|
+
id?: string;
|
|
34
|
+
className?: string;
|
|
35
|
+
height: number;
|
|
36
|
+
background: string;
|
|
37
|
+
}>;
|
|
38
|
+
gridSystem: 'grid' | 'flexbox' | 'none';
|
|
39
|
+
maxWidth: string;
|
|
40
|
+
breakpoints: string[];
|
|
41
|
+
};
|
|
42
|
+
typeScale: {
|
|
43
|
+
sizes: string[];
|
|
44
|
+
isModular: boolean;
|
|
45
|
+
ratio?: number;
|
|
46
|
+
baseSize: string;
|
|
47
|
+
families: string[];
|
|
48
|
+
headingStyle: {
|
|
49
|
+
family: string;
|
|
50
|
+
weights: number[];
|
|
51
|
+
};
|
|
52
|
+
bodyStyle: {
|
|
53
|
+
family: string;
|
|
54
|
+
weight: number;
|
|
55
|
+
lineHeight: string;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
qualitySignals: {
|
|
59
|
+
spacingConsistency: number;
|
|
60
|
+
typographyConsistency: number;
|
|
61
|
+
colorHarmony: number;
|
|
62
|
+
visualHierarchy: number;
|
|
63
|
+
overall: number;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Extract structured design intelligence from a Playwright Page.
|
|
68
|
+
* The page must already be navigated to the target URL.
|
|
69
|
+
*/
|
|
70
|
+
export declare function extractDesignAnalysis(page: Page): Promise<DesignAnalysis>;
|
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design Analysis — Structured visual design intelligence extraction.
|
|
3
|
+
*
|
|
4
|
+
* Runs entirely in the browser via page.evaluate(), returning a rich
|
|
5
|
+
* DesignAnalysis object that an AI agent can reason about without
|
|
6
|
+
* vision models.
|
|
7
|
+
*/
|
|
8
|
+
// ── Core extraction function ───────────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* Extract structured design intelligence from a Playwright Page.
|
|
11
|
+
* The page must already be navigated to the target URL.
|
|
12
|
+
*/
|
|
13
|
+
export async function extractDesignAnalysis(page) {
|
|
14
|
+
const timeoutMs = 15000; // 15 second timeout for design analysis
|
|
15
|
+
return await Promise.race([
|
|
16
|
+
page.evaluate(() => {
|
|
17
|
+
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
18
|
+
function elementLabel(el) {
|
|
19
|
+
const tag = el.tagName.toLowerCase();
|
|
20
|
+
const id = el.id ? `#${el.id}` : '';
|
|
21
|
+
const cls = el.className && typeof el.className === 'string'
|
|
22
|
+
? '.' + el.className.trim().split(/\s+/).slice(0, 2).join('.')
|
|
23
|
+
: '';
|
|
24
|
+
return `${tag}${id}${cls}`;
|
|
25
|
+
}
|
|
26
|
+
function isVisible(el) {
|
|
27
|
+
const rect = el.getBoundingClientRect();
|
|
28
|
+
if (rect.width === 0 && rect.height === 0)
|
|
29
|
+
return false;
|
|
30
|
+
const style = window.getComputedStyle(el);
|
|
31
|
+
return style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0';
|
|
32
|
+
}
|
|
33
|
+
function parseRgba(color) {
|
|
34
|
+
const m = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
|
|
35
|
+
if (!m)
|
|
36
|
+
return null;
|
|
37
|
+
return [parseInt(m[1]), parseInt(m[2]), parseInt(m[3]), m[4] !== undefined ? parseFloat(m[4]) : 1];
|
|
38
|
+
}
|
|
39
|
+
function toHex(r, g, b) {
|
|
40
|
+
return '#' + [r, g, b].map(v => v.toString(16).padStart(2, '0')).join('');
|
|
41
|
+
}
|
|
42
|
+
function colorToHex(color) {
|
|
43
|
+
const parsed = parseRgba(color);
|
|
44
|
+
if (!parsed)
|
|
45
|
+
return color;
|
|
46
|
+
return toHex(parsed[0], parsed[1], parsed[2]);
|
|
47
|
+
}
|
|
48
|
+
function luminance(color) {
|
|
49
|
+
const parsed = parseRgba(color);
|
|
50
|
+
if (!parsed)
|
|
51
|
+
return 0.5;
|
|
52
|
+
const [r, g, b] = parsed;
|
|
53
|
+
const [rs, gs, bs] = [r, g, b].map(c => {
|
|
54
|
+
const s = c / 255;
|
|
55
|
+
return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
|
|
56
|
+
});
|
|
57
|
+
return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
|
|
58
|
+
}
|
|
59
|
+
function extractGradientColors(gradient) {
|
|
60
|
+
const colors = [];
|
|
61
|
+
// Match hex colors
|
|
62
|
+
const hexMatches = gradient.match(/#[0-9a-fA-F]{3,8}/g) || [];
|
|
63
|
+
colors.push(...hexMatches);
|
|
64
|
+
// Match rgb/rgba
|
|
65
|
+
const rgbMatches = gradient.match(/rgba?\([^)]+\)/g) || [];
|
|
66
|
+
for (const c of rgbMatches) {
|
|
67
|
+
colors.push(colorToHex(c));
|
|
68
|
+
}
|
|
69
|
+
return colors;
|
|
70
|
+
}
|
|
71
|
+
// ── Color perception helpers (CIE Lab / deltaE76) ───────────────────────
|
|
72
|
+
function hexToRgb(hex) {
|
|
73
|
+
const h = hex.replace('#', '');
|
|
74
|
+
if (h.length === 3) {
|
|
75
|
+
return [
|
|
76
|
+
parseInt(h[0] + h[0], 16),
|
|
77
|
+
parseInt(h[1] + h[1], 16),
|
|
78
|
+
parseInt(h[2] + h[2], 16),
|
|
79
|
+
];
|
|
80
|
+
}
|
|
81
|
+
return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
|
|
82
|
+
}
|
|
83
|
+
function rgbToLab(r, g, b) {
|
|
84
|
+
// sRGB to linear light
|
|
85
|
+
let rr = r / 255, gg = g / 255, bb = b / 255;
|
|
86
|
+
rr = rr > 0.04045 ? Math.pow((rr + 0.055) / 1.055, 2.4) : rr / 12.92;
|
|
87
|
+
gg = gg > 0.04045 ? Math.pow((gg + 0.055) / 1.055, 2.4) : gg / 12.92;
|
|
88
|
+
bb = bb > 0.04045 ? Math.pow((bb + 0.055) / 1.055, 2.4) : bb / 12.92;
|
|
89
|
+
// linear RGB → XYZ (D65)
|
|
90
|
+
const x = (rr * 0.4124564 + gg * 0.3575761 + bb * 0.1804375) / 0.95047;
|
|
91
|
+
const y = (rr * 0.2126729 + gg * 0.7151522 + bb * 0.0721750);
|
|
92
|
+
const z = (rr * 0.0193339 + gg * 0.1191920 + bb * 0.9503041) / 1.08883;
|
|
93
|
+
// XYZ → Lab
|
|
94
|
+
const f = (t) => t > 0.008856 ? Math.cbrt(t) : (7.787 * t) + 16 / 116;
|
|
95
|
+
return [116 * f(y) - 16, 500 * (f(x) - f(y)), 200 * (f(y) - f(z))];
|
|
96
|
+
}
|
|
97
|
+
function deltaE(lab1, lab2) {
|
|
98
|
+
return Math.sqrt((lab1[0] - lab2[0]) ** 2 +
|
|
99
|
+
(lab1[1] - lab2[1]) ** 2 +
|
|
100
|
+
(lab1[2] - lab2[2]) ** 2);
|
|
101
|
+
}
|
|
102
|
+
const rawElements = Array.from(document.querySelectorAll('*'));
|
|
103
|
+
// Sample up to 500 elements for performance — sufficient for accurate analysis
|
|
104
|
+
const allElements = rawElements.length > 500
|
|
105
|
+
? rawElements.filter((_, i) => i % Math.ceil(rawElements.length / 500) === 0)
|
|
106
|
+
: rawElements;
|
|
107
|
+
// ── A. Visual Effects ───────────────────────────────────────────────────
|
|
108
|
+
const glassmorphism = [];
|
|
109
|
+
const shadows = [];
|
|
110
|
+
const gradients = [];
|
|
111
|
+
const animations = [];
|
|
112
|
+
const transforms = [];
|
|
113
|
+
const filters = [];
|
|
114
|
+
for (const el of allElements) {
|
|
115
|
+
if (!isVisible(el))
|
|
116
|
+
continue;
|
|
117
|
+
const style = window.getComputedStyle(el);
|
|
118
|
+
const sel = elementLabel(el);
|
|
119
|
+
// Glassmorphism
|
|
120
|
+
if (glassmorphism.length < 20) {
|
|
121
|
+
const bf = style.backdropFilter || style.webkitBackdropFilter || '';
|
|
122
|
+
const bg = style.backgroundColor;
|
|
123
|
+
if (bf && bf !== 'none' && bf.includes('blur')) {
|
|
124
|
+
const parsed = parseRgba(bg);
|
|
125
|
+
if (parsed && parsed[3] < 0.5) {
|
|
126
|
+
const props = {
|
|
127
|
+
'backdrop-filter': bf,
|
|
128
|
+
background: bg,
|
|
129
|
+
};
|
|
130
|
+
const bs = style.boxShadow;
|
|
131
|
+
if (bs && bs !== 'none')
|
|
132
|
+
props['box-shadow'] = bs;
|
|
133
|
+
glassmorphism.push({ selector: sel, properties: props });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Shadows
|
|
138
|
+
if (shadows.length < 20) {
|
|
139
|
+
const bs = style.boxShadow;
|
|
140
|
+
if (bs && bs !== 'none') {
|
|
141
|
+
// Count shadows (separated by commas not inside parens)
|
|
142
|
+
const parts = bs.split(/,(?![^(]*\))/);
|
|
143
|
+
let type;
|
|
144
|
+
if (parts.length > 1)
|
|
145
|
+
type = 'layered';
|
|
146
|
+
else if (bs.includes('inset'))
|
|
147
|
+
type = 'inset';
|
|
148
|
+
else
|
|
149
|
+
type = 'drop';
|
|
150
|
+
shadows.push({ selector: sel, properties: { 'box-shadow': bs, type } });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Gradients
|
|
154
|
+
if (gradients.length < 20) {
|
|
155
|
+
const bgImage = style.backgroundImage;
|
|
156
|
+
if (bgImage && bgImage !== 'none' && bgImage.includes('gradient')) {
|
|
157
|
+
const type = bgImage.includes('radial') ? 'radial' :
|
|
158
|
+
bgImage.includes('conic') ? 'conic' : 'linear';
|
|
159
|
+
const colors = extractGradientColors(bgImage);
|
|
160
|
+
gradients.push({ selector: sel, properties: { 'background-image': bgImage, type, colors: colors.join(', ') } });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Animations
|
|
164
|
+
if (animations.length < 20) {
|
|
165
|
+
const anim = style.animation;
|
|
166
|
+
const trans = style.transition;
|
|
167
|
+
if ((anim && anim !== 'none' && !anim.startsWith('none')) ||
|
|
168
|
+
(trans && trans !== 'none' && !trans.startsWith('none'))) {
|
|
169
|
+
const props = {};
|
|
170
|
+
if (anim && anim !== 'none')
|
|
171
|
+
props.animation = anim;
|
|
172
|
+
if (trans && trans !== 'none')
|
|
173
|
+
props.transition = trans;
|
|
174
|
+
animations.push({ selector: sel, properties: props });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Transforms
|
|
178
|
+
if (transforms.length < 20) {
|
|
179
|
+
const transform = style.transform;
|
|
180
|
+
if (transform && transform !== 'none') {
|
|
181
|
+
transforms.push({ selector: sel, properties: { transform } });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Filters
|
|
185
|
+
if (filters.length < 20) {
|
|
186
|
+
const filter = style.filter;
|
|
187
|
+
const blendMode = style.mixBlendMode;
|
|
188
|
+
if ((filter && filter !== 'none') ||
|
|
189
|
+
(blendMode && blendMode !== 'normal')) {
|
|
190
|
+
const props = {};
|
|
191
|
+
if (filter && filter !== 'none')
|
|
192
|
+
props.filter = filter;
|
|
193
|
+
if (blendMode && blendMode !== 'normal')
|
|
194
|
+
props['mix-blend-mode'] = blendMode;
|
|
195
|
+
filters.push({ selector: sel, properties: props });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// ── B. Color Palette ────────────────────────────────────────────────────
|
|
200
|
+
const bgColorMap = new Map();
|
|
201
|
+
const textColorSet = new Set();
|
|
202
|
+
const accentColorSet = new Set();
|
|
203
|
+
const gradientColorSet = new Set();
|
|
204
|
+
// Accent elements
|
|
205
|
+
const accentEls = document.querySelectorAll('button, a, [role="button"], input[type="submit"], input[type="button"]');
|
|
206
|
+
for (const el of Array.from(accentEls)) {
|
|
207
|
+
const style = window.getComputedStyle(el);
|
|
208
|
+
const bg = style.backgroundColor;
|
|
209
|
+
const parsed = parseRgba(bg);
|
|
210
|
+
if (parsed && parsed[3] > 0.1) {
|
|
211
|
+
accentColorSet.add(colorToHex(bg));
|
|
212
|
+
}
|
|
213
|
+
const color = style.color;
|
|
214
|
+
if (color)
|
|
215
|
+
textColorSet.add(colorToHex(color));
|
|
216
|
+
}
|
|
217
|
+
for (const el of allElements) {
|
|
218
|
+
if (!isVisible(el))
|
|
219
|
+
continue;
|
|
220
|
+
const style = window.getComputedStyle(el);
|
|
221
|
+
const bg = style.backgroundColor;
|
|
222
|
+
const parsed = parseRgba(bg);
|
|
223
|
+
if (parsed && parsed[3] > 0.05) {
|
|
224
|
+
const hex = colorToHex(bg);
|
|
225
|
+
bgColorMap.set(hex, (bgColorMap.get(hex) || 0) + 1);
|
|
226
|
+
}
|
|
227
|
+
const color = style.color;
|
|
228
|
+
if (color)
|
|
229
|
+
textColorSet.add(colorToHex(color));
|
|
230
|
+
// Gradient colors
|
|
231
|
+
const bgImage = style.backgroundImage;
|
|
232
|
+
if (bgImage && bgImage !== 'none' && bgImage.includes('gradient')) {
|
|
233
|
+
for (const c of extractGradientColors(bgImage)) {
|
|
234
|
+
gradientColorSet.add(c);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Top 5 dominant bg colors by frequency
|
|
239
|
+
const sorted = Array.from(bgColorMap.entries()).sort((a, b) => b[1] - a[1]);
|
|
240
|
+
const dominant = sorted.slice(0, 5).map(([hex]) => hex);
|
|
241
|
+
const backgrounds = Array.from(bgColorMap.keys());
|
|
242
|
+
// Detect scheme from body background luminance
|
|
243
|
+
const bodyBg = window.getComputedStyle(document.body).backgroundColor;
|
|
244
|
+
const bodyLum = luminance(bodyBg);
|
|
245
|
+
const scheme = bodyLum > 0.5 ? 'light' : bodyLum < 0.2 ? 'dark' : 'mixed';
|
|
246
|
+
// ── C. Layout Structure ──────────────────────────────────────────────────
|
|
247
|
+
const sections = [];
|
|
248
|
+
let gridSystem = 'none';
|
|
249
|
+
let maxWidth = '';
|
|
250
|
+
const layoutParents = [document.body, document.querySelector('main')].filter(Boolean);
|
|
251
|
+
for (const parent of layoutParents) {
|
|
252
|
+
for (const child of Array.from(parent.children)) {
|
|
253
|
+
const tag = child.tagName.toLowerCase();
|
|
254
|
+
if (tag !== 'section' && tag !== 'div' && tag !== 'article' && tag !== 'header' && tag !== 'footer' && tag !== 'nav')
|
|
255
|
+
continue;
|
|
256
|
+
const rect = child.getBoundingClientRect();
|
|
257
|
+
if (rect.height <= 100)
|
|
258
|
+
continue;
|
|
259
|
+
const style = window.getComputedStyle(child);
|
|
260
|
+
sections.push({
|
|
261
|
+
tag,
|
|
262
|
+
id: child.id || undefined,
|
|
263
|
+
className: child.className && typeof child.className === 'string' ? child.className.trim().slice(0, 80) || undefined : undefined,
|
|
264
|
+
height: Math.round(rect.height),
|
|
265
|
+
background: style.backgroundColor,
|
|
266
|
+
});
|
|
267
|
+
// Check grid system
|
|
268
|
+
const display = style.display;
|
|
269
|
+
if (display === 'grid' && gridSystem === 'none')
|
|
270
|
+
gridSystem = 'grid';
|
|
271
|
+
if (display === 'flex' && gridSystem === 'none')
|
|
272
|
+
gridSystem = 'flexbox';
|
|
273
|
+
// Check max-width
|
|
274
|
+
const mw = style.maxWidth;
|
|
275
|
+
if (mw && mw !== 'none' && !maxWidth)
|
|
276
|
+
maxWidth = mw;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// Also scan containers for grid/flex
|
|
280
|
+
if (gridSystem === 'none') {
|
|
281
|
+
for (const el of allElements) {
|
|
282
|
+
const style = window.getComputedStyle(el);
|
|
283
|
+
if (style.display === 'grid') {
|
|
284
|
+
gridSystem = 'grid';
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
if (style.display === 'flex') {
|
|
288
|
+
gridSystem = 'flexbox';
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Extract media query breakpoints
|
|
294
|
+
const breakpoints = [];
|
|
295
|
+
try {
|
|
296
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
297
|
+
try {
|
|
298
|
+
const rules = Array.from(sheet.cssRules || []);
|
|
299
|
+
for (const rule of rules) {
|
|
300
|
+
if (rule instanceof CSSMediaRule) {
|
|
301
|
+
const cond = rule.conditionText || rule.media?.mediaText || '';
|
|
302
|
+
if (cond && !breakpoints.includes(cond)) {
|
|
303
|
+
breakpoints.push(cond);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
// Cross-origin stylesheet
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
// ignore
|
|
315
|
+
}
|
|
316
|
+
// ── D. Typography Scale ──────────────────────────────────────────────────
|
|
317
|
+
const fontSizeMap = new Map();
|
|
318
|
+
const fontFamilySet = new Set();
|
|
319
|
+
const headingWeights = [];
|
|
320
|
+
let headingFamily = '';
|
|
321
|
+
let bodyFamily = '';
|
|
322
|
+
let bodyWeight = 400;
|
|
323
|
+
let bodyLineHeight = '1.5';
|
|
324
|
+
// Body style
|
|
325
|
+
const bodyStyle = window.getComputedStyle(document.body);
|
|
326
|
+
bodyFamily = bodyStyle.fontFamily.split(',')[0].replace(/["']/g, '').trim();
|
|
327
|
+
bodyWeight = parseInt(bodyStyle.fontWeight) || 400;
|
|
328
|
+
bodyLineHeight = bodyStyle.lineHeight;
|
|
329
|
+
const baseFontSize = parseFloat(bodyStyle.fontSize) || 16;
|
|
330
|
+
// Headings
|
|
331
|
+
const headingEls = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
|
332
|
+
for (const h of Array.from(headingEls)) {
|
|
333
|
+
const hs = window.getComputedStyle(h);
|
|
334
|
+
const w = parseInt(hs.fontWeight) || 400;
|
|
335
|
+
if (!headingWeights.includes(w))
|
|
336
|
+
headingWeights.push(w);
|
|
337
|
+
if (!headingFamily)
|
|
338
|
+
headingFamily = hs.fontFamily.split(',')[0].replace(/["']/g, '').trim();
|
|
339
|
+
}
|
|
340
|
+
// Collect all font sizes
|
|
341
|
+
for (const el of allElements) {
|
|
342
|
+
if (!isVisible(el))
|
|
343
|
+
continue;
|
|
344
|
+
const style = window.getComputedStyle(el);
|
|
345
|
+
const size = parseFloat(style.fontSize);
|
|
346
|
+
if (!isNaN(size) && size > 0) {
|
|
347
|
+
fontSizeMap.set(size, (fontSizeMap.get(size) || 0) + 1);
|
|
348
|
+
}
|
|
349
|
+
const family = style.fontFamily.split(',')[0].replace(/["']/g, '').trim();
|
|
350
|
+
if (family)
|
|
351
|
+
fontFamilySet.add(family);
|
|
352
|
+
}
|
|
353
|
+
const sortedSizes = Array.from(fontSizeMap.keys()).sort((a, b) => a - b);
|
|
354
|
+
const sizeStrings = sortedSizes.map(s => `${s}px`);
|
|
355
|
+
// Detect modular scale
|
|
356
|
+
let isModular = false;
|
|
357
|
+
let ratio;
|
|
358
|
+
if (sortedSizes.length >= 3) {
|
|
359
|
+
const ratios = [];
|
|
360
|
+
for (let i = 1; i < sortedSizes.length; i++) {
|
|
361
|
+
ratios.push(sortedSizes[i] / sortedSizes[i - 1]);
|
|
362
|
+
}
|
|
363
|
+
const meanRatio = ratios.reduce((a, b) => a + b, 0) / ratios.length;
|
|
364
|
+
const isConsistent = ratios.every(r => Math.abs(r - meanRatio) / meanRatio < 0.05);
|
|
365
|
+
if (isConsistent && meanRatio > 1.05) {
|
|
366
|
+
isModular = true;
|
|
367
|
+
ratio = Math.round(meanRatio * 1000) / 1000;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// ── E. Quality Signals ───────────────────────────────────────────────────
|
|
371
|
+
// spacingConsistency: % of margin/padding values that are multiples of 4 or 8
|
|
372
|
+
let spacingTotal = 0;
|
|
373
|
+
let spacingAligned = 0;
|
|
374
|
+
const spacingBase = 4;
|
|
375
|
+
const sampleEls = allElements.slice(0, 200);
|
|
376
|
+
for (const el of sampleEls) {
|
|
377
|
+
const style = window.getComputedStyle(el);
|
|
378
|
+
const props = [
|
|
379
|
+
style.marginTop, style.marginBottom, style.marginLeft, style.marginRight,
|
|
380
|
+
style.paddingTop, style.paddingBottom, style.paddingLeft, style.paddingRight,
|
|
381
|
+
];
|
|
382
|
+
for (const v of props) {
|
|
383
|
+
const px = parseFloat(v);
|
|
384
|
+
if (!isNaN(px) && px > 0) {
|
|
385
|
+
spacingTotal++;
|
|
386
|
+
if (Math.round(px) % spacingBase === 0)
|
|
387
|
+
spacingAligned++;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
const spacingConsistency = spacingTotal > 0 ? spacingAligned / spacingTotal : 0.5;
|
|
392
|
+
// typographyConsistency: R² of log-linear fit of font sizes
|
|
393
|
+
let typographyConsistency = 0.5;
|
|
394
|
+
if (sortedSizes.length >= 3) {
|
|
395
|
+
const n = sortedSizes.length;
|
|
396
|
+
const xs = sortedSizes.map((_, i) => i);
|
|
397
|
+
const ys = sortedSizes.map(s => Math.log(s));
|
|
398
|
+
const xMean = xs.reduce((a, b) => a + b, 0) / n;
|
|
399
|
+
const yMean = ys.reduce((a, b) => a + b, 0) / n;
|
|
400
|
+
const ssXY = xs.reduce((acc, x, i) => acc + (x - xMean) * (ys[i] - yMean), 0);
|
|
401
|
+
const ssXX = xs.reduce((acc, x) => acc + (x - xMean) ** 2, 0);
|
|
402
|
+
const ssYY = ys.reduce((acc, y) => acc + (y - yMean) ** 2, 0);
|
|
403
|
+
if (ssXX > 0 && ssYY > 0) {
|
|
404
|
+
typographyConsistency = Math.min(1, Math.max(0, (ssXY / Math.sqrt(ssXX * ssYY)) ** 2));
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
// colorHarmony: perceptual color clustering via CIE Lab / deltaE76
|
|
408
|
+
// Groups visually similar colors (deltaE ≤ 12) into clusters, then scores
|
|
409
|
+
// by cluster count — tolerant of glassmorphism variants, strict on chaos.
|
|
410
|
+
const uniqueColorSet = new Set([...backgrounds, ...Array.from(textColorSet), ...Array.from(accentColorSet)]);
|
|
411
|
+
const clusterCentroids = [];
|
|
412
|
+
for (const hex of uniqueColorSet) {
|
|
413
|
+
if (!/^#[0-9a-fA-F]{3,8}$/.test(hex))
|
|
414
|
+
continue;
|
|
415
|
+
const [r, g, b] = hexToRgb(hex);
|
|
416
|
+
const lab = rgbToLab(r, g, b);
|
|
417
|
+
let assigned = false;
|
|
418
|
+
for (const centroid of clusterCentroids) {
|
|
419
|
+
if (deltaE(lab, centroid) <= 12) {
|
|
420
|
+
// update centroid as running average
|
|
421
|
+
centroid[0] = (centroid[0] + lab[0]) / 2;
|
|
422
|
+
centroid[1] = (centroid[1] + lab[1]) / 2;
|
|
423
|
+
centroid[2] = (centroid[2] + lab[2]) / 2;
|
|
424
|
+
assigned = true;
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
if (!assigned)
|
|
429
|
+
clusterCentroids.push([lab[0], lab[1], lab[2]]);
|
|
430
|
+
}
|
|
431
|
+
const clusterCount = clusterCentroids.length;
|
|
432
|
+
let colorHarmony;
|
|
433
|
+
if (clusterCount <= 10)
|
|
434
|
+
colorHarmony = 1.0;
|
|
435
|
+
else if (clusterCount >= 25)
|
|
436
|
+
colorHarmony = 0.5;
|
|
437
|
+
else
|
|
438
|
+
colorHarmony = 1.0 - (clusterCount - 10) / (25 - 10) * 0.5;
|
|
439
|
+
// visualHierarchy: ratio of h1 font size to body
|
|
440
|
+
let visualHierarchy = 0.75;
|
|
441
|
+
const h1 = document.querySelector('h1');
|
|
442
|
+
if (h1) {
|
|
443
|
+
const h1Size = parseFloat(window.getComputedStyle(h1).fontSize);
|
|
444
|
+
const bodySize = baseFontSize;
|
|
445
|
+
const hratio = h1Size / bodySize;
|
|
446
|
+
if (hratio >= 2)
|
|
447
|
+
visualHierarchy = 1.0;
|
|
448
|
+
else if (hratio <= 1.5)
|
|
449
|
+
visualHierarchy = 0.5;
|
|
450
|
+
else
|
|
451
|
+
visualHierarchy = 0.5 + (hratio - 1.5) / (2 - 1.5) * 0.5;
|
|
452
|
+
}
|
|
453
|
+
const overall = (spacingConsistency * 0.25 + typographyConsistency * 0.25 + colorHarmony * 0.25 + visualHierarchy * 0.25);
|
|
454
|
+
return {
|
|
455
|
+
visualEffects: { glassmorphism, shadows, gradients, animations, transforms, filters },
|
|
456
|
+
palette: {
|
|
457
|
+
dominant,
|
|
458
|
+
backgrounds,
|
|
459
|
+
texts: Array.from(textColorSet),
|
|
460
|
+
accents: Array.from(accentColorSet),
|
|
461
|
+
gradientColors: Array.from(gradientColorSet),
|
|
462
|
+
scheme,
|
|
463
|
+
},
|
|
464
|
+
layout: {
|
|
465
|
+
sections: sections.slice(0, 30),
|
|
466
|
+
gridSystem,
|
|
467
|
+
maxWidth: maxWidth || 'none',
|
|
468
|
+
breakpoints: breakpoints.slice(0, 20),
|
|
469
|
+
},
|
|
470
|
+
typeScale: {
|
|
471
|
+
sizes: sizeStrings,
|
|
472
|
+
isModular,
|
|
473
|
+
...(ratio !== undefined ? { ratio } : {}),
|
|
474
|
+
baseSize: `${baseFontSize}px`,
|
|
475
|
+
families: Array.from(fontFamilySet),
|
|
476
|
+
headingStyle: { family: headingFamily || bodyFamily, weights: headingWeights.sort() },
|
|
477
|
+
bodyStyle: { family: bodyFamily, weight: bodyWeight, lineHeight: bodyLineHeight },
|
|
478
|
+
},
|
|
479
|
+
qualitySignals: {
|
|
480
|
+
spacingConsistency: Math.round(spacingConsistency * 1000) / 1000,
|
|
481
|
+
typographyConsistency: Math.round(typographyConsistency * 1000) / 1000,
|
|
482
|
+
colorHarmony: Math.round(colorHarmony * 1000) / 1000,
|
|
483
|
+
visualHierarchy: Math.round(visualHierarchy * 1000) / 1000,
|
|
484
|
+
overall: Math.round(overall * 1000) / 1000,
|
|
485
|
+
},
|
|
486
|
+
};
|
|
487
|
+
}),
|
|
488
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Design analysis timed out after 15s')), timeoutMs)),
|
|
489
|
+
]);
|
|
490
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design Compare — Structural diff between two pages' design tokens.
|
|
3
|
+
*
|
|
4
|
+
* Compares design quality of a subject URL against a reference URL,
|
|
5
|
+
* returning a structured gap list with severity ratings and CSS suggestions.
|
|
6
|
+
*/
|
|
7
|
+
import type { Page } from 'playwright';
|
|
8
|
+
import { type DesignAnalysis } from './design-analysis.js';
|
|
9
|
+
export interface DesignGap {
|
|
10
|
+
property: string;
|
|
11
|
+
description: string;
|
|
12
|
+
subject: string;
|
|
13
|
+
reference: string;
|
|
14
|
+
severity: 'high' | 'medium' | 'low';
|
|
15
|
+
suggestion: string;
|
|
16
|
+
}
|
|
17
|
+
export interface DesignComparison {
|
|
18
|
+
subjectUrl: string;
|
|
19
|
+
referenceUrl: string;
|
|
20
|
+
/** Design quality score relative to the reference (1–10, higher is closer). */
|
|
21
|
+
score: number;
|
|
22
|
+
gaps: DesignGap[];
|
|
23
|
+
subjectAnalysis: DesignAnalysis;
|
|
24
|
+
referenceAnalysis: DesignAnalysis;
|
|
25
|
+
summary: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build a DesignComparison from two pre-extracted DesignAnalysis objects.
|
|
29
|
+
*
|
|
30
|
+
* This is a pure synchronous function — straightforward to test and reuse
|
|
31
|
+
* from both the HTTP route and the CLI command.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildDesignComparison(subjectUrl: string, referenceUrl: string, subjectAnalysis: DesignAnalysis, referenceAnalysis: DesignAnalysis): DesignComparison;
|
|
34
|
+
/**
|
|
35
|
+
* Compare the design of two Playwright pages by extracting design tokens from
|
|
36
|
+
* both in parallel, then diffing the tokens into a structured DesignComparison.
|
|
37
|
+
*/
|
|
38
|
+
export declare function compareDesigns(subjectPage: Page, referencePage: Page): Promise<DesignComparison>;
|