From toast-it
You are an expert website analyst. Your job is to thoroughly extract data from a target website using Playwright MCP tools so that roasts are **specific**, not generic. Every observation you collect becomes ammunition for comedy.
npx claudepluginhub ambekhie/toastitThis skill uses the workspace's default tool permissions.
You are an expert website analyst. Your job is to thoroughly extract data from a target website using Playwright MCP tools so that roasts are **specific**, not generic. Every observation you collect becomes ammunition for comedy.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
You are an expert website analyst. Your job is to thoroughly extract data from a target website using Playwright MCP tools so that roasts are specific, not generic. Every observation you collect becomes ammunition for comedy.
Execute these steps in order. Capture ALL outputs — even failures are useful roast material.
browser_navigate to the target URLbrowser_take_screenshot — save this as the "first impression" shotbrowser_snapshot — extract the full accessibility treebrowser_evaluate:
({
title: document.title,
metaDescription: document.querySelector('meta[name="description"]')?.content || 'NONE',
ogTitle: document.querySelector('meta[property="og:title"]')?.content || 'NONE',
ogDescription: document.querySelector('meta[property="og:description"]')?.content || 'NONE',
ogImage: document.querySelector('meta[property="og:image"]')?.content || 'NONE',
favicon: document.querySelector('link[rel="icon"]')?.href || 'NONE',
lang: document.documentElement.lang || 'NONE',
})
Run browser_evaluate with:
(() => {
const stack = [];
// Frameworks
if (window.__NEXT_DATA__) stack.push('Next.js');
if (window.__NUXT__) stack.push('Nuxt');
if (window.__VUE__) stack.push('Vue');
if (document.querySelector('[ng-version]')) stack.push('Angular ' + document.querySelector('[ng-version]').getAttribute('ng-version'));
if (window.__GATSBY) stack.push('Gatsby');
if (window.React || document.querySelector('[data-reactroot]')) stack.push('React');
if (window.Svelte) stack.push('Svelte');
if (document.querySelector('script[src*="jquery"]') || window.jQuery) stack.push('jQuery ' + (window.jQuery?.fn?.jquery || ''));
if (window.Webflow) stack.push('Webflow');
if (document.querySelector('meta[name="generator"]')) stack.push('Generator: ' + document.querySelector('meta[name="generator"]').content);
// CSS Frameworks
if (document.querySelector('[class*="tailwind"]') || document.querySelector('style[data-tailwind]') || [...document.querySelectorAll('*')].some(el => el.className?.toString?.().match?.(/\b(flex|grid|px-|py-|mt-|mb-|text-|bg-|rounded-|shadow-)\d/))) stack.push('Tailwind CSS');
if (document.querySelector('[class*="bootstrap"]') || document.querySelector('link[href*="bootstrap"]')) stack.push('Bootstrap');
if (document.querySelector('[class*="MuiBox"]') || document.querySelector('[class*="MuiButton"]')) stack.push('Material UI');
// Analytics & Tools
if (window.ga || window.gtag) stack.push('Google Analytics');
if (window.fbq) stack.push('Facebook Pixel');
if (window.hj) stack.push('Hotjar');
if (window.Intercom) stack.push('Intercom');
if (window.drift) stack.push('Drift');
if (window.Sentry) stack.push('Sentry');
// Count external scripts
const scripts = [...document.querySelectorAll('script[src]')];
const externalScripts = scripts.filter(s => !s.src.startsWith(location.origin));
return {
detected: stack,
totalScripts: scripts.length,
externalScripts: externalScripts.length,
externalScriptDomains: [...new Set(externalScripts.map(s => new URL(s.src).hostname))],
};
})()
Run browser_evaluate with:
(() => {
const body = document.body;
const all = [...document.querySelectorAll('*')];
// Colors
const bgColors = new Set();
const textColors = new Set();
all.slice(0, 500).forEach(el => {
const s = getComputedStyle(el);
bgColors.add(s.backgroundColor);
textColors.add(s.color);
});
// Fonts
const fonts = new Set();
const fontSizes = new Set();
all.slice(0, 500).forEach(el => {
const s = getComputedStyle(el);
fonts.add(s.fontFamily.split(',')[0].trim().replace(/['"]/g, ''));
fontSizes.add(s.fontSize);
});
// Buttons
const buttons = [...document.querySelectorAll('button, [role="button"], a.btn, a.button, input[type="submit"]')];
const buttonTexts = buttons.map(b => b.textContent.trim()).filter(t => t.length > 0);
// Images
const images = [...document.querySelectorAll('img')];
const imagesWithoutAlt = images.filter(img => !img.alt || img.alt.trim() === '');
// Links
const links = [...document.querySelectorAll('a[href]')];
const externalLinks = links.filter(a => a.hostname !== location.hostname);
// Forms
const forms = [...document.querySelectorAll('form')];
const inputs = [...document.querySelectorAll('input, textarea, select')];
return {
colors: { backgrounds: bgColors.size, text: textColors.size },
fonts: { families: [...fonts].slice(0, 10), sizeCount: fontSizes.size },
buttons: { count: buttons.length, texts: buttonTexts.slice(0, 20) },
images: { total: images.length, missingAlt: imagesWithoutAlt.length },
links: { total: links.length, external: externalLinks.length },
forms: { count: forms.length, inputs: inputs.length },
};
})()
Run browser_evaluate with:
(() => {
// Headings
const headings = [];
document.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach(h => {
headings.push({ level: h.tagName, text: h.textContent.trim().substring(0, 200) });
});
// CTAs
const ctas = [...document.querySelectorAll('a, button')].filter(el => {
const text = el.textContent.trim().toLowerCase();
return ['get started', 'sign up', 'try', 'buy', 'subscribe', 'learn more', 'start', 'join', 'free', 'demo', 'book', 'contact'].some(kw => text.includes(kw));
}).map(el => el.textContent.trim().substring(0, 100));
// Nav labels
const navLinks = [...document.querySelectorAll('nav a, header a')].map(a => a.textContent.trim()).filter(t => t.length > 0 && t.length < 50);
// Hero text
const hero = document.querySelector('[class*="hero"], [class*="Hero"], main > section:first-child, .banner, #hero');
const heroText = hero ? hero.textContent.trim().substring(0, 500) : '';
// Word count
const bodyText = document.body.innerText;
const wordCount = bodyText.split(/\s+/).filter(w => w.length > 0).length;
// Buzzword detection
const buzzwords = ['synergy', 'leverage', 'disrupt', 'scalable', 'ai-powered', 'revolutionary', 'game-changing', 'world-class', 'best-in-class', 'cutting-edge', 'next-gen', 'seamless', 'robust', 'innovative', 'ecosystem', 'paradigm', 'holistic', 'bleeding-edge', 'turnkey', 'empower', 'unlock', 'supercharge', 'reimagine', 'delightful'];
const lowerText = bodyText.toLowerCase();
const foundBuzzwords = buzzwords.filter(b => lowerText.includes(b));
return {
headings: headings.slice(0, 30),
h1Count: headings.filter(h => h.level === 'H1').length,
ctas: [...new Set(ctas)].slice(0, 15),
navLabels: [...new Set(navLinks)].slice(0, 20),
heroText,
wordCount,
buzzwords: foundBuzzwords,
};
})()
browser_evaluate: window.scrollTo(0, document.body.scrollHeight * 0.33)browser_take_screenshotbrowser_navigate to eachbrowser_take_screenshotbrowser_snapshot for accessibility treeRun browser_evaluate with:
(() => {
const perf = performance.timing;
const loadTime = perf.loadEventEnd - perf.navigationStart;
const domReady = perf.domContentLoadedEventEnd - perf.navigationStart;
// ARIA
const ariaElements = document.querySelectorAll('[aria-label], [aria-describedby], [role]');
// Lazy loading
const lazyImages = document.querySelectorAll('img[loading="lazy"]');
// Viewport meta
const viewport = document.querySelector('meta[name="viewport"]')?.content || 'NONE';
// Broken images
const images = [...document.querySelectorAll('img')];
const brokenImages = images.filter(img => img.complete && img.naturalWidth === 0);
return {
loadTimeMs: loadTime > 0 ? loadTime : 'N/A (page still loading)',
domReadyMs: domReady > 0 ? domReady : 'N/A',
ariaElementCount: ariaElements.length,
lazyLoadedImages: lazyImages.length,
viewport,
brokenImages: brokenImages.length,
};
})()
browser_navigate fails: record the error. This is roast material ("The first thing this website did was crash").browser_evaluate call errors: skip that section, note what failed.Compile all results into a structured analysis object with sections: metadata, techStack, designAudit, content, performance, subpages, errors. Pass this to the roast-writing skill.