console-intelligence
Capture and categorize all console output with stack traces, source attribution, frequency deduplication, and temporal grouping. Uses CDP Runtime and Log domains for browser-level entries and unhandled exceptions.
What this skill does
# Console Intelligence
Capture every console message, unhandled exception, and browser-level log
entry from a page session. Categorize by severity, group by source file,
deduplicate repeated messages, detect framework-specific warnings (React,
Vue, Angular), identify CSP violations, and produce a prioritized report.
## When to Use
- Debugging production pages where console errors indicate broken functionality.
- Auditing a page for JavaScript errors, deprecation warnings, and CSP violations before release.
- Identifying noisy third-party scripts that flood the console.
- Detecting React/Vue/Angular framework warnings that indicate misuse or performance issues.
- Understanding the temporal sequence of errors during page load and interaction.
## Prerequisites
- **Playwright MCP server** connected and responding.
- **Chromium-based browser** for CDP Runtime and Log domain access.
- Target page must be reachable from the browser instance.
## Workflow
### Phase 1: Install Console Interceptors via CDP
Install CDP listeners **before** navigation so that early page errors are
captured. This uses three complementary channels:
1. **Runtime.exceptionThrown** -- catches unhandled exceptions with async stack traces.
2. **Log.entryAdded** -- catches browser-level entries (network errors, security warnings, interventions).
3. **Console method patching** via `browser_evaluate` -- catches all `console.*` calls with caller location.
```javascript
browser_run_code({
code: `async (page) => {
const client = await page.context().newCDPSession(page);
await client.send('Runtime.enable');
await client.send('Log.enable');
const entries = [];
let idCounter = 0;
// Channel 1: Unhandled exceptions (async stack traces included)
client.on('Runtime.exceptionThrown', (params) => {
const ex = params.exceptionDetails;
const entry = {
id: ++idCounter,
channel: 'exception',
level: 'error',
timestamp: params.timestamp,
text: ex.text || '',
description: ex.exception ? (ex.exception.description || ex.exception.value || '') : '',
url: ex.url || null,
lineNumber: ex.lineNumber,
columnNumber: ex.columnNumber,
stackTrace: null
};
if (ex.stackTrace && ex.stackTrace.callFrames) {
entry.stackTrace = ex.stackTrace.callFrames.map(f => ({
functionName: f.functionName || '(anonymous)',
url: f.url,
lineNumber: f.lineNumber,
columnNumber: f.columnNumber
}));
}
entries.push(entry);
});
// Channel 2: Browser-level log entries
client.on('Log.entryAdded', (params) => {
const e = params.entry;
entries.push({
id: ++idCounter,
channel: 'browser',
level: e.level,
timestamp: e.timestamp,
text: e.text,
url: e.url || null,
lineNumber: e.lineNumber || null,
source: e.source,
category: e.category || null,
networkRequestId: e.networkRequestId || null
});
});
globalThis.__consoleIntel = { client, entries };
return 'CDP console interceptors installed';
}`
})
```
### Phase 2: Install Console Method Patches
Patch `console.*` methods in the page context to capture calls with caller
information. This runs in the page's JavaScript context.
```javascript
browser_evaluate({
function: `() => {
window.__consoleCaptures = [];
const methods = ['log', 'warn', 'error', 'info', 'debug', 'trace', 'assert'];
const originals = {};
methods.forEach(method => {
originals[method] = console[method].bind(console);
console[method] = (...args) => {
// Capture caller location from stack trace
const stack = new Error().stack || '';
const callerLine = stack.split('\\n')[2] || '';
const match = callerLine.match(/(?:at\\s+)?(?:.*?)\\(?(.+?):(\\d+):(\\d+)\\)?/);
window.__consoleCaptures.push({
method: method,
timestamp: Date.now(),
args: args.map(a => {
try {
if (typeof a === 'object') return JSON.stringify(a).substring(0, 500);
return String(a).substring(0, 500);
} catch { return '[unserializable]'; }
}),
sourceUrl: match ? match[1] : null,
line: match ? parseInt(match[2]) : null,
column: match ? parseInt(match[3]) : null
});
originals[method](...args);
};
});
return 'Console methods patched (' + methods.length + ' methods)';
}`
})
```
### Phase 3: Navigate and Interact
Navigate to the target page. Console interceptors are already active.
```
browser_navigate({ url: "<target_url>" })
```
Wait for page load and deferred scripts:
```
browser_wait_for({ time: 3 })
```
Perform interactions that may trigger console output:
1. Scroll the page to trigger lazy-loaded content:
```javascript
browser_evaluate({
function: `() => {
window.scrollTo(0, document.body.scrollHeight / 2);
return 'scrolled to midpoint';
}`
})
```
2. Wait for async operations:
```
browser_wait_for({ time: 2 })
```
3. Take a snapshot and click interactive elements (buttons, tabs) to trigger
event handler errors:
```
browser_snapshot()
```
Then use `browser_click` on elements identified in the snapshot.
4. Wait again for async responses:
```
browser_wait_for({ time: 2 })
```
### Phase 4: Collect Baseline from Built-in Tool
Cross-reference with the built-in console capture.
```
browser_console_messages({ level: "debug" })
```
### Phase 5: Harvest and Analyze
Collect all captured data and perform categorization, deduplication, and
framework detection.
```javascript
browser_run_code({
code: `async (page) => {
const intel = globalThis.__consoleIntel;
if (!intel) return { error: 'Interceptors not installed' };
// Collect CDP entries
const cdpEntries = [...intel.entries];
// Collect page-context captures
const pageCaptures = await page.evaluate(() => window.__consoleCaptures || []);
// Merge into unified list
const all = [];
cdpEntries.forEach(e => all.push(e));
pageCaptures.forEach(c => {
all.push({
id: all.length + 1,
channel: 'console-patch',
level: c.method === 'warn' ? 'warning'
: c.method === 'assert' ? 'error'
: c.method === 'trace' ? 'info'
: c.method,
timestamp: c.timestamp,
text: c.args.join(' '),
url: c.sourceUrl,
lineNumber: c.line,
method: c.method
});
});
// Sort by timestamp
all.sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0));
// Deduplicate: group identical messages
const deduped = new Map();
all.forEach(entry => {
const key = entry.level + '|' + (entry.text || '').substring(0, 200);
if (deduped.has(key)) {
const existing = deduped.get(key);
existing.count++;
existing.lastSeen = entry.timestamp;
} else {
deduped.set(key, { ...entry, count: 1, lastSeen: entry.timestamp });
}
});
// Framework detection patterns
const frameworkPatterns = [
{ regex: /Warning:.*React/, framework: 'React', type: 'warning' },
{ regex: /react-dom\\.development/, framework: 'React', type: 'dev-mode' },
{ regex: /Each child in a list should have a unique/, framework: 'React', type: 'key-warning' },
{ regex: /Cannot update a component.*while rendering/, framework: 'React', type: 'state-during-render' },
{ regex: /\\[Vue warn\\]/, framework: 'Vue', type: 'warning' },
{ regex: /\\[deprecation\\]|NG\\d{4}/, framework: 'Angular', type: 'deprecation' },
{ regex: /Content.Security.Policy|CSP/, framework: 'Browser', type: 'csp-violation' },
{ regex: /Mixed Content/, framework: 'Browser', type: 'mixed-content' },
{ regex: /DEPRECATED|deprecated/, framRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.