anything-analyzer-cdp

安装量: 263
排名: #10761

安装

npx skills add https://github.com/aradotso/trending-skills --skill anything-analyzer-cdp

Anything Analyzer CDP Skill Skill by ara.so — Daily 2026 Skills collection. Anything Analyzer is an Electron desktop application that embeds a browser, captures all network traffic via Chrome DevTools Protocol (CDP), injects JS hooks, snapshots storage, and feeds the data to an AI (OpenAI/Anthropic/custom) to generate protocol analysis reports — useful for documenting registration flows, 2API reverse engineering, and general browser protocol analysis. Installation & Setup git clone https://github.com/MouseWW/anything-analyzer.git cd anything-analyzer pnpm install pnpm dev

development mode

pnpm build

production build

Windows native module build requirement:

Install Visual Studio Build Tools first, then:

pnpm install

If better-sqlite3 fails:

pnpm rebuild Package as installer: pnpm run build && npx electron-builder --win Core Architecture src/ ├── main/ # Electron main process │ ├── ai/ # AI analysis pipeline │ │ ├── ai-analyzer.ts # orchestrator │ │ ├── data-assembler.ts# data preparation │ │ ├── prompt-builder.ts# prompt generation │ │ └── scene-detector.ts# rule-based scene classification │ ├── capture/ # Capture engine │ │ ├── capture-engine.ts# data sink → SQLite + renderer │ │ ├── js-injector.ts # hook script injection │ │ └── storage-collector.ts # periodic storage snapshots │ ├── cdp/ │ │ └── cdp-manager.ts # CDP manager │ ├── db/ # SQLite via better-sqlite3 │ ├── session/ │ │ └── session-manager.ts # session lifecycle │ ├── tab-manager.ts # Multi-tab WebContentsView │ ├── window.ts # Main window layout │ └── ipc.ts # IPC handlers ├── preload/ # Context bridge + hook script ├── renderer/ # React 19 + Ant Design 5 UI └── shared/types.ts # Shared TypeScript types Key Concepts Sessions A Session scopes all captured data. Each session has a name, target URL, and contains all requests, JS hook events, and storage snapshots captured during that session. Capture Engine The capture engine: Attaches CDP to WebContentsView tabs Enables Fetch.enable for request interception Injects JS hooks via Page.addScriptToEvaluateOnNewDocument Collects storage snapshots periodically AI Analysis Pipeline Scene detection — rule-based classification (registration, OAuth, API auth, etc.) Data assembly — selects relevant requests, deduplicates, truncates large bodies Prompt building — constructs structured prompt with scene context LLM call — streams response back to renderer Configuration LLM Provider Setup (Settings UI) Configure via the Settings panel (bottom-left gear icon): // Config shape (stored in SQLite settings table) interface LLMConfig { provider : 'openai' | 'anthropic' | 'custom' ; apiKey : string ; // from env or user input model : string ; // e.g. 'gpt-4o', 'claude-sonnet-4-20250514' baseUrl ? : string ; // for custom OpenAI-compatible endpoints } OpenAI: API Key: $OPENAI_API_KEY Model: gpt-4o or gpt-4o-mini Anthropic: API Key: $ANTHROPIC_API_KEY Model: claude-sonnet-4-20250514 Custom (OpenAI-compatible): Base URL: e.g. https://api.deepseek.com/v1 API Key: your provider key Model: provider-specific model name IPC API (Main ↔ Renderer) Session Management // Create a session const session = await window . electron . ipcRenderer . invoke ( 'session:create' , { name : 'My Analysis Session' , url : 'https://example.com' } ) // List sessions const sessions = await window . electron . ipcRenderer . invoke ( 'session:list' ) // Delete session await window . electron . ipcRenderer . invoke ( 'session:delete' , sessionId ) Capture Control // Start capturing for current tab await window . electron . ipcRenderer . invoke ( 'capture:start' , { sessionId , tabId } ) // Stop capturing await window . electron . ipcRenderer . invoke ( 'capture:stop' , { sessionId , tabId } ) // Get captured requests const requests = await window . electron . ipcRenderer . invoke ( 'capture:getRequests' , sessionId ) AI Analysis // Trigger AI analysis (streams back via IPC events) await window . electron . ipcRenderer . invoke ( 'analyze:start' , { sessionId } ) // Listen for streaming chunks window . electron . ipcRenderer . on ( 'analyze:chunk' , ( _ , chunk : string ) => { setReport ( prev => prev + chunk ) } ) // Listen for completion window . electron . ipcRenderer . on ( 'analyze:done' , ( ) => { setAnalyzing ( false ) } ) Real Code Examples Extend the Scene Detector // src/main/ai/scene-detector.ts import { CapturedRequest } from '../../shared/types' export type Scene = | 'registration' | 'oauth' | 'api-auth' | 'websocket' | 'general' export function detectScene ( requests : CapturedRequest [ ] ) : Scene { const urls = requests . map ( r => r . url . toLowerCase ( ) ) const bodies = requests . map ( r => r . requestBody ?. toLowerCase ( ) ?? '' ) // OAuth detection if ( urls . some ( u => u . includes ( 'oauth' ) || u . includes ( 'authorize' ) || u . includes ( 'callback' ) ) ) { return 'oauth' } // Registration detection if ( bodies . some ( b => b . includes ( 'password' ) && ( b . includes ( 'email' ) || b . includes ( 'username' ) ) ) && urls . some ( u => u . includes ( 'register' ) || u . includes ( 'signup' ) || u . includes ( 'sign-up' ) ) ) { return 'registration' } // WebSocket upgrade detection if ( requests . some ( r => r . isWebSocket ) ) { return 'websocket' } // Auth token patterns if ( urls . some ( u => u . includes ( '/auth' ) || u . includes ( '/token' ) || u . includes ( '/login' ) ) ) { return 'api-auth' } return 'general' } Custom Prompt Builder // src/main/ai/prompt-builder.ts import { Scene } from './scene-detector' import { AssembledData } from './data-assembler' export function buildPrompt ( scene : Scene , data : AssembledData ) : string { const sceneInstructions : Record < Scene , string

= { registration : Analyze this registration flow. Extract: 1. Required fields and validation rules 2. Password requirements 3. Captcha/bot protection mechanisms 4. Email verification flow 5. Reproducible curl commands for each step , oauth : Analyze this OAuth flow. Extract: 1. OAuth provider and grant type 2. Authorization URL with all parameters 3. Token exchange endpoint and parameters 4. Token refresh mechanism 5. Scopes requested , 'api-auth' : Analyze this authentication protocol. Extract: 1. Auth endpoint and method 2. Request payload schema 3. Response token format (JWT/session/etc) 4. Token usage in subsequent requests (header name, format) 5. Expiry and refresh strategy , websocket : Analyze this WebSocket protocol. Extract: 1. Upgrade request headers 2. Initial handshake messages 3. Message format (JSON/binary/custom) 4. Heartbeat/ping-pong mechanism 5. Event types and schemas , general : Analyze this web protocol. Extract: 1. Core API endpoints and their purposes 2. Authentication mechanism 3. Request/response schemas 4. Error handling patterns 5. Rate limiting signals , } return ` You are a protocol reverse engineer. ${ sceneInstructions [ scene ] }

Captured Data

Network Requests (

${ data . requests . length } total) ${ data . requests . map ( r => ** ${ r . method } ${ r . url } ** Status: ${ r . statusCode } Request Headers: ${ JSON . stringify ( r . requestHeaders , null , 2 ) } Request Body: ${ r . requestBody ?? '(empty)' } Response Headers: ${ JSON . stringify ( r . responseHeaders , null , 2 ) } Response Body: ${ r . responseBody ?? '(empty)' } ) . join ( '\n---\n' ) }

JS Hook Events

${ JSON . stringify ( data . hookEvents , null , 2 ) }

Storage Snapshots

${ JSON . stringify ( data . storageSnapshots , null , 2 ) } Generate a comprehensive protocol analysis report in Markdown. } Adding a Custom JS Hook // src/main/capture/js-injector.ts export function buildHookScript ( ) : string { return (function() { // Hook fetch const _fetch = window.fetch.bind(window) window.fetch = async function(...args) { const [input, init] = args const url = input instanceof Request ? input.url : String(input) // Pre-request hook window.__cdpHook?.({ type: 'fetch:request', url, init: JSON.stringify(init) }) const response = await _fetch(...args) const clone = response.clone() // Post-response hook (non-blocking) clone.text().then(body => { window.__cdpHook?.({ type: 'fetch:response', url, status: response.status, body }) }).catch(() => {}) return response } // Hook XHR const _open = XMLHttpRequest.prototype.open const _send = XMLHttpRequest.prototype.send XMLHttpRequest.prototype.open = function(method, url, ...rest) { this.__hookData = { method, url } return _open.apply(this, [method, url, ...rest]) } XMLHttpRequest.prototype.send = function(body) { this.addEventListener('load', function() { window.__cdpHook?.({ type: 'xhr:complete', method: this.__hookData?.method, url: this.__hookData?.url, requestBody: body, status: this.status, responseBody: this.responseText }) }) return _send.apply(this, [body]) } // Hook crypto.subtle for key detection if (window.crypto?.subtle) { const _sign = crypto.subtle.sign.bind(crypto.subtle) crypto.subtle.sign = async function(algorithm, key, data) { window.__cdpHook?.({ type: 'crypto:sign', algorithm: JSON.stringify(algorithm) }) return _sign(algorithm, key, data) } } // Hook document.cookie const cookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') Object.defineProperty(document, 'cookie', { get: function() { return cookieDesc.get.call(this) }, set: function(val) { window.__cdpHook?.({ type: 'cookie:set', value: val }) return cookieDesc.set.call(this, val) } }) })() } Database Schema Access // src/main/db/ — SQLite via better-sqlite3 import Database from 'better-sqlite3' import path from 'path' import { app } from 'electron' const DB_PATH = path . join ( app . getPath ( 'userData' ) , 'analyzer.db' ) export function getDb ( ) : Database . Database { const db = new Database ( DB_PATH ) db . pragma ( 'journal_mode = WAL' ) return db } // Typical schema export function initSchema ( db : Database . Database ) { db . exec ( CREATE TABLE IF NOT EXISTS sessions ( id TEXT PRIMARY KEY, name TEXT NOT NULL, url TEXT NOT NULL, created_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS requests ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, url TEXT NOT NULL, method TEXT NOT NULL, status_code INTEGER, request_headers TEXT, request_body TEXT, response_headers TEXT, response_body TEXT, is_sse INTEGER DEFAULT 0, is_websocket INTEGER DEFAULT 0, timestamp INTEGER NOT NULL, FOREIGN KEY (session_id) REFERENCES sessions(id) ); CREATE TABLE IF NOT EXISTS hook_events ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, type TEXT NOT NULL, data TEXT NOT NULL, timestamp INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS storage_snapshots ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, cookies TEXT, local_storage TEXT, session_storage TEXT, timestamp INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS settings ( key TEXT PRIMARY KEY, value TEXT NOT NULL ); ` ) } Shared Types Reference // src/shared/types.ts export interface Session { id : string name : string url : string createdAt : number } export interface CapturedRequest { id : string sessionId : string url : string method : string statusCode ? : number requestHeaders ? : Record < string , string

requestBody ? : string responseHeaders ? : Record < string , string

responseBody ? : string isSSE : boolean isWebSocket : boolean timestamp : number } export interface HookEvent { id : string sessionId : string type : 'fetch:request' | 'fetch:response' | 'xhr:complete' | 'crypto:sign' | 'cookie:set' data : Record < string , unknown

timestamp : number } export interface StorageSnapshot { id : string sessionId : string cookies : string localStorage : Record < string , string

sessionStorage : Record < string , string

timestamp : number } export interface LLMConfig { provider : 'openai' | 'anthropic' | 'custom' apiKey : string model : string baseUrl ? : string } Common Patterns Pattern: Capture a Full Registration Flow Click New Session → enter name + target URL (e.g. https://example.com/register ) Click Start Capture In the embedded browser, complete the full registration flow Click Stop Capture Click Analyze → AI generates a report with extracted fields, validation rules, and curl commands Pattern: OAuth Flow Analysis Create session with the OAuth entry URL Start capture Authorize the OAuth flow including the redirect callback Stop capture — the analyzer auto-detects OAuth and focuses prompt on token exchange Pattern: Adding a New LLM Provider // src/main/ai/ai-analyzer.ts import Anthropic from '@anthropic-ai/sdk' import OpenAI from 'openai' export async function * callLLM ( config : LLMConfig , prompt : string ) : AsyncGenerator < string

{ if ( config . provider === 'anthropic' ) { const client = new Anthropic ( { apiKey : config . apiKey } ) const stream = await client . messages . stream ( { model : config . model , max_tokens : 8192 , messages : [ { role : 'user' , content : prompt } ] } ) for await ( const chunk of stream ) { if ( chunk . type === 'content_block_delta' && chunk . delta . type === 'text_delta' ) { yield chunk . delta . text } } } else { // OpenAI or custom compatible const client = new OpenAI ( { apiKey : config . apiKey , baseURL : config . baseUrl // undefined = default OpenAI } ) const stream = await client . chat . completions . create ( { model : config . model , messages : [ { role : 'user' , content : prompt } ] , stream : true } ) for await ( const chunk of stream ) { yield chunk . choices [ 0 ] ?. delta ?. content ?? '' } } } Pattern: Filter Requests Before Analysis // Useful for large sessions — filter to only auth-related requests function filterRelevantRequests ( requests : CapturedRequest [ ] ) : CapturedRequest [ ] { const AUTH_PATTERNS = [ / \/ auth / , / \/ login / , / \/ register / , / \/ signup / , / \/ token / , / \/ oauth / , / \/ session / , / \/ verify / , / \/ captcha / ] return requests . filter ( r => { // Always include if has auth header if ( r . requestHeaders ?. [ 'authorization' ] || r . requestHeaders ?. [ 'x-auth-token' ] ) { return true } // Include if URL matches auth patterns if ( AUTH_PATTERNS . some ( p => p . test ( r . url ) ) ) return true // Include if response sets cookies if ( r . responseHeaders ?. [ 'set-cookie' ] ) return true // Exclude static assets if ( / . ( js | css | png | jpg | gif | svg | woff | ico ) ( \? | $ ) / . test ( r . url ) ) return false return false } ) } Troubleshooting better-sqlite3 build fails on Windows npm install --global windows-build-tools

or install Visual Studio Build Tools 2022 manually

pnpm rebuild better-sqlite3 wrong Electron version

Rebuild for current Electron version

./node_modules/.bin/electron-rebuild -f -w better-sqlite3

or

npx @electron/rebuild -f -w better-sqlite3 CDP not attaching to tab Ensure WebContentsView is fully loaded before calling cdpManager.attach() Check webContents.getURL() isn't about:blank before enabling Fetch For popups/OAuth windows, listen for new-window or setWindowOpenHandler and capture the new WebContents AI response truncated Increase max_tokens in the LLM call (default 8192, increase to 16384) Reduce request body size in data-assembler.ts — truncate large response bodies to first 2000 chars Requests missing response bodies CDP Fetch.getResponseBody must be called before Fetch.continueRequest Binary/gzip responses need base64 decoding: check base64Encoded field in CDP response Some streaming responses (SSE) can't have body captured synchronously — mark as SSE and capture chunks via Network.eventSourceMessageReceived HTTPS interception not working CDP Fetch interception works on all HTTPS by default in Electron's WebContentsView If a site uses certificate pinning, it may reject interception — look for ERR_CERT_* in request errors App window blank on startup

Check renderer build

pnpm dev

Look for Vite errors in terminal — usually missing env vars or import errors

Development Tips
Hot reload
:
pnpm dev
uses electron-vite with HMR for renderer and restart for main
Devtools
In dev mode, DevTools auto-opens for renderer; use
Ctrl+Shift+I
for embedded browser webview devtools
SQLite inspection
Use
DB Browser for SQLite
on
%APPDATA%/anything-analyzer/analyzer.db
(Windows) or
~/Library/Application Support/anything-analyzer/analyzer.db
(macOS)
IPC debugging
Add
console.log
in
ipc.ts
handlers — logs appear in Electron main process terminal
CDP raw events
Enable cdp.on('*', console.log) in cdp-manager.ts during development to see all CDP events
返回排行榜