{"_id":"@aigentic/browser","_rev":"2-ff5619fe76394bcaf6d940272718d7f3","name":"@aigentic/browser","dist-tags":{"alpha":"3.0.0-alpha.3","latest":"3.0.0-alpha.3"},"versions":{"3.0.0-alpha.3":{"name":"@aigentic/browser","version":"3.0.0-alpha.3","keywords":["browser","automation","ai-agent","claude-flow","playwright","web-scraping","testing"],"author":{"name":"ruvnet"},"license":"MIT","_id":"@aigentic/browser@3.0.0-alpha.3","maintainers":[{"name":"aigentic","email":"engineering@aigentic.net"}],"homepage":"https://github.com/ruvnet/claude-flow#readme","bugs":{"url":"https://github.com/ruvnet/claude-flow/issues"},"dist":{"shasum":"585e70d41928364e6d9d48c203f2a7097c068a88","tarball":"https://registry.npmjs.org/@aigentic/browser/-/browser-3.0.0-alpha.3.tgz","fileCount":34,"integrity":"sha512-fV2sYaiMTGd5hP/DyyG5lzQ9Yjci9lucbiYaLJEbuUWwIcb4yoxnMPwiQl9EC6z+n7HUjOWpH1klVKsF9zkg6A==","signatures":[{"sig":"MEUCIGBjrkYHBXcjz4qPGvDacMGBhtKS0uekGu9Qil2QtD21AiEAgpl56qO8+uZkx3POQJvhkSzejTsEV9x8WIXhXEO5SiM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":237596},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"exports":{".":"./dist/index.js","./agent":"./dist/agent/index.js","./skill":"./dist/skill/index.js","./mcp-tools":"./dist/mcp-tools/index.js"},"gitHead":"e2cb6210ce8d478b39cad81872a4aef78a05ceb4","scripts":{"dev":"tsc --watch","lint":"eslint src/","test":"vitest run","build":"tsc","test:e2e":"vitest run tests/e2e","typecheck":"tsc --noEmit","test:watch":"vitest","postinstall":"node -e \"const{execSync}=require('child_process');try{execSync('agent-browser --version',{stdio:'ignore'});}catch{console.log('\\n📦 Installing agent-browser globally...');try{execSync('npm install -g agent-browser@latest',{stdio:'inherit'});console.log('✅ agent-browser installed successfully!');}catch(e){console.log('⚠️  Could not install agent-browser globally. Run manually:\\n   npm install -g agent-browser@latest');}}\""},"_npmUser":{"name":"aigentic","email":"engineering@aigentic.net"},"repository":{"url":"git+https://github.com/ruvnet/claude-flow.git","type":"git","directory":"v3/@claude-flow/browser"},"_npmVersion":"11.12.0","description":"Browser automation for AI agents - integrates agent-browser with claude-flow swarms","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@aigentic/zod":"^3.22.4","@aigentic/agentic-flow":"^2.0.12","@aigentic/agent-browser":"^0.6.0"},"_hasShrinkwrap":false,"devDependencies":{"@aigentic/node":"^20.10.0","@aigentic/vitest":"^4.0.16","@aigentic/typescript":"^5.3.0"},"peerDependencies":{"@aigentic/cli":">=3.5.0"},"_npmOperationalInternal":{"tmp":"tmp/browser_3.0.0-alpha.3_1779324014789_0.30889237225736266","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-05-21T00:40:14.655Z","modified":"2026-09-13T15:30:26.360Z","3.0.0-alpha.3":"2026-05-21T00:40:14.969Z"},"bugs":{"url":"https://github.com/ruvnet/claude-flow/issues"},"author":{"name":"ruvnet"},"license":"MIT","homepage":"https://github.com/ruvnet/claude-flow#readme","keywords":["browser","automation","ai-agent","claude-flow","playwright","web-scraping","testing"],"repository":{"url":"git+https://github.com/ruvnet/claude-flow.git","type":"git","directory":"v3/@claude-flow/browser"},"description":"Browser automation for AI agents - integrates agent-browser with claude-flow swarms","maintainers":[{"email":"engineering@aigentic.net","name":"aiggy"}],"readme":"# @claude-flow/browser\n\n<div align=\"center\">\n\n[![npm version](https://img.shields.io/npm/v/@claude-flow/browser?style=for-the-badge&logo=npm&color=blue)](https://www.npmjs.com/package/@claude-flow/browser)\n[![npm downloads](https://img.shields.io/npm/dm/@claude-flow/browser?style=for-the-badge&logo=npm&color=cb3837)](https://www.npmjs.com/package/@claude-flow/browser)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.3+-blue?style=for-the-badge&logo=typescript)](https://www.typescriptlang.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge)](https://opensource.org/licenses/MIT)\n[![Tests](https://img.shields.io/badge/Tests-128%20passing-green?style=for-the-badge&logo=vitest)](./tests)\n\n**AI-Optimized Browser Automation for Claude-Flow Swarms**\n\n*Integrate [agent-browser](https://github.com/AugmentCode/agent-browser) with claude-flow for intelligent web automation, trajectory learning, security scanning, and multi-agent browser coordination.*\n\n</div>\n\n---\n\n## Overview\n\n`@claude-flow/browser` provides a comprehensive browser automation layer for AI agents, combining Vercel Labs' `agent-browser` CLI with claude-flow's learning, memory, and security capabilities. It enables agents to navigate websites, fill forms, extract data, and learn from successful interaction patterns.\n\n### Architecture\n\n```\nAgent Request → Security Scan → Browser Adapter → agent-browser CLI → Playwright\n                    ↓                                      ↓\n              URL/PII Check                          Element Refs (@e1, @e2)\n                    ↓                                      ↓\n              Memory Store ← Trajectory ← Snapshot ← AI-Optimized DOM\n```\n\n### Key Features\n\n🌐 **59 MCP Browser Tools** - Complete browser automation via MCP protocol with element refs, snapshots, forms, navigation, and JavaScript execution.\n\n🔒 **Security-First Design** - Built-in URL validation, phishing detection, PII scanning, XSS/SQL injection prevention, and domain blocking.\n\n🧠 **Trajectory Learning** - Records browser interactions for ReasoningBank/SONA learning. Successful patterns are stored and reused.\n\n📊 **AI-Optimized Snapshots** - 93% context reduction using element refs (`@e1`, `@e2`) instead of full CSS selectors.\n\n🐝 **Swarm Coordination** - Multi-session browser coordination for parallel scraping, testing, and validation tasks.\n\n📋 **9 Workflow Templates** - Pre-built automation patterns for login, OAuth, scraping, form submission, and monitoring.\n\n---\n\n## Installation\n\n```bash\n# Install the package\nnpm install @claude-flow/browser\n\n# Peer dependency (if not already installed)\nnpm install @claude-flow/cli@^3.0.0-alpha\n\n# agent-browser CLI (required)\nnpm install -g agent-browser\n```\n\n### Requirements\n\n- Node.js 18+\n- `agent-browser` CLI installed globally\n- Playwright browsers (installed automatically by agent-browser)\n\n---\n\n## Quick Start\n\n### Basic Usage\n\n```typescript\nimport { createBrowserService, browserTools } from '@claude-flow/browser';\n\n// Create a browser service with security and memory enabled\nconst browser = createBrowserService({\n  sessionId: 'my-session',\n  enableSecurity: true,  // URL validation, PII detection\n  enableMemory: true,    // Trajectory storage for learning\n});\n\n// Start tracking for learning\nconst trajectoryId = browser.startTrajectory('Login to dashboard');\n\n// Navigate (automatically security-scanned)\nawait browser.open('https://example.com/login');\n\n// Get AI-optimized snapshot with element refs\nconst snapshot = await browser.snapshot({ interactive: true });\n// Returns: { refs: { '@e1': {role: 'textbox', name: 'Email'}, '@e2': ... } }\n\n// Fill form using refs (93% less context than CSS selectors)\nawait browser.fill('@e1', 'user@example.com');\nawait browser.fill('@e2', 'password');\nawait browser.click('@e3'); // Submit button\n\n// End trajectory and store for learning\nconst trajectory = await browser.endTrajectory(true, 'Login successful');\n\n// Close browser\nawait browser.close();\n```\n\n### MCP Integration\n\nRegister browser tools with claude-flow's MCP server:\n\n```typescript\nimport { browserTools } from '@claude-flow/browser';\n\n// browserTools contains 59 MCP-compatible tools\n// Register with your MCP server\nmcpServer.registerTools(browserTools);\n```\n\nAvailable MCP tools:\n- `browser/open` - Navigate to URL\n- `browser/snapshot` - Get AI-optimized accessibility tree\n- `browser/click` - Click element by ref or selector\n- `browser/fill` - Fill input field\n- `browser/type` - Type text with keyboard events\n- `browser/screenshot` - Capture page screenshot\n- `browser/wait` - Wait for element/condition\n- `browser/eval` - Execute JavaScript\n- And 51 more...\n\n---\n\n<details>\n<summary><strong>🎯 Core Concepts</strong></summary>\n\n### Element Refs (`@e1`, `@e2`, etc.)\n\nagent-browser generates AI-optimized element references that reduce context by 93%:\n\n```typescript\n// Traditional (verbose)\nawait page.click('body > div.container > form#login > button[type=\"submit\"].btn.btn-primary');\n\n// With element refs (compact)\nawait browser.click('@e3');\n```\n\nRefs are generated from accessibility tree snapshots and map to interactive elements.\n\n### Trajectory Tracking\n\nEvery browser session can record a trajectory for learning:\n\n```typescript\n// Start tracking\nconst id = browser.startTrajectory('Complete checkout flow');\n\n// All actions are recorded: open, click, fill, type, etc.\nawait browser.open('https://shop.example.com/cart');\nawait browser.click('@e1'); // Checkout button\nawait browser.fill('@e2', '4111111111111111'); // Card number\n// ...\n\n// End with verdict\nconst trajectory = await browser.endTrajectory(true, 'Checkout completed successfully');\n\n// Trajectory contains:\n// - goal: 'Complete checkout flow'\n// - steps: [{action: 'open', input: {...}, result: {...}, snapshot: {...}}, ...]\n// - success: true\n// - verdict: 'Checkout completed successfully'\n```\n\nTrajectories are automatically stored in memory and used by ReasoningBank for pattern learning.\n\n### Security Scanning\n\nAll URLs are scanned before navigation:\n\n```typescript\n// Automatic scanning (enabled by default)\nconst result = await browser.open('http://suspicious-login.xyz');\n// Returns: { success: false, error: 'Security scan failed: phishing detected' }\n\n// Manual scanning\nconst scanResult = await browser.scanUrl('https://example.com');\n// Returns: { safe: true, score: 1.0, threats: [], pii: [] }\n\n// PII detection in form values\nconst piiResult = browser.scanForPII('SSN: 123-45-6789');\n// Returns: { pii: [{type: 'ssn', masked: '***-**-6789', confidence: 0.95}] }\n```\n\n</details>\n\n---\n\n<details>\n<summary><strong>🔌 Integrations</strong></summary>\n\n### Memory Integration\n\nStore and search browser patterns using HNSW-indexed memory:\n\n```typescript\nimport { createMemoryManager } from '@claude-flow/browser';\n\nconst memory = createMemoryManager('session-1');\n\n// Store a pattern\nawait memory.storePattern('login-github', 'Login to GitHub', [\n  { action: 'fill', selector: '#login_field', value: '${username}' },\n  { action: 'fill', selector: '#password', value: '${password}' },\n  { action: 'click', selector: '[type=\"submit\"]' },\n], true);\n\n// Find similar patterns (semantic search)\nconst similar = await memory.findSimilarTrajectories('Sign in to GitHub');\n\n// Get session statistics\nconst stats = await memory.getSessionStats();\n// { trajectories: 5, patterns: 12, snapshots: 23, errors: 1, successRate: 0.83 }\n```\n\n### Security Integration\n\nComprehensive threat detection:\n\n```typescript\nimport { getSecurityScanner, isUrlSafe, containsPII } from '@claude-flow/browser';\n\nconst scanner = getSecurityScanner({\n  requireHttps: true,\n  blockedDomains: ['bit.ly', 'tinyurl.com'],\n  allowedDomains: ['github.com', 'google.com'],\n});\n\n// URL scanning\nconst urlResult = await scanner.scanUrl('https://paypa1-secure.xyz/login');\n// Detects: phishing (lookalike domain), suspicious TLD\n\n// Content scanning\nconst contentResult = scanner.scanContent('Email: test@example.com, Card: 4111-1111-1111-1111');\n// Detects: email, credit-card with masking\n\n// Input validation (XSS, SQL injection)\nconst inputResult = scanner.validateInput('<script>alert(1)</script>', 'comment');\n// Detects: xss threat\n\n// Quick checks\nawait isUrlSafe('https://example.com'); // true\ncontainsPII('My SSN is 123-45-6789'); // true\n```\n\n### Workflow Templates\n\nPre-built automation workflows:\n\n```typescript\nimport { listWorkflows, getWorkflow, getWorkflowManager } from '@claude-flow/browser';\n\n// List all templates\nconst workflows = listWorkflows();\n// ['login-basic', 'login-oauth', 'logout', 'scrape-table', 'scrape-list',\n//  'contact-form', 'visual-regression', 'smoke-test', 'uptime-check']\n\n// Get specific template\nconst loginTemplate = getWorkflow('login-basic');\n// {\n//   id: 'login-basic',\n//   name: 'Basic Login',\n//   category: 'authentication',\n//   variables: [{name: 'url', required: true}, {name: 'username'}, ...],\n//   steps: [{action: 'open', target: '${url}'}, {action: 'fill', ...}, ...]\n// }\n\n// Validate variables\nconst manager = getWorkflowManager();\nconst validation = manager.validateVariables('login-basic', {\n  url: 'https://example.com/login',\n  username: 'user',\n  password: 'pass',\n});\n// { valid: true, errors: [] }\n```\n\n#### Available Templates\n\n| Template | Category | Description |\n|----------|----------|-------------|\n| `login-basic` | authentication | Standard username/password login |\n| `login-oauth` | authentication | OAuth/SSO login flow (Google, GitHub) |\n| `logout` | authentication | Standard logout flow |\n| `scrape-table` | data-extraction | Extract data from HTML tables |\n| `scrape-list` | data-extraction | Extract items from repeated elements |\n| `contact-form` | form-submission | Fill and submit contact forms |\n| `visual-regression` | testing | Screenshot-based visual testing |\n| `smoke-test` | testing | Basic page load verification |\n| `uptime-check` | monitoring | Page availability monitoring |\n\n### Hooks Integration\n\nPre-browse and post-browse hooks for learning:\n\n```typescript\nimport { preBrowseHook, postBrowseHook, browserHooks } from '@claude-flow/browser';\n\n// Before browsing - get recommendations\nconst preResult = await preBrowseHook({\n  goal: 'Login to admin panel',\n  url: 'https://example.com/admin',\n});\n// {\n//   recommendedSteps: [{action: 'fill', selector: '#username'}, ...],\n//   similarPatterns: 3,\n//   suggestedModel: 'sonnet',\n//   estimatedDuration: 5000,\n//   warnings: ['URL is not HTTPS - authentication data may be at risk']\n// }\n\n// After browsing - record outcome\nconst postResult = await postBrowseHook({\n  trajectoryId: 'traj-123',\n  success: true,\n  verdict: 'Login successful',\n  duration: 4500,\n  stepsCompleted: 5,\n});\n// { patternStored: true, patternId: 'pattern-traj-123', learnedFrom: true }\n```\n\n</details>\n\n---\n\n<details>\n<summary><strong>🐝 Swarm Coordination</strong></summary>\n\nCoordinate multiple browser sessions for parallel tasks:\n\n```typescript\nimport { createBrowserSwarm } from '@claude-flow/browser';\n\n// Create a swarm coordinator\nconst swarm = createBrowserSwarm({\n  topology: 'hierarchical',\n  maxSessions: 5,\n  sessionPrefix: 'scraper',\n});\n\n// Spawn browser agents with specific roles\nconst navigator = await swarm.spawnAgent('navigator');\nconst scraper1 = await swarm.spawnAgent('scraper');\nconst scraper2 = await swarm.spawnAgent('scraper');\nconst validator = await swarm.spawnAgent('validator');\n\n// Share data between agents\nswarm.shareData('targetUrls', ['https://example.com/page1', 'https://example.com/page2']);\n\n// Each agent can access shared data\nconst urls = swarm.getSharedData<string[]>('targetUrls');\n\n// Get swarm stats\nconst stats = swarm.getStats();\n// { activeSessions: 4, maxSessions: 5, topology: 'hierarchical' }\n\n// Close all sessions\nawait swarm.closeAll();\n```\n\n### Agent Roles\n\n| Role | Capabilities | Use Case |\n|------|-------------|----------|\n| `navigator` | Navigation, authentication, session management | Login, navigate to pages |\n| `scraper` | Snapshots, extraction, pagination | Data collection |\n| `validator` | Assertions, state checks, screenshots | Verify results |\n| `tester` | Forms, interactions, assertions | E2E testing |\n| `monitor` | Network, console, errors | Performance monitoring |\n\n</details>\n\n---\n\n<details>\n<summary><strong>📚 API Reference</strong></summary>\n\n### BrowserService\n\n```typescript\ninterface BrowserServiceConfig {\n  sessionId?: string;          // Browser session ID\n  enableMemory?: boolean;      // Enable trajectory storage (default: true)\n  enableSecurity?: boolean;    // Enable URL/PII scanning (default: true)\n  requireHttps?: boolean;      // Require HTTPS URLs\n  blockedDomains?: string[];   // Block specific domains\n  allowedDomains?: string[];   // Allow only specific domains\n  defaultTimeout?: number;     // Default operation timeout\n  headless?: boolean;          // Run headless (default: true)\n}\n\nclass BrowserService {\n  // Trajectory tracking\n  startTrajectory(goal: string): string;\n  endTrajectory(success: boolean, verdict?: string): Promise<BrowserTrajectory | null>;\n  getCurrentTrajectory(): TrajectoryTracker | null;\n\n  // Navigation\n  open(url: string, options?: OpenOptions): Promise<ActionResult>;\n  close(): Promise<ActionResult>;\n\n  // Snapshots\n  snapshot(options?: SnapshotOptions): Promise<ActionResult<Snapshot>>;\n  getLatestSnapshot(): Snapshot | null;\n\n  // Interactions\n  click(target: string, options?: ClickOptions): Promise<ActionResult>;\n  fill(target: string, value: string, options?: FillOptions): Promise<ActionResult>;\n  type(target: string, text: string, options?: TypeOptions): Promise<ActionResult>;\n  press(key: string, delay?: number): Promise<ActionResult>;\n\n  // Waiting\n  wait(options: WaitOptions): Promise<ActionResult>;\n\n  // Data extraction\n  getText(target: string): Promise<ActionResult<string>>;\n  eval<T>(script: string): Promise<ActionResult<T>>;\n  extractData(refs: string[]): Promise<Record<string, string>>;\n\n  // Screenshots\n  screenshot(options?: ScreenshotOptions): Promise<ActionResult<string>>;\n\n  // Security\n  scanUrl(url: string): Promise<ThreatScanResult>;\n  scanForPII(content: string, context?: string): ThreatScanResult;\n\n  // Memory\n  findSimilarTrajectories(goal: string, topK?: number): Promise<BrowserTrajectory[]>;\n  getMemoryStats(): Promise<MemoryStats | null>;\n\n  // High-level operations\n  submitForm(fields: Array<{target: string, value: string}>, submitButton: string): Promise<ActionResult>;\n  navigateAndWait(url: string, selector: string, timeout?: number): Promise<ActionResult>;\n  authenticateWithHeaders(url: string, headers: Record<string, string>): Promise<ActionResult>;\n}\n```\n\n### Security Scanner\n\n```typescript\ninterface SecurityConfig {\n  enableUrlValidation: boolean;\n  enablePIIDetection: boolean;\n  enableThreatScanning: boolean;\n  blockedDomains: string[];\n  allowedDomains: string[];\n  maxRedirects: number;\n  requireHttps: boolean;\n  piiMaskingEnabled: boolean;\n}\n\nclass BrowserSecurityScanner {\n  scanUrl(url: string): Promise<ThreatScanResult>;\n  scanContent(content: string, context?: string): ThreatScanResult;\n  validateInput(value: string, fieldType: string): ThreatScanResult;\n  sanitizeInput(value: string): string;\n  maskPII(value: string, type: PIIType): string;\n}\n\ninterface ThreatScanResult {\n  safe: boolean;\n  threats: Threat[];\n  pii: PIIMatch[];\n  score: number;  // 0-1 (1 = safe)\n  scanDuration: number;\n}\n```\n\n### Memory Manager\n\n```typescript\nclass BrowserMemoryManager {\n  storeTrajectory(trajectory: BrowserTrajectory): Promise<void>;\n  storePattern(id: string, goal: string, steps: PatternStep[], success: boolean): Promise<void>;\n  storeSnapshot(id: string, snapshot: Snapshot): Promise<void>;\n  storeError(id: string, error: Error, context: object): Promise<void>;\n  findSimilarTrajectories(goal: string, topK?: number): Promise<BrowserTrajectory[]>;\n  findPatterns(goal: string, successfulOnly?: boolean): Promise<MemorySearchResult[]>;\n  getSessionStats(): Promise<SessionStats>;\n}\n```\n\n</details>\n\n---\n\n<details>\n<summary><strong>🧪 Testing</strong></summary>\n\n### Unit Tests\n\n```bash\n# Run all tests\nnpm test\n\n# Run with watch mode\nnpm run test:watch\n\n# Run specific test file\nnpm test -- tests/security-integration.test.ts\n```\n\n### E2E Tests (Docker)\n\n```bash\n# Navigate to docker directory\ncd docker\n\n# Run E2E tests with browser\ndocker compose --profile e2e up browser-e2e\n\n# Run in debug mode (keeps container running)\ndocker compose --profile debug up browser-debug\n```\n\n### Test Coverage\n\n| Component | Tests | Status |\n|-----------|-------|--------|\n| BrowserService | 18 | ✅ |\n| AgentBrowserAdapter | 27 | ✅ |\n| SecurityScanner | 30 | ✅ |\n| MemoryManager | 16 | ✅ |\n| WorkflowTemplates | 25 | ✅ |\n| ReasoningBankAdapter | 12 | ✅ |\n| **Total** | **128** | ✅ |\n\n</details>\n\n---\n\n<details>\n<summary><strong>⚙️ Configuration</strong></summary>\n\n### TypeScript\n\n```typescript\n// tsconfig.json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"esModuleInterop\": true,\n    \"strict\": true\n  }\n}\n```\n\n### Environment Variables\n\n```bash\n# Browser settings\nBROWSER_HEADLESS=true\nBROWSER_DEFAULT_TIMEOUT=30000\n\n# Security settings\nBROWSER_REQUIRE_HTTPS=true\nBROWSER_BLOCKED_DOMAINS=bit.ly,tinyurl.com\n\n# Memory settings\nBROWSER_ENABLE_MEMORY=true\nBROWSER_MEMORY_NAMESPACE=browser\n```\n\n</details>\n\n---\n\n<details>\n<summary><strong>💡 Examples</strong></summary>\n\n### Login and Extract Data\n\n```typescript\nimport { createBrowserService } from '@claude-flow/browser';\n\nconst browser = createBrowserService();\n\nasync function loginAndExtract() {\n  browser.startTrajectory('Login and extract user data');\n\n  // Login\n  await browser.open('https://app.example.com/login');\n  await browser.fill('#email', 'user@example.com');\n  await browser.fill('#password', 'secretpassword');\n  await browser.click('#login-button');\n\n  // Wait for dashboard\n  await browser.wait({ selector: '.dashboard' });\n\n  // Get snapshot and extract data\n  const snapshot = await browser.snapshot({ interactive: true });\n  const data = await browser.extractData(['@e1', '@e2', '@e3']);\n\n  await browser.endTrajectory(true, 'Data extracted successfully');\n  await browser.close();\n\n  return data;\n}\n```\n\n### Parallel Scraping\n\n```typescript\nimport { createBrowserSwarm } from '@claude-flow/browser';\n\nasync function parallelScrape(urls: string[]) {\n  const swarm = createBrowserSwarm({ maxSessions: 5 });\n  const results: any[] = [];\n\n  // Spawn scrapers for each URL\n  const promises = urls.map(async (url) => {\n    const scraper = await swarm.spawnAgent('scraper');\n    await scraper.open(url);\n    const snapshot = await scraper.snapshot();\n    const text = await scraper.getText('main');\n    return { url, content: text.data };\n  });\n\n  const data = await Promise.all(promises);\n  await swarm.closeAll();\n\n  return data;\n}\n```\n\n### Security-First Automation\n\n```typescript\nimport { createBrowserService, getSecurityScanner } from '@claude-flow/browser';\n\nasync function secureAutomation(url: string, formData: Record<string, string>) {\n  const scanner = getSecurityScanner({ requireHttps: true });\n\n  // Pre-scan URL\n  const urlScan = await scanner.scanUrl(url);\n  if (!urlScan.safe) {\n    throw new Error(`Unsafe URL: ${urlScan.threats.map(t => t.description).join(', ')}`);\n  }\n\n  // Scan form data for sensitive info\n  for (const [field, value] of Object.entries(formData)) {\n    const piiScan = scanner.scanContent(value, field);\n    if (piiScan.pii.length > 0) {\n      console.log(`Warning: PII detected in ${field}:`, piiScan.pii.map(p => p.type));\n    }\n  }\n\n  // Proceed with automation\n  const browser = createBrowserService({ enableSecurity: true });\n  await browser.open(url);\n\n  for (const [selector, value] of Object.entries(formData)) {\n    await browser.fill(selector, value);\n  }\n\n  await browser.close();\n}\n```\n\n</details>\n\n---\n\n<details>\n<summary><strong>🔧 Troubleshooting</strong></summary>\n\n### Common Issues\n\n**agent-browser not found**\n```bash\nnpm install -g agent-browser\n```\n\n**Playwright browsers missing**\n```bash\nnpx playwright install\n```\n\n**Security scan blocking legitimate URLs**\n```typescript\nconst browser = createBrowserService({\n  allowedDomains: ['trusted-domain.com'],\n  // Or disable for specific navigations\n});\nawait browser.open('http://trusted-domain.com', { skipSecurityCheck: true });\n```\n\n**Memory not persisting**\n```typescript\n// Ensure endTrajectory is called\nconst trajectory = await browser.endTrajectory(true); // Must await!\n```\n\n</details>\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](../../CONTRIBUTING.md) in the root repository.\n\n## License\n\nMIT License - see [LICENSE](../../LICENSE) for details.\n\n## Links\n\n- [GitHub Repository](https://github.com/ruvnet/claude-flow)\n- [agent-browser](https://github.com/AugmentCode/agent-browser)\n- [Claude-Flow Documentation](https://github.com/ruvnet/claude-flow#readme)\n- [MCP Protocol](https://modelcontextprotocol.io)\n\n---\n\n<div align=\"center\">\n\n**Part of the [Claude-Flow](https://github.com/ruvnet/claude-flow) ecosystem**\n\nMade with ❤️ by [ruvnet](https://github.com/ruvnet)\n\n</div>\n","readmeFilename":"README.md"}